예제 #1
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            // adjust count so it is in floats instead of bytes
            count /= sizeof(float);

            // make sure we don't have an odd count
            count -= count % m_reader.Channels;

            // get the buffer, creating a new one if none exists or the existing one is too small
            var cb = _conversionBuffer ?? (_conversionBuffer = new float[count]);

            if (cb.Length < count)
            {
                cb = (_conversionBuffer = new float[count]);
            }

            // let ReadSamples(float[], int, int) do the actual reading; adjust count back to bytes
            int cnt = m_reader.ReadSamples(cb, 0, count) * sizeof(float);

            // move the data back to the request buffer
            Buffer.BlockCopy(cb, 0, buffer, offset, cnt);

            // done!
            return(cnt);
        }
예제 #2
0
        private SoundEffect LoadSound(Stream stream, int length, string extension)
        {
            switch (extension)
            {
            case ".wav":
                if (!stream.CanSeek)
                {
                    stream = new MemoryStream(stream.ReadBytes(length));
                }
                return(SoundEffect.FromStream(stream));

            case ".mp3":
                using (var mp3Stream = new MP3Stream(stream))
                    using (var ms = new MemoryStream()) {
                        mp3Stream.CopyTo(ms);
                        return(new SoundEffect(ms.ToArray(), mp3Stream.Frequency, (AudioChannels)mp3Stream.ChannelCount));
                    }

            case ".ogg":
                using (var reader = new VorbisReader(stream, true)) {
                    var buffer   = new byte[reader.TotalSamples * 2 * reader.Channels];
                    var floatBuf = new float[buffer.Length / 2];
                    reader.ReadSamples(floatBuf, 0, floatBuf.Length);
                    MusicStreamingOGG.Convert(floatBuf, buffer);
                    return(new SoundEffect(buffer, reader.SampleRate, (AudioChannels)reader.Channels));
                }
            }
            throw new ResourceLoadException("Unknown sound extension " + extension);
        }
예제 #3
0
        public override AudioClip Load(Identifier name, Uri uri)
        {
            using var reader = new VorbisReader(uri.LocalPath)
                  {
                      ClipSamples = true
                  };

            var channels = reader.Channels;
            var format   = channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;

            var sampleRate = reader.SampleRate;

            // TODO use stream-able clip for large sounds
            var totalTime = reader.TotalTime;
            var buffer    = new float[channels * sampleRate * (int)System.Math.Ceiling(totalTime.TotalSeconds)];

            var count = 0;
            int read;

            do
            {
                read   = reader.ReadSamples(buffer, count, buffer.Length - count);
                count += read;
            } while (read > 0);

            var audioClip = new AudioClip(format, sampleRate);
            var data      = Convert(buffer);

            audioClip.SetData(data);
            return(audioClip);
        }
예제 #4
0
        /// <summary>
        /// Extract the bufferdata from an ogg-file.
        /// </summary>
        /// <param name="file">The file to load the data from.</param>
        /// <returns>A SoundBufferData object containing the data from the specified file.</returns>
        public static SoundBufferData FromOgg(Stream file)
        {
            var buffers = new List <short[]>();

            ALFormat format;
            int      sampleRate;

            using (var vorbis = new VorbisReader(file, true))
            {
                // Save format and samplerate for playback
                format     = vorbis.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
                sampleRate = vorbis.SampleRate;

                var buffer = new float[16384];
                int count;

                while ((count = vorbis.ReadSamples(buffer, 0, buffer.Length)) > 0)
                {
                    // Sample value range is -0.99999994f to 0.99999994f
                    // Samples are interleaved (chan0, chan1, chan0, chan1, etc.)

                    // Use the OggStreamer method to cast to the right format
                    var castBuffer = new short[count];
                    SoundBufferData.CastBuffer(buffer, castBuffer, count);
                    buffers.Add(castBuffer);
                }
            }

            return(new SoundBufferData(buffers, format, sampleRate));
        }
