public int Play(string path, bool loop, float gain = 1.0f) { MusicThreadParameters parameters = new MusicThreadParameters(); parameters.Path = path; parameters.Loop = loop; parameters.Gain = gain; Thread musicPlayer = new Thread(musicThread); musicPlayer.Start(parameters); return(musicPlayer.ManagedThreadId); }
private void musicThread(object param) { MusicThreadParameters parameters = (MusicThreadParameters)param; MusicThreadState musicThreadState = new MusicThreadState(); musicThreadState.Play = true; musicThreadState.MusicThread = Thread.CurrentThread; musicStates[Thread.CurrentThread.ManagedThreadId] = musicThreadState; int[] buffers = AL.GenBuffers(2); int source = AL.GenSource(); AL.Source(source, ALSourcef.Gain, parameters.Gain); do { VorbisReader vorbis; lock (sync) { vorbis = new VorbisReader(parameters.Path); } ALFormat format = (vorbis.Channels == 1) ? ALFormat.Mono16 : ALFormat.Stereo16; int bufferStride = vorbis.Channels * sizeof(ushort); int bufferLength = vorbis.Channels * vorbis.SampleRate * bufferCapacityInSeconds; float[] floatBuffer = new float[bufferLength]; ushort[] pcmBuffer = new ushort[bufferLength]; int samplesRead = vorbis.ReadSamples(floatBuffer, 0, bufferLength); toPCM(pcmBuffer, floatBuffer); AL.BufferData(buffers[0], format, pcmBuffer, samplesRead * sizeof(ushort), vorbis.SampleRate); if (samplesRead > 0) { samplesRead = vorbis.ReadSamples(floatBuffer, 0, bufferLength); toPCM(pcmBuffer, floatBuffer); AL.BufferData(buffers[1], format, pcmBuffer, samplesRead * sizeof(ushort), vorbis.SampleRate); AL.SourceQueueBuffers(source, buffers.Length, buffers); AL.SourcePlay(source); while ((samplesRead > 0) && musicThreadState.Play) { if (AL.GetSourceState(source) != ALSourceState.Playing) { AL.SourcePlay(source); } int processedBuffers; AL.GetSource(source, ALGetSourcei.BuffersProcessed, out processedBuffers); if (processedBuffers > 0) { int buffer = AL.SourceUnqueueBuffer(source); samplesRead = vorbis.ReadSamples(floatBuffer, 0, bufferLength); toPCM(pcmBuffer, floatBuffer); AL.BufferData(buffer, format, pcmBuffer, samplesRead * sizeof(ushort), vorbis.SampleRate); AL.SourceQueueBuffer(source, buffer); } else { Thread.Sleep(100); } } while ((AL.GetSourceState(source) == ALSourceState.Playing) && musicThreadState.Play) { Thread.Sleep(100); } AL.Source(source, ALSourcei.Buffer, 0); } } while (parameters.Loop && musicThreadState.Play); AL.DeleteSource(source); AL.DeleteBuffers(buffers); musicStates.TryRemove(Thread.CurrentThread.ManagedThreadId, out musicThreadState); }