private void Callback(IntPtr hdrvr, WaveOutMessage uMsg, int dwUser, IntPtr waveHdr, int dwParam2) { switch (uMsg) { case WaveOutMessage.Open: mIsPlay = true; break; case WaveOutMessage.Close: break; case WaveOutMessage.Done: if (!mIsPlay) { break; } waveOutWrite(mWaveOutHandle, waveHdr, (uint)Marshal.SizeOf(typeof(WAVEHDR))); for (mBufferIndex = 0; mBufferIndex < mWaveHeader.Length; ++mBufferIndex) { if (mWaveHeaderPtr[mBufferIndex] == waveHdr) { SetData(); mWaveHeader[mBufferIndex] = (WAVEHDR)Marshal.PtrToStructure(mWaveHeaderPtr[mBufferIndex], typeof(WAVEHDR)); Marshal.Copy(WaveBuffer, 0, mWaveHeader[mBufferIndex].lpData, WaveBuffer.Length); Marshal.StructureToPtr(mWaveHeader[mBufferIndex], mWaveHeaderPtr[mBufferIndex], true); } } break; } }
/// <summary> /// Fires when the operating system has a message about a device. /// </summary> /// <param name="waveOutHandle">A handle to the device on which the message has been fired.</param> /// <param name="message">The message to be processed.</param> /// <param name="instance">A user instance value.</param> /// <param name="param1">Message parameter one.</param> /// <param name="param2">Message parameter two.</param> private void InternalCallback(IntPtr waveOutHandle, WaveOutMessage message, IntPtr instance, IntPtr param1, IntPtr param2) { if (message == WaveOutMessage.WriteDone) { lock (this.bufferingLock) { this.bufferReleaseQueue.Enqueue(param1); this.bufferQueueCount--; Monitor.Pulse(this.bufferingLock); } } if (this.MessageReceived != null) { this.MessageReceived(this, new WaveOutMessageReceivedEventArgs((WaveOutMessage)message)); } }
static void DSP_Callback(IntPtr handle, WaveOutMessage uMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2) => s_playing = false;
void ProcessWaveOutCallback( IntPtr handle, WaveOutMessage message, UIntPtr user, ref WaveHeader header, UIntPtr reserved ) { Console.WriteLine( "callback:" + message + "," + buffersIndex ); if( message == WaveOutMessage.Done ) { Free( ref header ); // TODO: This probably needs to be rewritten. // Due to the asynchronous nature of WinMm, this function can be invoked on the thread that plays the music (I think?) // It would be much better regardless of this was invoked on the thread that called the player to begin with. if( chunks.MoveNext() ) { SendNextBuffer( chunks.Current ); buffersIndex++; } else { if( buffersIndex <= 0 ) { reachedEnd = true; } } } }
/// <summary> /// Initializes a new instance of the WaveOutMessageReceivedEventArgs class with the specified message. /// </summary> /// <param name="message">The message the new instance will describe.</param> public WaveOutMessageReceivedEventArgs(WaveOutMessage message) { this.message = message; }
private void WaveOutProc(IntPtr hWaveOut, WaveOutMessage message, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2) { MMRESULT result; switch (message) { case WaveOutMessage.WOM_DONE: { // Remove data block from device so it can be freed var hdr = (WAVEHDR)Marshal.PtrToStructure(dwParam1, typeof(WAVEHDR)); if ((result = waveOutUnprepareHeader(hWaveOut, dwParam1, sizeof(WAVEHDR))) != MMRESULT.MMSYSERR_NOERROR) throw new ExternalException($"Function 'waveOutUnprepareHeader' returned error code {result}"); // Free memory used by WAVEHDR and samples Marshal.FreeHGlobal(hdr.Data); Marshal.FreeHGlobal(dwParam1); // Decrease queue size and check if audio is no longer being streamed _queueSize--; if (_fullyQueued && _queueSize <= 0) { _resetEvent.Set(); Dispose(); _synth.TTS.RemoveActiveAudio(this); } break; } } }