예제 #5
0
            private static void LoadOgg(VorbisReader vorbis, out byte[] data, out ALFormat format, out uint sampleRate, out TimeSpan len)
            {
                sampleRate = (uint)vorbis.SampleRate;
                format     = vorbis.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
                len        = vorbis.TotalTime;

                float[]     buffer = new float[vorbis.SampleRate / 10 * vorbis.Channels];
                List <byte> bytes  = new List <byte>((int)(vorbis.SampleRate * vorbis.Channels * 2 * len.TotalSeconds));
                int         count  = 0;

                while ((count = vorbis.ReadSamples(buffer, 0, buffer.Length)) > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        int temp = (int)(short.MaxValue * buffer[i]);
                        if (temp > short.MaxValue)
                        {
                            temp = short.MaxValue;
                        }
                        else if (temp < short.MinValue)
                        {
                            temp = short.MinValue;
                        }
                        short tempBytes = (short)temp;
                        byte  byte1     = (byte)((tempBytes >> 8) & 0x00FF);
                        byte  byte2     = (byte)((tempBytes >> 0) & 0x00FF);

                        // Little endian
                        bytes.Add(byte2);
                        bytes.Add(byte1);
                    }
                }
                // TODO: Add better implementation so that there's no need for array copying
                data = bytes.ToArray();
            }
        public static SoundStats <float> LoadNVorbisData(string fileName)
        {
            var result = new SoundStats <float>();

            var reader = new VorbisReader(fileName);

            result.SampleRate   = reader.SampleRate;
            result.TotalSeconds = (float)reader.TotalTime.TotalSeconds;
            result.Channels     = reader.Channels;

            var dataResult = new List <float>();

            float[] buffer = new float[reader.Channels * reader.SampleRate];             // 200ms

            while (reader.ReadSamples(buffer, 0, buffer.Length) > 0)
            {
                dataResult.AddRange(buffer);
            }

            switch (reader.Channels)
            {
            case 1:
                result.Format = AudioFormat.Mono32Float;
                break;

            case 2:
                result.Format = AudioFormat.StereoFloat32;
                break;
            }

            result.BufferData = dataResult.ToArray();

            return(result);
        }
예제 #7
0
        internal unsafe AudioClip(IResource resource)
        {
            Al.GenBuffer(out Buffer);

            using var reader = new VorbisReader(resource.OpenStream());

            var channels   = reader.Channels;
            var sampleRate = reader.SampleRate;
            var seconds    = reader.TotalTime.TotalSeconds;
            var samples    = (int)Math.Ceiling(seconds * sampleRate * channels);

            var floats = new Span <float>(new float[samples]);

            if (reader.ReadSamples(floats) <= 0)
            {
                throw new Exception("Failed to read OGG stream.");
            }

            var shorts = new Span <short>(new short[samples]); // 16 bit

            for (var i = 0; i < floats.Length; i++)
                shorts[i] = (short)(short.MaxValue * floats[i]);

            fixed(void *p = &shorts.GetPinnableReference())
            {
                Al.BufferData(Buffer, channels == 2 ? Al.FormatStereo16 : Al.FormatMono16, p, shorts.Length * sizeof(short), sampleRate);
            }
        }
예제 #8
0
        // This is used to load audio files that supported by NVorbis like ogg
        public static AudioClip LoadOggAudioFile(string path)
        {
            float[] audioData  = null;
            int     channels   = 0;
            int     sampleRate = 0; try

            {
                using (VorbisReader reader = new VorbisReader(path))
                {
                    //Note: Same here
                    if (reader.TotalSamples * reader.Channels > 0x7FFFFFFFL)
                    {
                        return(null);
                    }
                    float[] data = new float[reader.TotalSamples * reader.Channels];
                    reader.ReadSamples(data, 0, (int)(reader.TotalSamples * reader.Channels));
                    channels   = reader.Channels;
                    sampleRate = reader.SampleRate;
                    audioData  = data;
                }
            }
            catch
            {
                return(null);
            }
            if (audioData == null)
            {
                return(null);
            }
            AudioDataHost dataHost = new AudioDataHost(audioData, channels);
            AudioClip     clip     = AudioClip.Create(path, audioData.Length / channels, channels, sampleRate, true, dataHost.PCMReaderCallback, dataHost.PCMSetPositionCallback);

            return(clip);
        }
