public override Sound SoundCreate(VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, SoundMode mode) { criticalSection.Enter(); OpenALSound sound; bool initialized; if ((int)(mode & SoundMode.Stream) == 0) { sound = new OpenALSampleSound(stream, soundType, null, mode, out initialized); if (closeStreamAfterReading) { stream.Close(); } } else { sound = new OpenALFileStreamSound(stream, closeStreamAfterReading, soundType, null, mode, out initialized); } if (!initialized) { sound.Dispose(); sound = null; } criticalSection.Leave(); return(sound); }
unsafe bool FileStream(int alStreamBuffer) { OpenALFileStreamSound fileStreamSound = (OpenALFileStreamSound)currentSound; int size = 0; streamDataAvailable = true; while (size < streamBufferSize) { byte *pointer = streamBuffer + size; int readBytes = fileStreamSound.vorbisFile.read((IntPtr)pointer, streamBufferSize - size, 0, 2, 1, IntPtr.Zero); //convert to mono for 3D if (readBytes > 0 && fileStreamSound.needConvertToMono) { readBytes /= 2; for (int n = 0; n < readBytes; n += 2) { pointer[n + 0] = pointer[n * 2 + 0]; pointer[n + 1] = pointer[n * 2 + 1]; } } if (readBytes > 0) { size += readBytes; } else { break; } } if (size == 0) { streamDataAvailable = false; return(false); } int alFormat = (currentSound.channels == 1) ? Al.AL_FORMAT_MONO16 : Al.AL_FORMAT_STEREO16; Al.alBufferData(alStreamBuffer, alFormat, streamBuffer, size, currentSound.frequency); OpenALSoundWorld.CheckError(); return(true); }
public override Sound SoundCreate(string name, SoundMode mode) { criticalSection.Enter(); OpenALSound sound; sound = (OpenALSound)base.SoundCreate(name, mode); if (sound != null) { criticalSection.Leave(); return(sound); } VirtualFileStream stream = CreateFileStream(name); if (stream == null) { criticalSection.Leave(); Log.Warning(string.Format("Creating sound \"{0}\" failed.", name)); return(null); } bool initialized; if ((mode & SoundMode.Stream) == 0) { sound = new OpenALSampleSound(stream, SoundType.Unknown, name, mode, out initialized); stream.Close(); } else { sound = new OpenALFileStreamSound(stream, true, SoundType.Unknown, name, mode, out initialized); } if (!initialized) { sound.Dispose(); sound = null; } criticalSection.Leave(); return(sound); }
public void UpdateFileStreamFromThread() { if (currentSound == null) { return; } //update buffers int processed; Al.alGetSourcei(alSource, Al.AL_BUFFERS_PROCESSED, out processed); OpenALSoundWorld.CheckError(); while (processed != 0) { int alStreamBuffer = 0; Al.alSourceUnqueueBuffers(alSource, 1, ref alStreamBuffer); OpenALSoundWorld.CheckError(); FileStream(alStreamBuffer); if (streamDataAvailable) { Al.alSourceQueueBuffers(alSource, 1, ref alStreamBuffer); OpenALSoundWorld.CheckError(); } processed--; } //play if buffer stopped (from behind internal buffers processed) int state; Al.alGetSourcei(alSource, Al.AL_SOURCE_STATE, out state); OpenALSoundWorld.CheckError(); bool stoppedNoQueued = false; if (state == Al.AL_STOPPED) { int queued; Al.alGetSourcei(alSource, Al.AL_BUFFERS_QUEUED, out queued); if (queued != 0) { Al.alSourcePlay(alSource); } else { stoppedNoQueued = true; } } //file stream played OpenALFileStreamSound fileStreamSound = (OpenALFileStreamSound)currentSound; if (!streamDataAvailable && stoppedNoQueued) { if ((currentSound.Mode & SoundMode.Loop) != 0) { //loop play. we need recreate vorbis file //stop and unqueues sources Al.alSourceStop(alSource); Al.alGetSourcei(alSource, Al.AL_BUFFERS_PROCESSED, out processed); OpenALSoundWorld.CheckError(); while (processed != 0) { int alStreamBuffer = 0; Al.alSourceUnqueueBuffers(alSource, 1, ref alStreamBuffer); OpenALSoundWorld.CheckError(); processed--; } //recreate vorbis file fileStreamSound.Rewind(); FileStreamStartPlay(); //Pause = false; Al.alSourcePlay(alSource); OpenALSoundWorld.CheckError(); } else { CurrentVirtualChannel.Stop(); } } }
unsafe protected override void PostAttachVirtualChannel() { OpenALSoundWorld.criticalSection.Enter(); currentSound = (OpenALSound)CurrentVirtualChannel.CurrentSound; OpenALSampleSound sampleSound = currentSound as OpenALSampleSound; OpenALDataBufferSound streamSound = null; OpenALFileStreamSound fileStreamSound = null; OpenALDataStreamSound dataStreamSound = null; if (sampleSound == null) { streamSound = currentSound as OpenALDataBufferSound; fileStreamSound = currentSound as OpenALFileStreamSound; dataStreamSound = currentSound as OpenALDataStreamSound; } //create streamBuffer if (fileStreamSound != null) { int bufferSize = 0; int numSamples = (int)fileStreamSound.vorbisFile.pcm_total(-1); int channels; int rate; fileStreamSound.vorbisFile.get_info(-1, out channels, out rate); if (fileStreamSound.needConvertToMono) { channels = 1; } int sizeInBytes = numSamples * channels * 2; bufferSize = sizeInBytes / 2; if (bufferSize > 65536 * 4) { bufferSize = 65536 * 4; } streamBufferSize = bufferSize; streamBuffer = (byte *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, streamBufferSize); } if (dataStreamSound != null) { streamBufferSize = dataStreamSound.bufferSize; streamBuffer = (byte *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, streamBufferSize); } //init source bool mode3d = (currentSound.Mode & SoundMode.Mode3D) != 0; bool loop = (currentSound.Mode & SoundMode.Loop) != 0; if (alSource == 0) { Al.alGenSources(1, out alSource); if (OpenALSoundWorld.CheckError()) { PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } } if (sampleSound != null) { //no stream sound Al.alSourcei(alSource, Al.AL_BUFFER, sampleSound.alBuffer); if (OpenALSoundWorld.CheckError()) { PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } } if (fileStreamSound != null) { FileStreamStartPlay(); } if (dataStreamSound != null) { DataStreamStartPlay(); } Al.alSourcei(alSource, Al.AL_SOURCE_RELATIVE, mode3d ? Al.AL_FALSE : Al.AL_TRUE); //update parameters if (mode3d) { UpdatePosition2(); UpdateVelocity2(); } else { UpdatePan2(); } UpdatePitch2(); UpdateVolume2(); if (sampleSound != null) { Al.alSourcei(alSource, Al.AL_LOOPING, loop ? Al.AL_TRUE : Al.AL_FALSE); } else { Al.alSourcei(alSource, Al.AL_LOOPING, Al.AL_FALSE); } if (OpenALSoundWorld.CheckError()) { PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } UpdateTime2(); //unpause Al.alSourcePlay(alSource); OpenALSoundWorld.CheckError(); //add to fileStreamChannels if (fileStreamSound != null) { OpenALSoundWorld.Instance.fileStreamRealChannels.Add(this); } OpenALSoundWorld.criticalSection.Leave(); }
unsafe internal protected override void PostAttachVirtualChannel() { OpenALSoundWorld.criticalSection.Enter(); currentSound = (OpenALSound)CurrentVirtualChannel.Sound; OpenALSampleSound sampleSound = currentSound as OpenALSampleSound; OpenALDataBufferSound streamSound = null; OpenALFileStreamSound fileStreamSound = null; OpenALDataStreamSound dataStreamSound = null; if (sampleSound == null) { streamSound = currentSound as OpenALDataBufferSound; fileStreamSound = currentSound as OpenALFileStreamSound; dataStreamSound = currentSound as OpenALDataStreamSound; } //create streamBuffer if (fileStreamSound != null) { var stream = OpenALSoundWorld.CreateFileStream2(currentSound.Name); if (stream == null) { //Log.Warning( string.Format( "Creating sound \"{0}\" failed.", currentSound.Name ) ); PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } fileStreamVorbisFile = new VorbisFile.File(); fileStreamVorbisFileReader = new VorbisFileReader(stream, true); if (!fileStreamVorbisFileReader.OpenVorbisFile(fileStreamVorbisFile)) { //Log.Warning( string.Format( "Creating sound \"{0}\" failed.", currentSound.Name ) ); PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } int numSamples = (int)fileStreamVorbisFile.pcm_total(-1); fileStreamVorbisFile.get_info(-1, out var channels, out var frequency); //int numSamples = (int)fileStreamSound.vorbisFile.pcm_total( -1 ); //fileStreamSound.vorbisFile.get_info( -1, out var channels, out var rate ); if (fileStreamSound.needConvertToMono) { channels = 1; } int sizeInBytes = numSamples * channels * 2; int bufferSize = sizeInBytes / 2; if (bufferSize > 65536 * 4) { bufferSize = 65536 * 4; } streamBufferSize = bufferSize; streamBuffer = (byte *)NativeUtility.Alloc(NativeUtility.MemoryAllocationType.SoundAndVideo, streamBufferSize); } if (dataStreamSound != null) { streamBufferSize = dataStreamSound.bufferSize; streamBuffer = (byte *)NativeUtility.Alloc(NativeUtility.MemoryAllocationType.SoundAndVideo, streamBufferSize); } //create al data buffers if (fileStreamSound != null || dataStreamSound != null) { if (streamAlDataBuffers == null) { streamAlDataBuffers = new int[2]; fixed(int *pAlDataBuffers = streamAlDataBuffers) Al.alGenBuffers(streamAlDataBuffers.Length, pAlDataBuffers); if (OpenALSoundWorld.CheckError()) { streamAlDataBuffers = null; PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } } } //init source bool mode3d = (currentSound.Mode & SoundModes.Mode3D) != 0; bool loop = (currentSound.Mode & SoundModes.Loop) != 0; if (alSource == 0) { Al.alGenSources(1, out alSource); if (OpenALSoundWorld.CheckError()) { PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } } if (sampleSound != null) { //no stream sound Al.alSourcei(alSource, Al.AL_BUFFER, sampleSound.alBuffer); if (OpenALSoundWorld.CheckError()) { PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } } if (fileStreamSound != null) { FileStreamStartPlay(); } if (dataStreamSound != null) { DataStreamStartPlay(); } Al.alSourcei(alSource, Al.AL_SOURCE_RELATIVE, mode3d ? Al.AL_FALSE : Al.AL_TRUE); //update parameters if (mode3d) { UpdatePosition2(); UpdateVelocity2(); } else { UpdatePan2(); } UpdatePitch2(); UpdateVolume2(); if (sampleSound != null) { Al.alSourcei(alSource, Al.AL_LOOPING, loop ? Al.AL_TRUE : Al.AL_FALSE); } else { Al.alSourcei(alSource, Al.AL_LOOPING, Al.AL_FALSE); } if (OpenALSoundWorld.CheckError()) { PreDetachVirtualChannel(); OpenALSoundWorld.criticalSection.Leave(); return; } UpdateTime2(); //unpause Al.alSourcePlay(alSource); OpenALSoundWorld.CheckError(); //add to fileStreamChannels if (fileStreamSound != null) { OpenALSoundWorld.fileStreamRealChannels.Add(this); } OpenALSoundWorld.criticalSection.Leave(); }
public override Sound SoundCreate( VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, SoundMode mode ) { criticalSection.Enter(); OpenALSound sound; bool initialized; if( (int)( mode & SoundMode.Stream ) == 0 ) { sound = new OpenALSampleSound( stream, soundType, null, mode, out initialized ); if( closeStreamAfterReading ) stream.Close(); } else { sound = new OpenALFileStreamSound( stream, closeStreamAfterReading, soundType, null, mode, out initialized ); } if( !initialized ) { sound.Dispose(); sound = null; } criticalSection.Leave(); return sound; }
public override Sound SoundCreate( string name, SoundMode mode ) { criticalSection.Enter(); OpenALSound sound; sound = (OpenALSound)base.SoundCreate( name, mode ); if( sound != null ) { criticalSection.Leave(); return sound; } VirtualFileStream stream = CreateFileStream( name ); if( stream == null ) { criticalSection.Leave(); Log.Warning( string.Format( "Creating sound \"{0}\" failed.", name ) ); return null; } bool initialized; if( ( mode & SoundMode.Stream ) == 0 ) { sound = new OpenALSampleSound( stream, SoundType.Unknown, name, mode, out initialized ); stream.Close(); } else { sound = new OpenALFileStreamSound( stream, true, SoundType.Unknown, name, mode, out initialized ); } if( !initialized ) { sound.Dispose(); sound = null; } criticalSection.Leave(); return sound; }