Example #1
0
        unsafe void decode_metadata()
        {
            byte x;
            int  i, id;

            //bool first = true;
            byte[] FLAC__STREAM_SYNC_STRING = new byte[] { (byte)'f', (byte)'L', (byte)'a', (byte)'C' };
            byte[] ID3V2_TAG_ = new byte[] { (byte)'I', (byte)'D', (byte)'3' };

            for (i = id = 0; i < 4;)
            {
                if (_IO.Read(_framesBuffer, 0, 1) == 0)
                {
                    throw new Exception("FLAC stream not found");
                }
                x = _framesBuffer[0];
                if (x == FLAC__STREAM_SYNC_STRING[i])
                {
                    //first = true;
                    i++;
                    id = 0;
                    continue;
                }
                if (id < 3 && x == ID3V2_TAG_[id])
                {
                    id++;
                    i = 0;
                    if (id == 3)
                    {
                        if (!skip_bytes(3))
                        {
                            throw new Exception("FLAC stream not found");
                        }
                        int skip = 0;
                        for (int j = 0; j < 4; j++)
                        {
                            if (0 == _IO.Read(_framesBuffer, 0, 1))
                            {
                                throw new Exception("FLAC stream not found");
                            }
                            skip <<= 7;
                            skip  |= ((int)_framesBuffer[0] & 0x7f);
                        }
                        if (!skip_bytes(skip))
                        {
                            throw new Exception("FLAC stream not found");
                        }
                    }
                    continue;
                }
                id = 0;
                if (x == 0xff)                 /* MAGIC NUMBER for the first 8 frame sync bits */
                {
                    do
                    {
                        if (_IO.Read(_framesBuffer, 0, 1) == 0)
                        {
                            throw new Exception("FLAC stream not found");
                        }
                        x = _framesBuffer[0];
                    } while (x == 0xff);
                    if (x >> 2 == 0x3e)                     /* MAGIC NUMBER for the last 6 sync bits */
                    {
                        //_IO.Position -= 2;
                        // state = frame
                        throw new Exception("headerless file unsupported");
                    }
                }
                throw new Exception("FLAC stream not found");
            }

            do
            {
                fill_frames_buffer();
                fixed(byte *buf = _framesBuffer)
                {
                    BitReader    bitreader = new BitReader(buf, _framesBufferOffset, _framesBufferLength - _framesBufferOffset);
                    bool         is_last   = bitreader.readbit() != 0;
                    MetadataType type      = (MetadataType)bitreader.readbits(7);
                    int          len       = (int)bitreader.readbits(24);

                    if (type == MetadataType.StreamInfo)
                    {
                        const int FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN  = 16;                 /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN  = 16;                 /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN  = 24;                 /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN  = 24;                 /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN     = 20;                 /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN        = 3;                  /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5;                  /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN   = 36;                 /* bits */
                        const int FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN          = 128;                /* bits */

                        min_block_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN);
                        max_block_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN);
                        min_frame_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN);
                        max_frame_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN);
                        int sample_rate     = (int)bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN);
                        int channels        = 1 + (int)bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN);
                        int bits_per_sample = 1 + (int)bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN);
                        pcm          = new AudioPCMConfig(bits_per_sample, channels, sample_rate);
                        _sampleCount = (long)bitreader.readbits64(FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN);
                        bitreader.skipbits(FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN);
                    }
                    else if (type == MetadataType.Seektable)
                    {
                        int num_entries = len / 18;
                        seek_table = new SeekPoint[num_entries];
                        for (int e = 0; e < num_entries; e++)
                        {
                            seek_table[e].number    = bitreader.read_long();
                            seek_table[e].offset    = bitreader.read_long();
                            seek_table[e].framesize = (int)bitreader.read_ushort();
                        }
                    }
                    if (_framesBufferLength < 4 + len)
                    {
                        _IO.Position       += 4 + len - _framesBufferLength;
                        _framesBufferLength = 0;
                    }
                    else
                    {
                        _framesBufferLength -= 4 + len;
                        _framesBufferOffset += 4 + len;
                    }
                    if (is_last)
                    {
                        break;
                    }
                }
            } while (true);
            first_frame_offset = _IO.Position - _framesBufferLength;
        }
