// public OpenALFileStreamSound(VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, string name, SoundMode mode, out bool initialized) { initialized = false; if (soundType == SoundType.Unknown) { if (name != null) { soundType = GetSoundTypeByName(name); } else { soundType = GetSoundTypeByStream(stream); } } if (soundType != SoundType.OGG) { Log.Warning(string.Format("Streaming is not supported for \"{0}\" files ({1}).", soundType, name)); return; } vorbisFile = new VorbisFile.File(); vorbisFileReader = new VorbisFileReader(stream, closeStreamAfterReading); if (!vorbisFileReader.OpenVorbisFile(vorbisFile)) { vorbisFileReader.Dispose(); Log.Warning(string.Format("Creating sound \"{0}\" failed.", name)); return; } long numSamples = vorbisFile.pcm_total(-1); vorbisFile.get_info(-1, out channels, out frequency); //convert to mono for 3D if ((mode & SoundMode.Mode3D) != 0 && channels == 2) { needConvertToMono = true; channels = 1; } if (!GenerateBuffers(2)) { Log.Warning("OpenALSoundSystem: Creating sound failed \"{0}\".", name); return; } double length = (double)numSamples / (double)frequency; Init(name, mode, (float)length, channels, frequency); initialized = true; }
// unsafe public DirectFileStreamSound(VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, string name, SoundMode mode, out bool initialized) { initialized = false; if (soundType == SoundType.Unknown) { if (name != null) { soundType = GetSoundTypeByName(name); } else { soundType = GetSoundTypeByStream(stream); } } if (soundType != SoundType.OGG) { DirectSoundWorld.Warning(string.Format( "Streaming is not supported for \"{0}\" files ({1}).", soundType, name)); return; } vorbisFile = new VorbisFile.File(); vorbisFileReader = new VorbisFileReader(stream, closeStreamAfterReading); if (!vorbisFileReader.OpenVorbisFile(vorbisFile)) { vorbisFileReader.Dispose(); DirectSoundWorld.Warning(string.Format("Creating sound \"{0}\" failed.", name)); return; } int channels; int frequency; long numSamples = vorbisFile.pcm_total(-1); vorbisFile.get_info(-1, out channels, out frequency); //convert to mono for 3D if ((int)(mode & SoundMode.Mode3D) != 0 && channels == 2) { needConvertToMono = true; channels = 1; } waveFormat = (WAVEFORMATEX *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, sizeof(WAVEFORMATEX)); NativeUtils.ZeroMemory((IntPtr)waveFormat, sizeof(WAVEFORMATEX)); waveFormat->wFormatTag = DSound.WAVE_FORMAT_PCM; waveFormat->nChannels = (ushort)channels; waveFormat->nSamplesPerSec = (uint)frequency; waveFormat->wBitsPerSample = 16; waveFormat->nBlockAlign = (ushort)((waveFormat->nChannels * waveFormat->wBitsPerSample) / 8); waveFormat->nAvgBytesPerSec = waveFormat->nSamplesPerSec * waveFormat->nBlockAlign; double length = (double)numSamples / (double)frequency; Init(name, mode, (float)length, channels, frequency); initialized = true; }
// bool LoadSamplesFromStream(VirtualFileStream stream, SoundType soundType, out int channels, out int frequency, out float timeLength, out string error) { channels = 0; frequency = 0; timeLength = 0; error = null; switch (soundType) { case SoundType.OGG: { VorbisFileReader vorbisFileReader = new VorbisFileReader(stream, false); VorbisFile.File vorbisFile = new VorbisFile.File(); if (!vorbisFileReader.OpenVorbisFile(vorbisFile)) { vorbisFile.Dispose(); vorbisFileReader.Dispose(); error = "Reading failed"; return(false); } int numSamples = (int)vorbisFile.pcm_total(-1); vorbisFile.get_info(-1, out channels, out frequency); timeLength = (float)vorbisFile.time_total(-1); int size = numSamples * channels; int sizeInBytes = size * 2; soundSamples = new byte[sizeInBytes]; unsafe { fixed(byte *pSoundSamples = soundSamples) { int samplePos = 0; while (samplePos < sizeInBytes) { int readBytes = vorbisFile.read((IntPtr)(pSoundSamples + samplePos), sizeInBytes - samplePos, 0, 2, 1, IntPtr.Zero); if (readBytes <= 0) { break; } samplePos += readBytes; } } } vorbisFile.Dispose(); vorbisFileReader.Dispose(); } return(true); case SoundType.WAV: { int sizeInBytes; if (!WavLoader.Load(stream, out channels, out frequency, out soundSamples, out sizeInBytes, out error)) { return(false); } timeLength = (float)(soundSamples.Length / channels / 2) / (float)frequency; } return(true); } error = "Unknown file type"; return(false); }
unsafe public OpenALSampleSound( VirtualFileStream stream, SoundType soundType, string name, SoundMode mode, out bool initialized ) { initialized = false; byte[] samples; int sizeInBytes; float timeLength; if( string.Compare( Path.GetExtension( name ), ".ogg", true ) == 0 ) { //ogg VorbisFileReader vorbisFileReader = new VorbisFileReader( stream, false ); VorbisFile.File vorbisFile = new VorbisFile.File(); if( !vorbisFileReader.OpenVorbisFile( vorbisFile ) ) { vorbisFile.Dispose(); vorbisFileReader.Dispose(); Log.Warning( "OpenALSoundSystem: Creating sound failed \"{0}\" (Reading failed).", name ); return; } int numSamples = (int)vorbisFile.pcm_total( -1 ); vorbisFile.get_info( -1, out channels, out frequency ); timeLength = (float)vorbisFile.time_total( -1 ); sizeInBytes = numSamples * channels * 2; samples = new byte[ sizeInBytes ]; fixed( byte* pSamples = samples ) { int samplePos = 0; while( samplePos < sizeInBytes ) { int readBytes = vorbisFile.read( (IntPtr)( pSamples + samplePos ), sizeInBytes - samplePos, 0, 2, 1, IntPtr.Zero ); if( readBytes <= 0 ) break; samplePos += readBytes; } } vorbisFile.Dispose(); vorbisFileReader.Dispose(); } else if( string.Compare( Path.GetExtension( name ), ".wav", true ) == 0 ) { //wav string error; if( !WavLoader.Load( stream, out channels, out frequency, out samples, out sizeInBytes, out error ) ) { Log.Warning( "OpenALSoundSystem: Creating sound failed \"{0}\" ({1}).", name, error ); return; } timeLength = (float)( samples.Length / channels / 2 ) / (float)frequency; } else { Log.Warning( "OpenALSoundSystem: Creating sound failed \"{0}\" (Unknown file type).", name ); return; } //create buffer Al.alGenBuffers( 1, out alBuffer ); int alFormat = ( channels == 1 ) ? Al.AL_FORMAT_MONO16 : Al.AL_FORMAT_STEREO16; //bug fix: half volume mono 2D sounds //convert to stereo if( ( mode & SoundMode.Mode3D ) == 0 && alFormat == Al.AL_FORMAT_MONO16 ) { byte[] stereoSamples = new byte[ sizeInBytes * 2 ]; for( int n = 0; n < sizeInBytes; n += 2 ) { stereoSamples[ n * 2 + 0 ] = samples[ n ]; stereoSamples[ n * 2 + 1 ] = samples[ n + 1 ]; stereoSamples[ n * 2 + 2 ] = samples[ n ]; stereoSamples[ n * 2 + 3 ] = samples[ n + 1 ]; } samples = stereoSamples; alFormat = Al.AL_FORMAT_STEREO16; sizeInBytes *= 2; } //convert to mono for 3D if( ( mode & SoundMode.Mode3D ) != 0 && channels == 2 ) { byte[] oldSamples = samples; samples = new byte[ oldSamples.Length / 2 ]; for( int n = 0; n < samples.Length; n += 2 ) { samples[ n + 0 ] = oldSamples[ n * 2 + 0 ]; samples[ n + 1 ] = oldSamples[ n * 2 + 1 ]; } alFormat = Al.AL_FORMAT_MONO16; sizeInBytes /= 2; } fixed( byte* pSamples = samples ) { Al.alBufferData( alBuffer, alFormat, pSamples, sizeInBytes, frequency ); } if( OpenALSoundWorld.CheckError() ) { Log.Warning( "OpenALSoundSystem: Creating sound failed \"{0}\".", name ); return; } Init( name, mode, timeLength, channels, frequency ); initialized = true; }
// public OpenALFileStreamSound( VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, string name, SoundMode mode, out bool initialized ) { initialized = false; if( soundType == SoundType.Unknown ) { if( name != null ) soundType = GetSoundTypeByName( name ); else soundType = GetSoundTypeByStream( stream ); } if( soundType != SoundType.OGG ) { Log.Warning( string.Format( "Streaming is not supported for \"{0}\" files ({1}).", soundType, name ) ); return; } vorbisFile = new VorbisFile.File(); vorbisFileReader = new VorbisFileReader( stream, closeStreamAfterReading ); if( !vorbisFileReader.OpenVorbisFile( vorbisFile ) ) { vorbisFileReader.Dispose(); Log.Warning( string.Format( "Creating sound \"{0}\" failed.", name ) ); return; } long numSamples = vorbisFile.pcm_total( -1 ); vorbisFile.get_info( -1, out channels, out frequency ); //convert to mono for 3D if( ( mode & SoundMode.Mode3D ) != 0 && channels == 2 ) { needConvertToMono = true; channels = 1; } if( !GenerateBuffers( 2 ) ) { Log.Warning( "OpenALSoundSystem: Creating sound failed \"{0}\".", name ); return; } double length = (double)numSamples / (double)frequency; Init( name, mode, (float)length, channels, frequency ); initialized = true; }
unsafe public OpenALSampleSound(VirtualFileStream stream, SoundType soundType, string name, SoundModes mode, out bool initialized) { initialized = false; byte[] samples; int sizeInBytes; float timeLength; if (string.Compare(Path.GetExtension(name), ".ogg", true) == 0) { //ogg VorbisFileReader vorbisFileReader = new VorbisFileReader(stream, false); VorbisFile.File vorbisFile = new VorbisFile.File(); if (!vorbisFileReader.OpenVorbisFile(vorbisFile)) { vorbisFile.Dispose(); vorbisFileReader.Dispose(); Log.Warning("OpenALSoundSystem: Creating sound failed \"{0}\" (Reading failed).", name); return; } int numSamples = (int)vorbisFile.pcm_total(-1); vorbisFile.get_info(-1, out channels, out frequency); timeLength = (float)vorbisFile.time_total(-1); sizeInBytes = numSamples * channels * 2; samples = new byte[sizeInBytes]; fixed(byte *pSamples = samples) { int samplePos = 0; while (samplePos < sizeInBytes) { int readBytes = vorbisFile.read((IntPtr)(pSamples + samplePos), sizeInBytes - samplePos, 0, 2, 1, IntPtr.Zero); if (readBytes <= 0) { break; } samplePos += readBytes; } } vorbisFile.Dispose(); vorbisFileReader.Dispose(); } else if (string.Compare(Path.GetExtension(name), ".wav", true) == 0) { //wav string error; if (!WavLoader.Load(stream, out channels, out frequency, out samples, out sizeInBytes, out error)) { Log.Warning("OpenALSoundSystem: Creating sound failed \"{0}\" ({1}).", name, error); return; } timeLength = (float)(samples.Length / channels / 2) / (float)frequency; } else { Log.Warning("OpenALSoundSystem: Creating sound failed \"{0}\" (Unknown file type).", name); return; } //create buffer Al.alGenBuffers(1, out alBuffer); int alFormat = (channels == 1) ? Al.AL_FORMAT_MONO16 : Al.AL_FORMAT_STEREO16; //bug fix: half volume mono 2D sounds //convert to stereo if ((mode & SoundModes.Mode3D) == 0 && alFormat == Al.AL_FORMAT_MONO16) { byte[] stereoSamples = new byte[sizeInBytes * 2]; for (int n = 0; n < sizeInBytes; n += 2) { stereoSamples[n * 2 + 0] = samples[n]; stereoSamples[n * 2 + 1] = samples[n + 1]; stereoSamples[n * 2 + 2] = samples[n]; stereoSamples[n * 2 + 3] = samples[n + 1]; } samples = stereoSamples; alFormat = Al.AL_FORMAT_STEREO16; sizeInBytes *= 2; } //convert to mono for 3D if ((mode & SoundModes.Mode3D) != 0 && channels == 2) { byte[] oldSamples = samples; samples = new byte[oldSamples.Length / 2]; for (int n = 0; n < samples.Length; n += 2) { samples[n + 0] = oldSamples[n * 2 + 0]; samples[n + 1] = oldSamples[n * 2 + 1]; } alFormat = Al.AL_FORMAT_MONO16; sizeInBytes /= 2; } fixed(byte *pSamples = samples) Al.alBufferData(alBuffer, alFormat, pSamples, sizeInBytes, frequency); if (OpenALSoundWorld.CheckError()) { Log.Warning("OpenALSoundSystem: Creating sound failed \"{0}\".", name); return; } Init(name, mode, timeLength, channels, frequency); initialized = true; }
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(); }
// unsafe public DirectFileStreamSound( VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, string name, SoundMode mode, out bool initialized ) { initialized = false; if( soundType == SoundType.Unknown ) { if( name != null ) soundType = GetSoundTypeByName( name ); else soundType = GetSoundTypeByStream( stream ); } if( soundType != SoundType.OGG ) { DirectSoundWorld.Warning( string.Format( "Streaming is not supported for \"{0}\" files ({1}).", soundType, name ) ); return; } vorbisFile = new VorbisFile.File(); vorbisFileReader = new VorbisFileReader( stream, closeStreamAfterReading ); if( !vorbisFileReader.OpenVorbisFile( vorbisFile ) ) { vorbisFileReader.Dispose(); DirectSoundWorld.Warning( string.Format( "Creating sound \"{0}\" failed.", name ) ); return; } int channels; int frequency; long numSamples = vorbisFile.pcm_total( -1 ); vorbisFile.get_info( -1, out channels, out frequency ); //convert to mono for 3D if( (int)( mode & SoundMode.Mode3D ) != 0 && channels == 2 ) { needConvertToMono = true; channels = 1; } waveFormat = (WAVEFORMATEX*)NativeUtils.Alloc( NativeMemoryAllocationType.SoundAndVideo, sizeof( WAVEFORMATEX ) ); NativeUtils.ZeroMemory( (IntPtr)waveFormat, sizeof( WAVEFORMATEX ) ); waveFormat->wFormatTag = DSound.WAVE_FORMAT_PCM; waveFormat->nChannels = (ushort)channels; waveFormat->nSamplesPerSec = (uint)frequency; waveFormat->wBitsPerSample = 16; waveFormat->nBlockAlign = (ushort)( ( waveFormat->nChannels * waveFormat->wBitsPerSample ) / 8 ); waveFormat->nAvgBytesPerSec = waveFormat->nSamplesPerSec * waveFormat->nBlockAlign; double length = (double)numSamples / (double)frequency; Init( name, mode, (float)length, channels, frequency ); initialized = true; }
// bool LoadSamplesFromStream( VirtualFileStream stream, SoundType soundType, out int channels, out int frequency, out float timeLength, out string error ) { channels = 0; frequency = 0; timeLength = 0; error = null; switch( soundType ) { case SoundType.OGG: { VorbisFileReader vorbisFileReader = new VorbisFileReader( stream, false ); VorbisFile.File vorbisFile = new VorbisFile.File(); if( !vorbisFileReader.OpenVorbisFile( vorbisFile ) ) { vorbisFile.Dispose(); vorbisFileReader.Dispose(); error = "Reading failed"; return false; } int numSamples = (int)vorbisFile.pcm_total( -1 ); vorbisFile.get_info( -1, out channels, out frequency ); timeLength = (float)vorbisFile.time_total( -1 ); int size = numSamples * channels; int sizeInBytes = size * 2; soundSamples = new byte[ sizeInBytes ]; unsafe { fixed( byte* pSoundSamples = soundSamples ) { int samplePos = 0; while( samplePos < sizeInBytes ) { int readBytes = vorbisFile.read( (IntPtr)( pSoundSamples + samplePos ), sizeInBytes - samplePos, 0, 2, 1, IntPtr.Zero ); if( readBytes <= 0 ) break; samplePos += readBytes; } } } vorbisFile.Dispose(); vorbisFileReader.Dispose(); } return true; case SoundType.WAV: { int sizeInBytes; if( !WavLoader.Load( stream, out channels, out frequency, out soundSamples, out sizeInBytes, out error ) ) { return false; } timeLength = (float)( soundSamples.Length / channels / 2 ) / (float)frequency; } return true; } error = "Unknown file type"; return false; }