예제 #9
0
        public ConvertOGG()
        {
            DirectoryInfo dInfo = new DirectoryInfo(@"C:\Games\Thief2\FMs\DCE_v1\snd\ogg");

            FileInfo[] oggFiles = dInfo.GetFiles("*.ogg", SearchOption.TopDirectoryOnly);

            for (int i = 0; i < oggFiles.Length; i++)
            {
                //to do - figure out how to do this.
                VorbisReader vR      = new VorbisReader(oggFiles[i].FullName);
                long         samples = vR.TotalSamples;
                float[]      f       = new float[samples];
                vR.ReadSamples(f, 0, f.Length);

                byte[] sndByte = new byte[f.Length];
                for (int j = 0; j < f.Length; j++)
                {
                    float fl = f[j];
                    sndByte[j] = (byte)fl;
                }

                WaveFormat     wFormat = new WaveFormat();
                string         wName   = oggFiles[i].FullName.Replace(oggFiles[i].Extension, ".wav");
                WaveFileWriter writer  = new WaveFileWriter(wName, wFormat);

                writer.Write(sndByte, 0, sndByte.Length);
            }
        }
예제 #10
0
 public void OnAudioFilterRead(float[] data, int ch)
 {
     if (isReady)
     {
         int num = vorbisReader.ReadSamples(data, 0, data.Length);
         if (num != data.Length && vorbisReader.DecodedPosition >= vorbisReader.TotalSamples && isLoop)
         {
             vorbisReader.DecodedPosition = loopPoint;
             num += vorbisReader.ReadSamples(data, num, data.Length - num);
         }
         for (int i = 0; i < num; i++)
         {
             data[i] = data[i] * volume * subVolume * chvolume[i % 2];
         }
     }
 }
예제 #11
0
        static void PlayOGG(string filename)
        {
            var buffers = Initialize(out IntPtr device, out ContextHandle context, out int source);

            var vorbis      = new VorbisReader(string.Format(AudioFilesPathFormat, filename));
            var stream      = new MemoryStream();
            var samples     = new float[vorbis.Channels * vorbis.SampleRate];
            var samplesRead = 0;

            while ((samplesRead = vorbis.ReadSamples(samples, 0, samples.Length)) > 0)
            {
                var readBuffer = new byte[samplesRead * 4];
                Buffer.BlockCopy(samples, 0, readBuffer, 0, readBuffer.Length);

                stream.Write(readBuffer, 0, readBuffer.Length);
            }

            stream.Position = 0;

            PlayAndDispose(stream, buffers, source, vorbis.SampleRate);

            vorbis.Dispose();
            vorbis = null;

            Dispose(ref device, ref context);
        }
예제 #12
0
        private void FillBuffers(int buffers = 3, int samples = 44100)
        {
            float[] sampleBuffer = null;

            while (mInstance.PendingBufferCount < buffers && mReader != null)
            {
                if (sampleBuffer == null)
                {
                    sampleBuffer = new float[samples];
                }

                var read = mReader.ReadSamples(sampleBuffer, 0, sampleBuffer.Length);
                if (read == 0)
                {
                    mReader.DecodedPosition = 0;
                    continue;
                }

                var dataBuffer = new byte[read << 1];
                for (var sampleIndex = 0; sampleIndex < read; ++sampleIndex)
                {
                    var sample     = (short)MathHelper.Clamp(sampleBuffer[sampleIndex] * 32767f, short.MinValue, short.MaxValue);
                    var sampleData = BitConverter.GetBytes(sample);
                    for (var sampleByteIndex = 0; sampleByteIndex < sampleData.Length; ++sampleByteIndex)
                    {
                        dataBuffer[(sampleIndex << 1) + sampleByteIndex] = sampleData[sampleByteIndex];
                    }
                }

                mInstance.SubmitBuffer(dataBuffer, 0, read << 1);
            }
        }
