Example #1
0
        /// <summary>
        /// http://tech.ebu.ch/docs/tech/tech3306-2009.pdf
        /// </summary>
        private void ReadDs64Chunk(BinaryReader reader)
        {
            int ds64ChunkId = WaveInterop.mmioStringToFOURCC("ds64", 0);
            int chunkId     = reader.ReadInt32();

            if (chunkId != ds64ChunkId)
            {
                throw new FormatException("Invalid RF64 WAV file - No ds64 chunk found");
            }
            int chunkSize = reader.ReadInt32();

            riffSize        = reader.ReadInt64();
            dataChunkLength = reader.ReadInt64();
            // ReSharper disable once UnusedVariable
            long sampleCount = reader.ReadInt64(); // replaces the value in the fact chunk

            reader.ReadBytes(chunkSize - 24);      // get to the end of this chunk (should parse extra stuff later)
        }
Example #2
0
        private GCHandle hThis;   // for the user callback

        /// <summary>
        /// creates a new wavebuffer
        /// </summary>
        /// <param name="waveInHandle">WaveIn device to write to</param>
        /// <param name="bufferSize">Buffer size in bytes</param>
        public WaveInBuffer(IntPtr waveInHandle, Int32 bufferSize)
        {
            this.bufferSize   = bufferSize;
            buffer            = new byte[bufferSize];
            hBuffer           = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            this.waveInHandle = waveInHandle;

            header              = new WaveHeader();
            hHeader             = GCHandle.Alloc(header);
            header.dataBuffer   = hBuffer.AddrOfPinnedObject();
            header.bufferLength = bufferSize;
            header.loops        = 1;
            hThis           = GCHandle.Alloc(this);
            header.userData = (IntPtr)hThis;

            MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader");
            //MmException.Try(WaveInterop.waveInAddBuffer(waveInHandle, header, Marshal.SizeOf(header)), "waveInAddBuffer");
        }
Example #3
0
 /// <summary>
 /// Stop recording
 /// </summary>
 public void StopRecording()
 {
     if (recording)
     {
         recording = false;
         MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
         // report the last buffers, sometimes more than one, so taking care to report them in the right order
         for (int n = 0; n < buffers.Length; n++)
         {
             int index  = (n + lastReturnedBufferIndex + 1) % buffers.Length;
             var buffer = buffers[index];
             if (buffer.Done)
             {
                 RaiseDataAvailable(buffer);
             }
         }
         RaiseRecordingStopped(null);
     }
     //MmException.Try(WaveInterop.waveInReset(waveInHandle), "waveInReset");
     // Don't actually close yet so we get the last buffer
 }
Example #4
0
        public void ReadWaveHeader(Stream stream)
        {
            dataChunkPosition = -1;
            waveFormat        = null;
            riffChunks        = new List <RiffChunk>();
            dataChunkLength   = 0;

            BinaryReader br = new BinaryReader(stream);

            ReadRiffHeader(br);
            riffSize = br.ReadUInt32(); // read the file size (minus 8 bytes)

            if (br.ReadInt32() != WaveInterop.mmioStringToFOURCC("WAVE", 0))
            {
                throw new FormatException("Not a WAVE file - no WAVE header");
            }

            if (isRf64)
            {
                ReadDs64Chunk(br);
            }

            int dataChunkID   = WaveInterop.mmioStringToFOURCC("data", 0);
            int formatChunkId = WaveInterop.mmioStringToFOURCC("fmt ", 0);

            // sometimes a file has more data than is specified after the RIFF header
            long stopPosition = Math.Min(riffSize + 8, stream.Length);

            // this -8 is so we can be sure that there are at least 8 bytes for a chunk id and length
            while (stream.Position <= stopPosition - 8)
            {
                Int32 chunkIdentifier = br.ReadInt32();
                Int32 chunkLength     = br.ReadInt32();
                if (chunkIdentifier == dataChunkID)
                {
                    dataChunkPosition = stream.Position;
                    if (!isRf64) // we already know the dataChunkLength if this is an RF64 file
                    {
                        dataChunkLength = chunkLength;
                    }
                    stream.Position += chunkLength;
                }
                else if (chunkIdentifier == formatChunkId)
                {
                    waveFormat = WaveFormat.FromFormatChunk(br, chunkLength);
                }
                else
                {
                    // check for invalid chunk length
                    if (chunkLength < 0 || chunkLength > stream.Length - stream.Position)
                    {
                        if (strictMode)
                        {
                            Debug.Assert(false, String.Format("Invalid chunk length {0}, pos: {1}. length: {2}",
                                                              chunkLength, stream.Position, stream.Length));
                        }
                        // an exception will be thrown further down if we haven't got a format and data chunk yet,
                        // otherwise we will tolerate this file despite it having corrupt data at the end
                        break;
                    }
                    if (storeAllChunks)
                    {
                        riffChunks.Add(GetRiffChunk(stream, chunkIdentifier, chunkLength));
                    }
                    stream.Position += chunkLength;
                }
            }

            if (waveFormat == null)
            {
                throw new FormatException("Invalid WAV file - No fmt chunk found");
            }
            if (dataChunkPosition == -1)
            {
                throw new FormatException("Invalid WAV file - No data chunk found");
            }
        }