Beispiel #1
0
        /// <summary> Initializes the audio system with given settings </summary>
        /// <param name="sampleRate"> Sample rate (default is 44.1kHz) </param>
        /// <param name="channels"> Number of channels (default is 1) </param>
        /// <param name="blocks"> Number of blocks in buffer (default is 8) </param>
        /// <param name="blockSamples"> Number of samples per block (default is 512) </param>
        public void CreateAudio(uint sampleRate = 44100, uint channels = 1, uint blocks = 8, uint blockSamples = 512)
        {
            Active            = false;
            this.sampleRate   = sampleRate;
            this.channels     = channels;
            blockCount        = blocks;
            this.blockSamples = blockSamples;
            blockFree         = blockCount;
            blockCurrent      = 0;
            blockMemory       = null;
            waveHeaders       = null;

            WaveFormatEx waveFormat = new WaveFormatEx {
                FormatTag     = Windows.WaveFormatPcm,
                SamplesPerSec = (int)sampleRate,
                BitsPerSample = sizeof(short) * 8,
                Channels      = (short)channels,
            };

            waveFormat.BlockAlign     = (short)((waveFormat.BitsPerSample / 8) * waveFormat.Channels);
            waveFormat.AvgBytesPerSec = waveFormat.SamplesPerSec * waveFormat.BlockAlign;
            waveFormat.Size           = (short)Marshal.SizeOf(waveFormat);

            waveProc = WaveOutProc;

            if (Windows.WaveOutOpen(out device, Windows.WaveMapper, waveFormat, waveProc, 0, Windows.CallbackFunction) != 0)
            {
                DestroyAudio();
            }

            blockMemory = new short[blockCount * blockSamples];
            waveHeaders = new WaveHdr[blockCount];

            unsafe
            {
                fixed(short *mem = blockMemory)
                {
                    for (uint n = 0; n < blockCount; n++)
                    {
                        waveHeaders[n].BufferLength = (int)(blockSamples * sizeof(short));
                        waveHeaders[n].Data         = (IntPtr)(mem + (n * blockSamples));
                    }
                }
            }

            Active      = true;
            audioThread = new Thread(AudioThread);
            audioThread.Start();
        }
Beispiel #2
0
        /// <summary> Loads a wave file </summary>
        /// <param name="reader"> Stream reader. </param>
        /// <param name="isFromMp3"> Flag if converted from mp3 </param>
        /// <returns> True if success, false if failed </returns>
        private bool LoadFromWav(BinaryReader reader, bool isFromMp3 = false)
        {
            const string Riff = "RIFF";
            const string Wave = "WAVE";
            const string Fmt  = "fmt ";

            char[] dump;

            dump = reader.ReadChars(4);             // RIFF"
            if (string.Compare(string.Concat(dump), Riff) != 0)
            {
                return(false);
            }

            dump = reader.ReadChars(4);             // Ignore

            dump = reader.ReadChars(4);             // "WAVE"
            if (string.Compare(string.Concat(dump), Wave) != 0)
            {
                return(false);
            }

            dump = reader.ReadChars(4);             // "fmt "
            if (string.Compare(string.Concat(dump), Fmt) != 0)
            {
                return(false);
            }

            dump = reader.ReadChars(4);             // Ignore

            WavHeader = new WaveFormatEx()
            {
                FormatTag      = reader.ReadInt16(),
                Channels       = reader.ReadInt16(),
                SamplesPerSec  = reader.ReadInt32(),
                AvgBytesPerSec = reader.ReadInt32(),
                BlockAlign     = reader.ReadInt16(),
                BitsPerSample  = reader.ReadInt16()
            };
            WavHeader.Size = (short)Marshal.SizeOf(WavHeader);

            if (WavHeader.SamplesPerSec != 44100)
            {
                return(false);
            }

            const string Data = "data";

            // Offset 2 characters to reach data.
            // There are 2 extra chars while converting from mp3 for some reason ???
            if (isFromMp3)
            {
                reader.ReadChars(2);
            }


            dump = reader.ReadChars(4);             // Chunk header
            long chunkSize = reader.ReadUInt32();

            while (string.Compare(string.Concat(dump), Data) != 0)
            {
                reader.BaseStream.Seek(chunkSize, SeekOrigin.Current);
                dump      = reader.ReadChars(4);
                chunkSize = reader.ReadUInt32();
            }

            SampleCount = chunkSize / (WavHeader.Channels * (WavHeader.BitsPerSample >> 3));
            Channels    = WavHeader.Channels;

            Samples = new short[SampleCount * Channels];

            const float Mult8Bit  = (float)short.MaxValue / byte.MaxValue;
            const float Mult24Bit = (float)short.MaxValue / (1 << 24);
            const float Mult32Bit = (float)short.MaxValue / int.MaxValue;

            for (long l = 0; l < Samples.Length; l++)
            {
                // Divide by 8 to convert to bits to bytes
                switch (WavHeader.BitsPerSample / 8)
                {
                case 1:                         // 8-bits
                    byte b = reader.ReadByte();
                    Samples[l] = (short)(b * Mult8Bit);
                    break;

                case 2:                         // 16-bits
                    short s = reader.ReadInt16();
                    Samples[l] = s;
                    break;

                case 3:                         // 24-bits
                    byte[] bs = reader.ReadBytes(3);
                    int    n  = bs[0] | (bs[1] << 8) | (bs[2] << 16);
                    Samples[l] = (short)(n * Mult24Bit);
                    break;

                case 4:                         // 32-bits
                    int i = reader.ReadInt32();
                    Samples[l] = (byte)(i * Mult32Bit);
                    break;
                }
            }

            return(true);
        }