예제 #13
0
        public byte[] ReadSamples(int samples)
        {
            var bytes  = Array.Empty <byte>();
            var offset = 0;

            while (samples > 0)
            {
                var sampleCount = Math.Min(samples, _buffer.Length);

                var read = _reader.ReadSamples(_buffer, 0, sampleCount);

                var byteCount = read * sizeof(ushort);

                if (offset + byteCount > bytes.Length)
                {
                    Array.Resize(ref bytes, offset + byteCount);
                }

                for (var i = 0; i < read; i++)
                {
                    var sample = _buffer[i];
                    var asPCM  = (ushort)(sample * sc16);

                    bytes[offset]     = (byte)asPCM;
                    bytes[offset + 1] = (byte)(asPCM >> 8);

                    offset += sizeof(ushort);
                }

                samples -= sampleCount;
            }

            return(bytes);
        }
예제 #14
0
        public override bool load()
        {
            float[] readSampleBuffer = new float[AudioBuffer.MAX_BUFFER_SIZE];
            short[] convBuffer       = new short[AudioBuffer.MAX_BUFFER_SIZE];

            myState = SourceState.LOADING;
            using (myReader = new VorbisReader(myFilename))
            {
                myNumChannels = myReader.Channels;
                mySampleRate  = myReader.SampleRate;
                long sampleCount = myReader.TotalSamples * myNumChannels;

                int numBuffers = (int)Math.Ceiling((double)sampleCount / (double)AudioBuffer.MAX_BUFFER_SIZE);

                for (int i = 0; i < numBuffers; i++)
                {
                    AudioBuffer buffer      = new AudioBuffer(myNumChannels == 1 ? AudioBuffer.AudioFormat.MONO16 : AudioBuffer.AudioFormat.STEREO16, mySampleRate);
                    int         samplesRead = myReader.ReadSamples(readSampleBuffer, 0, AudioBuffer.MAX_BUFFER_SIZE);
                    buffer.size = samplesRead;
                    castBuffer(readSampleBuffer, buffer.data, samplesRead);

                    //put it in the audio system
                    buffer.buffer();
                    myBuffers.Add(buffer);
                }

                myState = Source.SourceState.LOADED;
                Debug.print("Loaded audio file: {0}", myFilename);
            }
            return(true);
        }
예제 #15
0
        protected override void FillBuffer(byte[] buffer)
        {
            if (floatBuf == null)
            {
                floatBuf = new float[buffer.Length / 2];
            }

            int read = reader.ReadSamples(floatBuf, 0, floatBuf.Length);

            if ((loopEnd > 0 && reader.DecodedPosition >= loopEnd) || read < floatBuf.Length)
            {
                reader.DecodedPosition = loopStart;
                reader.ReadSamples(floatBuf, read, floatBuf.Length - read);
            }

            Convert(floatBuf, buffer);
        }
