Пример #1
0
        public void PlayStreaming(Stream stream)
        {
            VorbisCodec codec = new VorbisCodec();
            AudioFormat fmt   = codec.ReadHeader(stream);

            SetFormat(fmt);
            IEnumerator <AudioChunk> chunks = codec.StreamData(stream).GetEnumerator();
            AudioChunk tmp = new AudioChunk();

            // largest possible vorbis frame decodes to blocksize1 samples
            // so we may end up decoding slightly over a second of audio
            int chunkSize = (fmt.SampleRate + 8192) * fmt.Channels * sizeof(short);

            byte[][] data = new byte[NumBuffers][];
            for (int i = 0; i < NumBuffers; i++)
            {
                data[i] = new byte[chunkSize];
            }

            bool reachedEnd = false;

            for (int i = 0; i < NumBuffers && !reachedEnd; i++)
            {
                tmp.Data   = data[i];
                reachedEnd = BufferBlock(tmp, fmt, chunks);
                BufferData(i, tmp);
            }
            Play();

            for (; !reachedEnd;)
            {
                int next = -1;
                for (int i = 0; i < NumBuffers; i++)
                {
                    if (IsCompleted(i))
                    {
                        next = i; break;
                    }
                }

                if (next == -1)
                {
                    Thread.Sleep(10); continue;
                }
                if (pendingStop)
                {
                    break;
                }

                tmp.Data   = data[next];
                reachedEnd = BufferBlock(tmp, fmt, chunks);
                BufferData(next, tmp);
            }

            while (!IsFinished())
            {
                Thread.Sleep(10);
            }
        }
Пример #2
0
        public override void BufferData(int index, AudioChunk chunk)
        {
            fixed(byte *data = chunk.Data)
            {
                uint buffer = bufferIDs[index];

                completed[index] = false;

                AL.alBufferData(buffer, dataFormat, (IntPtr)data,
                                chunk.Length, Format.SampleRate);
                CheckError("BufferData");

                AL.alSourceQueueBuffers(source, 1, &buffer);
                CheckError("QueueBuffers");
            }
        }
Пример #3
0
        void ApplyVolume(IntPtr handle, AudioChunk chunk)
        {
            if (volumePercent == 100)
            {
                return;
            }

            if (Format.BitsPerSample == 16)
            {
                VolumeMixer.Mix16((short *)handle, chunk.Length / sizeof(short), volumePercent);
            }
            else if (Format.BitsPerSample == 8)
            {
                VolumeMixer.Mix8((byte *)handle, chunk.Length, volumePercent);
            }
        }
Пример #4
0
        bool BufferBlock(AudioChunk tmp, AudioFormat fmt, IEnumerator <AudioChunk> chunks)
        {
            // decode up to around a second
            int secondSize = fmt.SampleRate * fmt.Channels * sizeof(short);

            tmp.Length = 0;

            while (tmp.Length < secondSize)
            {
                if (!chunks.MoveNext())
                {
                    return(true);
                }
                AudioChunk src = chunks.Current;

                Buffer.BlockCopy(src.Data, 0, tmp.Data, tmp.Length, src.Length);
                tmp.Length += src.Length;
            }
            return(false);
        }
Пример #5
0
        bool BufferBlock(int i, AudioChunk tmp, int size, IEnumerator <AudioChunk> chunks)
        {
            tmp.Length = 0;
            bool end = false;

            while (tmp.Length < size)
            {
                if (!chunks.MoveNext())
                {
                    end = true; break;
                }
                AudioChunk src = chunks.Current;

                Buffer.BlockCopy(src.Data, 0, tmp.Data, tmp.Length, src.Length);
                tmp.Length += src.Length;
            }

            BufferData(i, tmp);
            return(end);
        }
Пример #6
0
        public override void BufferData(int index, AudioChunk chunk)
        {
            if (chunk.Length > dataSizes[index])
            {
                IntPtr ptr = dataHandles[index];
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptr);
                }
                dataHandles[index] = Marshal.AllocHGlobal(chunk.Length);
            }

            IntPtr handle = dataHandles[index];

            fixed(byte *data = chunk.Data)
            {
                MemUtils.memcpy((IntPtr)data, handle, chunk.Length);
                ApplyVolume(handle, chunk);
            }

            WaveHeader header = default(WaveHeader);

            header.DataBuffer   = handle;
            header.BufferLength = chunk.Length;
            header.Loops        = 1;

            WaveHeader *hdr = (WaveHeader *)headers + index;

            *hdr = header;

            uint result = WinMM.waveOutPrepareHeader(devHandle, (IntPtr)hdr, waveHeaderSize);

            CheckError(result, "PrepareHeader");
            result = WinMM.waveOutWrite(devHandle, (IntPtr)hdr, waveHeaderSize);
            CheckError(result, "Write");
        }
Пример #7
0
 public void PlayData(int index, AudioChunk chunk)
 {
     BufferData(index, chunk);
     Play();
 }
Пример #8
0
 public abstract void BufferData(int index, AudioChunk chunk);
Пример #9
0
 public VorbisCodec()
 {
     chunk = new AudioChunk();
 }