Example #2
0
        private void ParseHeaders()
        {
            const long maxFileSize = 0x7FFFFFFEL;
            const uint fccRIFF     = 0x46464952;
            const uint fccWAVE     = 0x45564157;
            const uint fccFormat   = 0x20746D66;
            const uint fccData     = 0x61746164;

            uint lenRIFF;
            bool foundFormat, foundData;

            if (_br.ReadUInt32() != fccRIFF)
            {
                throw new Exception("Not a valid RIFF file.");
            }

            lenRIFF = _br.ReadUInt32();

            if (_br.ReadUInt32() != fccWAVE)
            {
                throw new Exception("Not a valid WAVE file.");
            }

            _largeFile  = false;
            foundFormat = false;
            foundData   = false;
            long pos = 12;

            do
            {
                uint ckID, ckSize, ckSizePadded;
                long ckEnd;

                ckID         = _br.ReadUInt32();
                ckSize       = _br.ReadUInt32();
                ckSizePadded = (ckSize + 1U) & ~1U;
                pos         += 8;
                ckEnd        = pos + (long)ckSizePadded;

                if (ckID == fccFormat)
                {
                    foundFormat = true;

                    uint fmtTag        = _br.ReadUInt16();
                    int  _channelCount = _br.ReadInt16();
                    int  _sampleRate   = _br.ReadInt32();
                    _br.ReadInt32(); // bytes per second
                    int _blockAlign    = _br.ReadInt16();
                    int _bitsPerSample = _br.ReadInt16();
                    int _channelMask   = 0;
                    pos += 16;

                    if (fmtTag == 0xFFFEU && ckSize >= 34) // WAVE_FORMAT_EXTENSIBLE
                    {
                        _br.ReadInt16();                   // CbSize
                        _br.ReadInt16();                   // ValidBitsPerSample
                        _channelMask = _br.ReadInt32();
                        fmtTag       = _br.ReadUInt16();
                        pos         += 10;
                    }

                    if (fmtTag != 1) // WAVE_FORMAT_PCM
                    {
                        throw new Exception("WAVE format tag not WAVE_FORMAT_PCM.");
                    }

                    pcm = new AudioPCMConfig(_bitsPerSample, _channelCount, _sampleRate, (AudioPCMConfig.SpeakerConfig)_channelMask);
                    if (pcm.BlockAlign != _blockAlign)
                    {
                        throw new Exception("WAVE has strange BlockAlign");
                    }
                }
                else if (ckID == fccData)
                {
                    foundData = true;

                    _dataOffset = pos;
                    if (!_IO.CanSeek || _IO.Length <= maxFileSize)
                    {
                        if (ckSize == 0 || ckSize >= 0x7fffffff)
                        {
                            _dataLen = -1;
                        }
                        else
                        {
                            _dataLen = (long)ckSize;
                        }
                    }
                    else
                    {
                        _largeFile = true;
                        _dataLen   = _IO.Length - pos;
                    }
                }

                if ((foundFormat & foundData) || _largeFile)
                {
                    break;
                }
                if (_IO.CanSeek)
                {
                    _IO.Seek(ckEnd, SeekOrigin.Begin);
                }
                else
                {
                    _br.ReadBytes((int)(ckEnd - pos));
                }
                pos = ckEnd;
            } while (true);

            if ((foundFormat & foundData) == false || pcm == null)
            {
                throw new Exception("Format or data chunk not found.");
            }
            if (pcm.ChannelCount <= 0)
            {
                throw new Exception("Channel count is invalid.");
            }
            if (pcm.SampleRate <= 0)
            {
                throw new Exception("Sample rate is invalid.");
            }
            if ((pcm.BitsPerSample <= 0) || (pcm.BitsPerSample > 32))
            {
                throw new Exception("Bits per sample is invalid.");
            }
            if (pos != _dataOffset)
            {
                Position = 0;
            }
        }
Example #3
0
 public AudioBuffer(IAudioSource source, int _size)
 {
     pcm  = source.PCM;
     size = _size;
 }
Example #4
0
 public AudioBuffer(AudioPCMConfig _pcm, byte[] _bytes, int _length)
 {
     pcm = _pcm;
     Prepare(_bytes, _length);
 }
Example #5
0
 public AudioBuffer(AudioPCMConfig _pcm, int[,] _samples, int _length)
 {
     pcm = _pcm;
     // assert _samples.GetLength(1) == pcm.ChannelCount
     Prepare(_samples, _length);
 }
Example #6
0
 public AudioBuffer(AudioPCMConfig _pcm, int _size)
 {
     pcm    = _pcm;
     size   = _size;
     length = 0;
 }