예제 #16
0
        protected override void FillBuffer(byte[] buffer)
        {
            if (floatBuf == null)
            {
                floatBuf = new float[buffer.Length / 2];
            }

            int read = reader.ReadSamples(floatBuf, 0, floatBuf.Length);

            if (read < floatBuf.Length)
            {
                Reset();
                reader.ReadSamples(floatBuf, read, floatBuf.Length - read);
            }

            Convert(floatBuf, buffer);
        }
 public int ReadBuffer()
 {
     ReadSamples = _stream.ReadSamples(_stream_buffer, 0, _stream_buffer.Length);
     for (var i = 0; i < ReadSamples; i++)
     {
         var temp = (int)(32767f * _stream_buffer[i]);
         if (temp > short.MaxValue)
         {
             temp = short.MaxValue;
         }
         else if (temp < short.MinValue)
         {
             temp = short.MinValue;
         }
         Buffer[i] = (short)temp;
     }
     return(ReadSamples);
 }
        private static RecyclableBuffer LoadVorbis(
            Stream stream, out ALFormat format, out int frequency, out int channels,
            out int blockAlignment, out int bitsPerSample, out int samplesPerBlock, out int sampleCount)
        {
            RecyclableBuffer?result = null;
            var reader = new VorbisReader(stream, leaveOpen: false);

            try
            {
                bool useFloat   = ALController.Get().SupportsFloat32;
                int  sampleSize = useFloat ? sizeof(float) : sizeof(short);

                channels = reader.Channels;
                if (channels == 1)
                {
                    format = useFloat ? ALFormat.MonoFloat32 : ALFormat.Mono16;
                }
                else if (channels == 2)
                {
                    format = useFloat ? ALFormat.StereoFloat32 : ALFormat.Stereo16;
                }
                else
                {
                    throw new NotSupportedException("Only mono and stereo is supported.");
                }

                sampleCount     = (int)reader.TotalSamples;
                frequency       = reader.SampleRate;
                blockAlignment  = 0;
                samplesPerBlock = 0;
                bitsPerSample   = sampleSize * 8;

                long outputBytes = sampleCount * channels * sampleSize;
                if (outputBytes > int.MaxValue)
                {
                    throw new InvalidDataException("Size of decoded audio data exceeds " + int.MaxValue + " bytes.");
                }

                result = RecyclableMemoryManager.Default.GetBuffer((int)outputBytes, "Vorbis audio data");

                var resultSpan       = result.AsSpan();
                int totalSamplesRead = 0;
                int samplesRead;

                // Both paths allocate around 4096 stack bytes for buffers.
                if (useFloat)
                {
                    Span <float> sampleBuffer      = stackalloc float[1024];
                    Span <byte>  sampleBufferBytes = MemoryMarshal.AsBytes(sampleBuffer);

                    // we can copy directly to output
                    while ((samplesRead = reader.ReadSamples(sampleBuffer)) > 0)
                    {
                        Span <byte> bytes = sampleBufferBytes.Slice(0, samplesRead * sizeof(float));
                        bytes.CopyTo(resultSpan);
                        resultSpan        = resultSpan[bytes.Length..];
예제 #19
0
            public override int ReadNextChunk(float[] target, int offset, int numFrames)
            {
                if (_reader.DecodedPosition + numFrames > _reader.TotalSamples)                   //Double check eof, some ogg files seem to have padding
                {
                    numFrames = ( int )(_reader.TotalSamples - _reader.DecodedPosition);
                }

                int readFrames = _reader.ReadSamples(target, offset, numFrames * Channels) / Channels;                   //readsamples returns samples and not frames...

                return(readFrames);
            }
예제 #20
0
        public static AudioClip LoadVorbis(string filename)
        {
            using (VorbisReader reader = new VorbisReader(filename))
            {
                int sampleCount = (int)reader.TotalSamples * reader.Channels;

                var audioData = new float[sampleCount];

                reader.ReadSamples(audioData, 0, sampleCount);

                return(LoadInternal(filename, audioData, reader.Channels, reader.SampleRate));
            }
        }
예제 #21
0
        public override long GetSamples(int samples, ref byte[] data)
        {
            int bytes = _audioFormat.BytesPerSample * samples;

            Array.Resize(ref data, bytes);

            Array.Resize(ref _readBuf, samples);
            _reader.ReadSamples(_readBuf, 0, samples);

            CastBuffer(_readBuf, data, samples);

            return(samples);
        }
예제 #22
0
        public override int FillStreamBuffer(int samplePos, short[] buffer)
        {
            if (!Stream)
            {
                throw new Exception("Called FillStreamBuffer on a non-streamed sound!");
            }

            if (samplePos >= reader.TotalSamples * reader.Channels * 2)
            {
                return(0);
            }

            samplePos /= reader.Channels * 2;
            reader.DecodedPosition = samplePos;

            float[] floatBuffer = new float[buffer.Length];
            int     readSamples = reader.ReadSamples(floatBuffer, 0, buffer.Length / 2);

            //MuffleBuffer(floatBuffer, reader.Channels);
            CastBuffer(floatBuffer, buffer, readSamples);

            return(readSamples * 2);
        }
예제 #23
0
        //public bool IsLooped { get; set; }

        public static OggSound Load(string oggFile, int bufferCount = DefaultBufferCount)
        {
            OggSound sound = new OggSound();

            sound.file = oggFile;

            using (VorbisReader reader = new VorbisReader(oggFile))
            {
                int bufferSize = (int)reader.TotalSamples * reader.Channels;

                float[] buffer = new float[bufferSize];
                sound.castBuffer = new short[bufferSize];

                int readSamples = reader.ReadSamples(buffer, 0, bufferSize);
                CastBuffer(buffer, sound.castBuffer, readSamples);

                sound.alBufferId = AL.GenBuffer();

                sound.format     = reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
                sound.sampleRate = reader.SampleRate;

                ALHelper.Check();

                //alSourceId = AL.GenSource();
                AL.BufferData(sound.alBufferId, reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, sound.castBuffer,
                              readSamples * sizeof(short), reader.SampleRate);

                ALHelper.Check(oggFile);
            }

            //AL.Source(alSourceId, ALSourcei.Buffer, alBufferId);

            //if (ALHelper.XRam.IsInitialized)
            //{
            //    ALHelper.XRam.SetBufferMode(bufferCount, ref alBufferId, XRamExtension.XRamStorage.Hardware);
            //    ALHelper.Check();
            //}

            //Volume = 1;

            //if (ALHelper.Efx.IsInitialized)
            //{
            //    alFilterId = ALHelper.Efx.GenFilter();
            //    ALHelper.Efx.Filter(alFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass);
            //    ALHelper.Efx.Filter(alFilterId, EfxFilterf.LowpassGain, 1);
            //    LowPassHFGain = 1;
            //}

            return(sound);
        }
예제 #24
0
        private static void QueueBuffer(int source, int buffer, VorbisReader vorbis, ALFormat format, int sampleRate, int targetSamples, long endSample)
        {
            var shortBuffer = new short[targetSamples];

            try
            {
                var samples = Math.Min(targetSamples, (int)(endSample - vorbis.SamplePosition) * sizeof(short));
                if (samples <= 0)
                {
                    return;
                }

                var floatBuffer = new float[samples];

                var thread = default(Thread);
                var t      = Task.Factory.StartNew(() =>
                {
                    thread = Thread.CurrentThread;
                    return(vorbis.ReadSamples(floatBuffer, 0, samples));
                });

                if (!t.Wait((int)(OggBufferSize * 100)) || t.Result <= 0)
                {
                    thread?.Abort();
                    return;
                }

                shortBuffer = new short[samples];

                for (int i = 0; i < samples; i++)
                {
                    var temp = (int)(short.MaxValue * floatBuffer[i]);
                    if (temp > short.MaxValue)
                    {
                        temp = short.MaxValue;
                    }
                    else if (temp < short.MinValue)
                    {
                        temp = short.MinValue;
                    }
                    shortBuffer[i] = (short)temp;
                }
            }
            finally
            {
                AL.BufferData(buffer, format, shortBuffer, shortBuffer.Length * sizeof(short), sampleRate);
                AL.SourceQueueBuffer(source, buffer);
            }
        }
예제 #25
0
        public int Read(byte[] buffer, int length)
        {
            float[] sampleBuffer = new float[length / 2];
            int     count        = reader.ReadSamples(sampleBuffer, 0, sampleBuffer.Length);
            int     targetIndex  = 0;

            for (int i = 0; i < count; i++)
            {
                short sample = FloatToShortRange(sampleBuffer[i]);
                buffer[targetIndex++] = (byte)(sample & 0x00FF);
                buffer[targetIndex++] = (byte)((sample >> 8) & 0x00FF);
            }

            return(count * 2);
        }
예제 #26
0
        public override AudioClip Import(Stream stream, string filePath)
        {
            using var r = new VorbisReader(stream, true);

            long bufferSize = r.TotalSamples * r.Channels;
            var  data       = new float[bufferSize];

            r.ReadSamples(data, 0, (int)bufferSize);

            var clip = new AudioClip();

            clip.SetData(data, r.Channels, sizeof(float), r.SampleRate);

            return(clip);
        }
예제 #27
0
        private async Task PlaySoundImpl(Stream stream)
        {
            using (var vorbis = new VorbisReader(stream, true))
            {
                var channels   = vorbis.Channels;
                var sampleRate = vorbis.SampleRate;
                var samples    = new float[channels * sampleRate];

                var format = new WaveFormat(sampleRate, 32, 2);
                var src    = new SourceVoice(_device, format);

                var bufferQueue = new Queue <AudioBuffer>();
                src.BufferEnd += (IntPtr _) =>
                {
                    bufferQueue.Dequeue().Stream.Dispose();
                };

                src.Start();

                bool doneReading = false;
                do
                {
                    if (src.State.BuffersQueued < 3 && !doneReading)
                    {
                        int bytesRead = vorbis.ReadSamples(samples, 0, samples.Length);
                        if (bytesRead == 0)
                        {
                            doneReading = true;
                            continue;
                        }

                        var dataStream = new DataStream(bytesRead * sizeof(float), true, true);
                        dataStream.WriteRange(samples, 0, bytesRead);
                        dataStream.Position = 0;

                        var buffer = new AudioBuffer(dataStream);
                        buffer.Flags = BufferFlags.EndOfStream;
                        bufferQueue.Enqueue(buffer);
                        src.SubmitSourceBuffer(buffer, null);
                    }

                    await Task.Delay(100).ConfigureAwait(false);
                } while (src.State.BuffersQueued > 0);

                src.DestroyVoice();
                src.Dispose();
            }
        }
예제 #28
0
        public OggSound(SoundManager owner, string filename, bool stream) : base(owner, filename, stream, true)
        {
            if (!ToolBox.IsProperFilenameCase(filename))
            {
                DebugConsole.ThrowError("Sound file \"" + filename + "\" has incorrect case!");
            }

            reader = new VorbisReader(filename);

            ALFormat   = reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
            SampleRate = reader.SampleRate;

            if (!stream)
            {
                int bufferSize = (int)reader.TotalSamples * reader.Channels;

                float[] floatBuffer = new float[bufferSize];
                short[] shortBuffer = new short[bufferSize];

                int readSamples = reader.ReadSamples(floatBuffer, 0, bufferSize);

                CastBuffer(floatBuffer, shortBuffer, readSamples);

                AL.BufferData((int)ALBuffer, ALFormat, shortBuffer,
                              readSamples * sizeof(short), SampleRate);

                ALError alError = AL.GetError();
                if (alError != ALError.NoError)
                {
                    throw new Exception("Failed to set buffer data for non-streamed audio! " + AL.GetErrorString(alError));
                }

                MuffleBuffer(floatBuffer, SampleRate, reader.Channels);

                CastBuffer(floatBuffer, shortBuffer, readSamples);

                AL.BufferData((int)ALMuffledBuffer, ALFormat, shortBuffer,
                              readSamples * sizeof(short), SampleRate);

                alError = AL.GetError();
                if (alError != ALError.NoError)
                {
                    throw new Exception("Failed to set buffer data for non-streamed audio! " + AL.GetErrorString(alError));
                }

                reader.Dispose();
            }
        }
예제 #29
0
            public override int Read(byte[] buffer, int offset, int count)
            {
                if (offset != 0)
                {
                    throw new NotImplementedException();
                }
                int sampleCount = count / 2;
                int readSamples;

                lock (floats)
                {
                    readSamples = reader.ReadSamples(floats, 0, sampleCount);
                    CastBuffer(floats, buffer, readSamples);
                }
                return(readSamples * 2);
            }
예제 #30
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            int samples = count / reader.Channels / 4;

            if (floats.Length < samples)
            {
                floats = new float[samples * 2];
            }
            int    read = reader.ReadSamples(floats, 0, samples) * reader.Channels;
            IntPtr pointer;

            using (buffer.Pin(out pointer, offset, read * 4))
                Marshal.Copy(floats, 0, pointer, read);

            return(read);
        }