Example #1
0
void VGMColl::UnpackSampColl(DLSFile& dls, VGMSampColl* sampColl, vector<VGMSamp*>& finalSamps)
{
	assert(sampColl != NULL);

	size_t nSamples = sampColl->samples.size();
	for (size_t i=0; i<nSamples; i++)
	{
		VGMSamp* samp = sampColl->samples[i];

		uint32_t bufSize;
		if (samp->ulUncompressedSize)
			bufSize = samp->ulUncompressedSize;
		else
			bufSize = (uint32_t)ceil((double)samp->dataLength * samp->GetCompressionRatio());
		//bool bOddBufSize = bufSize % 2;
		//if (bOddBufSize)				//if the buffer size is odd, we must align it to be even for the RIFF format
		//	bufSize++;
		uint8_t* uncompSampBuf = new uint8_t[bufSize];	//create a new memory space for the uncompressed wave
		samp->ConvertToStdWave(uncompSampBuf);			//and uncompress into that space
		//if (bOddBufSize)
		//	uncompSampBuf[bufSize] = 0;		//set the last (should be unused) byte to 0;

		uint16_t blockAlign = samp->bps / 8*samp->channels;
		dls.AddWave(1, samp->channels, samp->rate, samp->rate*blockAlign, blockAlign,
			samp->bps, bufSize, uncompSampBuf, wstring2string(samp->name));
		finalSamps.push_back(samp);
	}
}
Example #2
0
bool VGMColl::OnSaveAllDLS() {
  wstring dirpath = pRoot->UI_GetSaveDirPath();
  if (dirpath.length() != 0) {
    DLSFile dlsfile;
    wstring filepath = dirpath + L"\\" + ConvertToSafeFileName(this->name) + L".dls";
    if (CreateDLSFile(dlsfile)) {
      if (!dlsfile.SaveDLSFile(filepath))
        pRoot->AddLogItem(new LogItem(std::wstring(L"Failed to save DLS file"), LOG_LEVEL_ERR, L"VGMColl"));
    }
    else
      pRoot->AddLogItem(new LogItem(std::wstring(L"Failed to save DLS file"), LOG_LEVEL_ERR, L"VGMColl"));

    if (this->seq != nullptr) {
      filepath = dirpath + L"\\" + ConvertToSafeFileName(this->name) + L".mid";
      if (!this->seq->SaveAsMidi(filepath))
        pRoot->AddLogItem(new LogItem(std::wstring(L"Failed to save MIDI file"), LOG_LEVEL_ERR, L"VGMColl"));
    }
  }
  return true;
}
Example #3
0
bool VGMColl::OnSaveAllDLS()
{
	wstring dirpath = pRoot->UI_GetSaveDirPath();
	if (dirpath.length() != 0)
	{
		DLSFile dlsfile;
		wstring filepath = dirpath + L"\\" + ConvertToSafeFileName(this->name) + L".dls";
		if (CreateDLSFile(dlsfile))
		{
			if (!dlsfile.SaveDLSFile(filepath))
				Alert(L"Failed to save DLS file.");
		}
		else
			Alert(L"Failed to save DLS file.");

		filepath = dirpath + L"\\" + ConvertToSafeFileName(this->name) + L".mid";
		if (!this->seq->SaveAsMidi(filepath))
			Alert(L"Failed to save MIDI file.");
	}
	return true;
}
Example #4
0
void VGMColl::UnpackSampColl(DLSFile &dls, VGMSampColl *sampColl, vector<VGMSamp *> &finalSamps) {
  assert(sampColl != NULL);

  size_t nSamples = sampColl->samples.size();
  for (size_t i = 0; i < nSamples; i++) {
    VGMSamp *samp = sampColl->samples[i];

    uint32_t bufSize;
    if (samp->ulUncompressedSize)
      bufSize = samp->ulUncompressedSize;
    else
      bufSize = (uint32_t) ceil((double) samp->dataLength * samp->GetCompressionRatio());
    uint8_t *uncompSampBuf = new uint8_t[bufSize];    //create a new memory space for the uncompressed wave
    samp->ConvertToStdWave(uncompSampBuf);            //and uncompress into that space

    uint16_t blockAlign = samp->bps / 8 * samp->channels;
    dls.AddWave(1, samp->channels, samp->rate, samp->rate * blockAlign, blockAlign,
                samp->bps, bufSize, uncompSampBuf, wstring2string(samp->name));
    finalSamps.push_back(samp);
  }
}
Example #5
0
bool VGMColl::MainDLSCreation(DLSFile &dls) {
  vector<VGMSamp *> finalSamps;
  //we have to collect the finalSampColls in case sampcolls is empty but there are multiple instrSets with
  //embedded sampcolls
  vector<VGMSampColl *> finalSampColls;

  if (!instrsets.size() /*|| !sampcolls.size()*/)
    return false;

  // if there are independent SampColl(s) in the collection
  if (sampcolls.size()) {
    for (uint32_t sam = 0; sam < sampcolls.size(); sam++) {
      finalSampColls.push_back(sampcolls[sam]);
      UnpackSampColl(dls, sampcolls[sam], finalSamps);
    }
  }
    // otherwise, the SampColl(s) are children of the InstrSet(s)
  else {
    for (uint32_t i = 0; i < instrsets.size(); i++) {
      finalSampColls.push_back(instrsets[i]->sampColl);
      UnpackSampColl(dls, instrsets[i]->sampColl, finalSamps);
    }
  }

  if (finalSamps.size() == 0)
    return false;


  for (size_t inst = 0; inst < instrsets.size(); inst++) {
    VGMInstrSet *set = instrsets[inst];
    size_t nInstrs = set->aInstrs.size();
    for (size_t i = 0; i < nInstrs; i++) {
      VGMInstr *vgminstr = set->aInstrs[i];
      size_t nRgns = vgminstr->aRgns.size();
      std::string name = wstring2string(vgminstr->name);
      DLSInstr *newInstr = dls.AddInstr(vgminstr->bank, vgminstr->instrNum, name);
      for (uint32_t j = 0; j < nRgns; j++) {
        VGMRgn *rgn = vgminstr->aRgns[j];
        //				if (rgn->sampNum+1 > sampColl->samples.size())	//does thereferenced sample exist?
        //					continue;

        // Determine the SampColl associated with this rgn.  If there's an explicit pointer to it, use that.
        VGMSampColl *sampColl = rgn->sampCollPtr;
        if (!sampColl) {
          // If rgn is of an InstrSet with an embedded SampColl, use that SampColl.
          if (((VGMInstrSet *) rgn->vgmfile)->sampColl)
            sampColl = ((VGMInstrSet *) rgn->vgmfile)->sampColl;

            // If that does not exist, assume the first SampColl
          else
            sampColl = finalSampColls[0];
        }

        // Determine the sample number within the rgn's associated SampColl
        size_t realSampNum;
        // If a sample offset is provided, then find the sample number based on this offset.
        // see sampOffset declaration in header file for more info.
        if (rgn->sampOffset != -1) {
          bool bFoundIt = false;
          for (uint32_t s = 0; s < sampColl->samples.size(); s++) {                            //for every sample
            if (rgn->sampOffset == sampColl->samples[s]->dwOffset - sampColl->dwOffset - sampColl->sampDataOffset) {
              realSampNum = s;

              //samples[m]->loop.loopStart = parInstrSet->aInstrs[i]->aRgns[k]->loop.loopStart;
              //samples[m]->loop.loopLength = (samples[m]->dataLength) - (parInstrSet->aInstrs[i]->aRgns[k]->loop.loopStart); //[aInstrs[i]->aRegions[k]->sample_num]->dwUncompSize/2) - ((aInstrs[i]->aRegions[k]->loop_point*28)/16); //to end of sample
              bFoundIt = true;
              break;
            }
          }
          if (!bFoundIt) {
            std::wstring message = FormatString<wstring>(L"Could not match rgn with sampOffset %X to a sample with that offset.\n  (InstrSet %d, Instr %d, Rgn %d)", rgn->sampOffset, inst, i, j);
            pRoot->AddLogItem(new LogItem(std::wstring(message.c_str()), LOG_LEVEL_ERR, L"VGMColl"));
            realSampNum = 0;
          }
        }
          // Otherwise, the sample number should be explicitly defined in the rgn.
        else
          realSampNum = rgn->sampNum;


        // Determine the sampCollNum (index into our finalSampColls vector)
        unsigned int sampCollNum;
        for (unsigned int k = 0; k < finalSampColls.size(); k++) {
          if (finalSampColls[k] == sampColl)
            sampCollNum = k;
        }
        //   now we add the number of samples from the preceding SampColls to the value to get the real sampNum
        //   in the final DLS file.
        for (unsigned int k = 0; k < sampCollNum; k++)
          realSampNum += finalSampColls[k]->samples.size();


        // For collections with multiple SampColls
        // If a SampColl ptr is given, find the SampColl and adjust the sample number of the region
        // to compensate for all preceding SampColl samples.
        //if (rgn->sampCollNum == -1)	//if a sampCollPtr is defined
        //{
        //	// find the sampColl's index in samplecolls (the sampCollNum, effectively)
        //	for (uint32_t i=0; i < finalSampColls.size(); i++)
        //	{
        //		if (finalSampColls[i] == sampColl)
        //			rgn->sampCollNum = i;
        //	}
        //}
        //if (rgn->sampCollNum != -1)		//if a sampCollNum is defined
        //{									//then sampNum represents the sample number in the specific sample collection
        //	for (int k=0; k < rgn->sampCollNum; k++)
        //		realSampNum += finalSampColls[k]->samples.size();	//so now we add all previous sample collection samples to the value to get the real (absolute) sampNum
        //}


        DLSRgn *newRgn = newInstr->AddRgn();
        newRgn->SetRanges(rgn->keyLow, rgn->keyHigh,
                          rgn->velLow, rgn->velHigh);
        newRgn->SetWaveLinkInfo(0, 0, 1, (uint32_t) realSampNum);

        if (realSampNum >= finalSamps.size()) {
          wchar_t log[256];
          swprintf(log, 256, L"Sample %u does not exist.", realSampNum);
          pRoot->AddLogItem(new LogItem(log, LOG_LEVEL_ERR, L"VGMColl"));
          realSampNum = finalSamps.size() - 1;
        }

        VGMSamp *samp = finalSamps[realSampNum];//sampColl->samples[rgn->sampNum];
        DLSWsmp *newWsmp = newRgn->AddWsmp();

        // This is a really loopy way of determining the loop information, pardon the pun.  However, it works.
        // There might be a way to simplify this, but I don't want to test out whether another method breaks anything just yet
        // Use the sample's loopStatus to determine if a loop occurs.  If it does, see if the sample provides loop info
        // (gathered during ADPCM > PCM conversion.  If the sample doesn't provide loop offset info, then use the region's
        // loop info.
        if (samp->bPSXLoopInfoPrioritizing) {
          if (samp->loop.loopStatus != -1) {
            if (samp->loop.loopStart != 0 || samp->loop.loopLength != 0)
              newWsmp->SetLoopInfo(samp->loop, samp);
            else {
              rgn->loop.loopStatus = samp->loop.loopStatus;
              newWsmp->SetLoopInfo(rgn->loop, samp);
            }
          }
          else throw;
        }
          // The normal method: First, we check if the rgn has loop info defined.
          // If it doesn't, then use the sample's loop info.
        else if (rgn->loop.loopStatus == -1) {
          if (samp->loop.loopStatus != -1)
            newWsmp->SetLoopInfo(samp->loop, samp);
          else throw;
        }
        else
          newWsmp->SetLoopInfo(rgn->loop, samp);

        uint8_t realUnityKey;
        if (rgn->unityKey == -1)
          realUnityKey = samp->unityKey;
        else
          realUnityKey = rgn->unityKey;
        if (realUnityKey == -1)
          realUnityKey = 0x3C;

        short realFineTune;
        if (rgn->fineTune == 0)
          realFineTune = samp->fineTune;
        else
          realFineTune = rgn->fineTune;

        long realAttenuation;
        if (rgn->volume == -1 && samp->volume == -1)
          realAttenuation = 0;
        else if (rgn->volume == -1)
          realAttenuation = (long) (-(ConvertLogScaleValToAtten(samp->volume) * DLS_DECIBEL_UNIT * 10));
        else
          realAttenuation = (long) (-(ConvertLogScaleValToAtten(rgn->volume) * DLS_DECIBEL_UNIT * 10));

        long convAttack = (long) roundi(SecondsToTimecents(rgn->attack_time) * 65536);
        long convDecay = (long) roundi(SecondsToTimecents(rgn->decay_time) * 65536);
        long convSustainLev;
        if (rgn->sustain_level == -1)
          convSustainLev = 0x03e80000;        //sustain at full if no sustain level provided
        else {
          //the DLS envelope is a range from 0 to -96db.
          double attenInDB = ConvertLogScaleValToAtten(rgn->sustain_level);
          convSustainLev = (long) (((96.0 - attenInDB) / 96.0) * 0x03e80000);
        }

        long convRelease = (long) roundi(SecondsToTimecents(rgn->release_time) * 65536);

        DLSArt *newArt = newRgn->AddArt();
        newArt->AddPan(ConvertPercentPanTo10thPercentUnits(rgn->pan) * 65536);
        newArt->AddADSR(convAttack, 0, convDecay, convSustainLev, convRelease, 0);

        newWsmp->SetPitchInfo(realUnityKey, realFineTune, realAttenuation);
      }
    }
  }
  return true;
}