Esempio n. 1
0
HRESULT SaveWavToFile( MyDirectSoundBuffer* o, const void* data, DWORD size, const char* filepath )
{
	// The WAVEFORMATEX structure can have a variable length that depends on the details of the format.
	// Before retrieving the format description, the application should query the DirectSoundBuffer object
	// for the size of the format by calling this method and specifying NULL for the lpwfxFormat parameter.
	// The size of the structure will be returned in the lpdwSizeWritten parameter. 
	DWORD bytesToAllocate = 0;
	V_RET(o->m_pDSoundBuffer->GetFormat(NULL, 0, &bytesToAllocate));

	WAVEFORMATEX* lpwfxFormat = (WAVEFORMATEX*) alloca( bytesToAllocate );
	V_RET(o->m_pDSoundBuffer->GetFormat(lpwfxFormat, bytesToAllocate, NULL));


#ifdef FOLDER_TO_SAVE_WAVEFORMATEX
	{
		const UINT64 format_hash = MurmurHash64( lpwfxFormat, bytesToAllocate );

		// generate unique file name
		char buffer[32];
		sprintf(buffer, "%016llX", format_hash);

		char filepath[MAX_PATH];
		strcpy_s(filepath, FOLDER_TO_SAVE_WAVEFORMATEX);
		strcat_s(filepath, buffer);
		strcat_s(filepath, ".wav_header");

		FILE* pFile = ::fopen( filepath, "w" );
		if( pFile )
		{
			::fwrite( lpwfxFormat, sizeof(char), bytesToAllocate, pFile );
			::fclose( pFile );
			pFile = NULL;
		}
	}
#endif

	CWaveFile  waveFile;
	V_RET(waveFile.Open( (char*)filepath, lpwfxFormat, WAVEFILE_WRITE ));

	UINT bytesWritten;
	V_RET(waveFile.Write( size, (BYTE*)data, &bytesWritten ));

	V_RET(waveFile.Close());

	return S_OK;
}
Esempio n. 2
0
// export thread
static DWORD __stdcall export_rendering_thread(void *parameter) {
  const int samples_per_sec = 44100;
  uint progress = 0;

  WAVEFORMATEX  wfxInput;
  ZeroMemory( &wfxInput, sizeof(wfxInput));
  wfxInput.wFormatTag = WAVE_FORMAT_PCM;
  wfxInput.nSamplesPerSec = samples_per_sec;
  wfxInput.wBitsPerSample =  16; 
  wfxInput.nChannels = 2;
  wfxInput.nBlockAlign = wfxInput.nChannels * (wfxInput.wBitsPerSample / 8);
  wfxInput.nAvgBytesPerSec = wfxInput.nBlockAlign * wfxInput.nSamplesPerSec;

  HRESULT hr;
  CWaveFile wavFile;

  hr = wavFile.Open((char*)parameter, &wfxInput, WAVEFILE_WRITE);
  if (FAILED(hr)) {
    goto done;
  }


  // stop playing
  song_stop_playback();

  // skip 5 seconds
  for (int samples = samples_per_sec * 5; samples > 0; samples -= 32) {
    float temp_buffer[2][32];

    // update song
    song_update(1000.0 * (double)32 / (double)samples_per_sec);

    // update effect
    vsti_update_config((float)samples_per_sec, 32);

    // call vsti process func
    vsti_process(temp_buffer[0], temp_buffer[1], 32);
  }

  song_start_playback();

  for (;;) {
    const int samples = 32;

    float temp_buffer[2][samples];
    short output_buffer[2 * samples];

    // update song
    song_update(1000.0 * (double)samples / (double)samples_per_sec);

    // update effect
    vsti_update_config((float)samples_per_sec, samples);

    // call vsti process func
    vsti_process(temp_buffer[0], temp_buffer[1], samples);

    short* output = output_buffer;
    float volume = config_get_output_volume() / 100.0;
    for (int i = 0; i < samples; i++) {
      float l = 
      output[0] = convertSample(temp_buffer[0][i] * 32767.0f * volume);
      output[1] = convertSample(temp_buffer[1][i] * 32767.0f * volume);
      output += 2;
    }

    UINT sizeWrote = 0;
    hr = wavFile.Write(sizeof(output_buffer), (BYTE*)output_buffer, &sizeWrote);

    if (!song_is_playing())
      break;

    if (!gui_is_exporting())
      break;

    uint new_progress = 100 * song_get_time() / song_get_length();
    if (new_progress != progress) {
      progress = new_progress;
      gui_update_export_progress(progress);
    }
  }

done:
  song_stop_playback();
  gui_close_export_progress();
  wavFile.Close();
  return hr;
}