// // Code by TLM (based on IQ framework) // #include "4klang.h" #include "mmsystem.h" #include "mmreg.h" static HWAVEOUT audio_hWaveOut = 0; // Define Audio buffer static SAMPLE_TYPE audio_buffer[MAX_SAMPLES * 2] = { 0 }; // "AUDIO_SAMPLES * 2" => so we can dump pass-1 data // Pause/Resume/Seek related variables #ifdef EXTERNAL_ROCKET_CONTROL bool audio_IsPaused = false; long audio_StartOffset = 0; // in samples #endif // Sound related structures static WAVEFORMATEX audio_WaveFMT = { #ifdef FLOAT_32BIT WAVE_FORMAT_IEEE_FLOAT, #else WAVE_FORMAT_PCM, #endif 2, // channels SAMPLE_RATE, // samples per sec SAMPLE_RATE*sizeof(SAMPLE_TYPE)* 2, // bytes per sec sizeof(SAMPLE_TYPE)* 2, // block alignment; sizeof(SAMPLE_TYPE)* 8, // bits per sample 0 // extension not needed }; static WAVEHDR audio_WaveHDR = { (LPSTR)audio_buffer, MAX_SAMPLES*sizeof(SAMPLE_TYPE)* 2, // MAX_SAMPLES*sizeof(float)*2(stereo) 0, 0, 0, 0, 0, 0 }; MMTIME audio_MMTime = { TIME_SAMPLES, 0 }; void Audio_PlayBuffer() { waveOutOpen(&audio_hWaveOut, WAVE_MAPPER, &audio_WaveFMT, NULL, 0, CALLBACK_NULL); waveOutPrepareHeader(audio_hWaveOut, &audio_WaveHDR, sizeof(audio_WaveHDR)); waveOutWrite(audio_hWaveOut, &audio_WaveHDR, sizeof(audio_WaveHDR)); } float Audio_GetCurrentTime() { // Get current played sample waveOutGetPosition(audio_hWaveOut, &audio_MMTime, sizeof(audio_MMTime)); #if defined(EXTERNAL_ROCKET_CONTROL) return (audio_StartOffset + audio_MMTime.u.sample + 1500) / (SAMPLES_PER_TICK * 0.5f); #else return (audio_MMTime.u.sample + 1500) / (SAMPLES_PER_TICK * 0.5f); #endif } #ifdef EXTERNAL_ROCKET_CONTROL void Audio_Pause(bool bPause) { // Check if there is change of current play/pause state? if (audio_IsPaused != bPause) { // Assign new state audio_IsPaused = bPause; // Change audio play state if (audio_IsPaused) waveOutPause(audio_hWaveOut); else waveOutRestart(audio_hWaveOut); } } void Audio_Seek(int row) { // Compute start offset audio_StartOffset = row * SAMPLES_PER_TICK * 0.5f; audio_WaveHDR.lpData = (LPSTR)(float*)(audio_buffer + audio_StartOffset * 2); audio_WaveHDR.dwBufferLength = (MAX_SAMPLES - audio_StartOffset) * 2 * 4; // Send buffer to waveOut waveOutReset(audio_hWaveOut); waveOutPrepareHeader(audio_hWaveOut, &audio_WaveHDR, sizeof(audio_WaveHDR)); waveOutWrite(audio_hWaveOut, &audio_WaveHDR, sizeof(audio_WaveHDR)); // Handle paused state if (audio_IsPaused) waveOutPause(audio_hWaveOut); } bool Audio_IsPlaying() { return !audio_IsPaused; } #endif