Ejemplo n.º 1
0
        /// <summary>
        /// Helper function to retrieve a WaveFormat structure from a pointer
        /// </summary>
        /// <param name="pointer">WaveFormat structure</param>
        /// <returns></returns>
        public static WaveFormatProvider MarshalFromPtr(IntPtr pointer)
        {
            WaveFormatProvider waveFormat = (WaveFormatProvider)Marshal.PtrToStructure(pointer, typeof(WaveFormatProvider));

            switch (waveFormat.Encoding)
            {
            case WaveFormatEncoding.Pcm:
                // can't rely on extra size even being there for PCM so blank it to avoid reading
                // corrupt data
                waveFormat.extraSize = 0;
                break;

            case WaveFormatEncoding.Extensible:
                waveFormat = (WaveFormatExtensible)Marshal.PtrToStructure(pointer, typeof(WaveFormatExtensible));
                break;

            case WaveFormatEncoding.Adpcm:
                waveFormat = (AdpcmWaveFormat)Marshal.PtrToStructure(pointer, typeof(AdpcmWaveFormat));
                break;

            case WaveFormatEncoding.Gsm610:
                waveFormat = (Gsm610WaveFormat)Marshal.PtrToStructure(pointer, typeof(Gsm610WaveFormat));
                break;

            default:
                if (waveFormat.ExtraSize > 0)
                {
                    waveFormat = (WaveFormatExtraData)Marshal.PtrToStructure(pointer, typeof(WaveFormatExtraData));
                }
                break;
            }
            return(waveFormat);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Helper function to marshal WaveFormat to an IntPtr
        /// </summary>
        /// <param name="format">WaveFormat</param>
        /// <returns>IntPtr to WaveFormat structure (needs to be freed by callee)</returns>
        public static IntPtr MarshalToPtr(WaveFormatProvider format)
        {
            int    formatSize    = Marshal.SizeOf(format);
            IntPtr formatPointer = Marshal.AllocHGlobal(formatSize);

            Marshal.StructureToPtr(format, formatPointer, false);
            return(formatPointer);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WasapiCapture"/> class.
        /// </summary>
        /// <param name="captureDevice">The capture device.</param>
        /// <param name="useEventSync">true if sync is done with event. false use sleep.</param>
        public WasapiCapture(MMDevice captureDevice, bool useEventSync)
        {
            syncContext      = SynchronizationContext.Current;
            audioClient      = captureDevice.AudioClient;
            ShareMode        = AudioClientShareMode.Shared;
            isUsingEventSync = useEventSync;

            waveFormat = audioClient.MixFormat;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates a Wave File Reader based on an input stream
        /// </summary>
        /// <param name="inputStream">The input stream containing a WAV file including header</param>
        public WaveFileReader(Stream inputStream)
        {
            this.waveStream = inputStream;
            var chunkReader = new WaveFileChunkReader();

            chunkReader.ReadWaveHeader(inputStream);
            this.waveFormat      = chunkReader.WaveFormat;
            this.dataPosition    = chunkReader.DataChunkPosition;
            this.dataChunkLength = chunkReader.DataChunkLength;
            this.chunks          = chunkReader.RiffChunks;
            Position             = 0;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates a WaveFormat with custom members
        /// </summary>
        /// <param name="tag">The encoding</param>
        /// <param name="sampleRate">Sample Rate</param>
        /// <param name="channels">Number of channels</param>
        /// <param name="averageBytesPerSecond">Average Bytes Per Second</param>
        /// <param name="blockAlign">Block Align</param>
        /// <param name="bitsPerSample">Bits Per Sample</param>
        /// <returns></returns>
        public static WaveFormatProvider CreateCustomFormat(WaveFormatEncoding tag, int sampleRate, int channels, int averageBytesPerSecond, int blockAlign, int bitsPerSample)
        {
            WaveFormatProvider waveFormat = new WaveFormatProvider();

            waveFormat.waveFormatTag         = tag;
            waveFormat.channels              = (short)channels;
            waveFormat.sampleRate            = sampleRate;
            waveFormat.averageBytesPerSecond = averageBytesPerSecond;
            waveFormat.blockAlign            = (short)blockAlign;
            waveFormat.bitsPerSample         = (short)bitsPerSample;
            waveFormat.extraSize             = 0;
            return(waveFormat);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates a new 32 bit IEEE floating point wave format
        /// </summary>
        /// <param name="sampleRate">sample rate</param>
        /// <param name="channels">number of channels</param>
        public static WaveFormatProvider CreateIeeeFloatWaveFormat(int sampleRate, int channels)
        {
            WaveFormatProvider wf = new WaveFormatProvider();

            wf.waveFormatTag         = WaveFormatEncoding.IeeeFloat;
            wf.channels              = (short)channels;
            wf.bitsPerSample         = 32;
            wf.sampleRate            = sampleRate;
            wf.blockAlign            = (short)(4 * channels);
            wf.averageBytesPerSecond = sampleRate * wf.blockAlign;
            wf.extraSize             = 0;
            return(wf);
        }
Ejemplo n.º 7
0
        internal MmResult WaveOutOpen(out IntPtr waveOutHandle, int deviceNumber, WaveFormatProvider waveFormat, WaveInterop.WaveCallback callback)
        {
            MmResult result;

            if (Strategy == WaveCallbackStrategy.FunctionCallback)
            {
                result = WaveInterop.waveOutOpen(out waveOutHandle, (IntPtr)deviceNumber, waveFormat, callback, IntPtr.Zero, WaveInOutOpenFlags.CallbackFunction);
            }
            else
            {
                result = WaveInterop.waveOutOpenWindow(out waveOutHandle, (IntPtr)deviceNumber, waveFormat, this.Handle, IntPtr.Zero, WaveInOutOpenFlags.CallbackWindow);
            }
            return(result);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Compares with another WaveFormat object
        /// </summary>
        /// <param name="obj">Object to compare to</param>
        /// <returns>True if the objects are the same</returns>
        public override bool Equals(object obj)
        {
            WaveFormatProvider other = obj as WaveFormatProvider;

            if (other != null)
            {
                return(waveFormatTag == other.waveFormatTag &&
                       channels == other.channels &&
                       sampleRate == other.sampleRate &&
                       averageBytesPerSecond == other.averageBytesPerSecond &&
                       blockAlign == other.blockAlign &&
                       bitsPerSample == other.bitsPerSample);
            }
            return(false);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// WaveFileWriter that actually writes to a stream
        /// </summary>
        /// <param name="outStream">Stream to be written to</param>
        /// <param name="format">Wave format to use</param>
        public WaveFileWriter(System.IO.Stream outStream, WaveFormatProvider format)
        {
            this.outStream = outStream;
            this.format    = format;
            this.writer    = new BinaryWriter(outStream, System.Text.Encoding.UTF8);
            this.writer.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"));
            this.writer.Write((int)0); // placeholder
            this.writer.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"));

            this.writer.Write(System.Text.Encoding.UTF8.GetBytes("fmt "));
            format.Serialize(this.writer);

            CreateFactChunk();
            WriteDataChunkHeader();
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Prepares a Wave input device for recording
 /// </summary>
 public WaveIn(WaveCallbackInfo callbackInfo)
 {
     syncContext = SynchronizationContext.Current;
     if ((callbackInfo.Strategy == WaveCallbackStrategy.NewWindow || callbackInfo.Strategy == WaveCallbackStrategy.ExistingWindow) &&
         syncContext == null)
     {
         throw new InvalidOperationException("Use WaveInEvent to record on a background thread");
     }
     DeviceNumber       = 0;
     WaveFormat         = new WaveFormatProvider(8000, 16, 1);
     BufferMilliseconds = 100;
     NumberOfBuffers    = 3;
     callback           = Callback;
     this.callbackInfo  = callbackInfo;
     callbackInfo.Connect(callback);
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Creates a new MediaFoundationReader based on the supplied file
        /// </summary>
        /// <param name="inputStream">The input stream containing a WAV.</param>
        /// <param name="settings">Advanced settings</param>
        public MediaFoundationReader(System.IO.Stream inputStream, MediaFoundationReaderSettings settings)
        {
            MediaFoundationApi.Startup();
            this.settings = settings;
            _inputStream  = inputStream;
            var reader = CreateReader(settings);

            waveFormat = GetCurrentWaveFormat(reader);

            reader.SetStreamSelection(MediaFoundationInterop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, true);
            length = GetLength(reader);

            if (settings.SingleReaderObject)
            {
                pReader = reader;
            }
        }
Ejemplo n.º 12
0
        private WaveFormatProvider GetCurrentWaveFormat(IMFSourceReader reader)
        {
            IMFMediaType uncompressedMediaType;

            reader.GetCurrentMediaType(MediaFoundationInterop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, out uncompressedMediaType);

            // Two ways to query it, first is to ask for properties (second is to convert into WaveFormatEx using MFCreateWaveFormatExFromMFMediaType)
            var  outputMediaType = new MediaType(uncompressedMediaType);
            Guid actualMajorType = outputMediaType.MajorType;

            Guid audioSubType = outputMediaType.SubType;
            int  channels     = outputMediaType.ChannelCount;
            int  bits         = outputMediaType.BitsPerSample;
            int  sampleRate   = outputMediaType.SampleRate;

            return(audioSubType == AudioSubtypes.MFAudioFormat_PCM
                ? new WaveFormatProvider(sampleRate, bits, channels)
                : WaveFormatProvider.CreateIeeeFloatWaveFormat(sampleRate, channels));
        }
        /// <summary>
        /// Creates a stream that can convert to PCM
        /// </summary>
        /// <param name="sourceStream">The source stream</param>
        /// <returns>A PCM stream</returns>
        public static WaveStream CreatePcmStream(WaveStream sourceStream)
        {
            if (sourceStream.WaveFormat.Encoding == WaveFormatEncoding.Pcm)
            {
                return(sourceStream);
            }
            WaveFormatProvider pcmFormat = AcmStream.SuggestPcmFormat(sourceStream.WaveFormat);

            if (pcmFormat.SampleRate < 8000)
            {
                if (sourceStream.WaveFormat.Encoding == WaveFormatEncoding.G723)
                {
                    pcmFormat = new WaveFormatProvider(8000, 16, 1);
                }
                else
                {
                    throw new InvalidOperationException("Invalid suggested output format, please explicitly provide a target format");
                }
            }
            return(new WaveFormatConversionStream(pcmFormat, sourceStream));
        }
        /// <summary>
        /// Create a new WaveFormat conversion stream
        /// </summary>
        /// <param name="targetFormat">Desired output format</param>
        /// <param name="sourceStream">Source stream</param>
        public WaveFormatConversionStream(WaveFormatProvider targetFormat, WaveStream sourceStream)
        {
            this.sourceStream = sourceStream;
            this.targetFormat = targetFormat;

            conversionStream = new AcmStream(sourceStream.WaveFormat, targetFormat);

            /*try
             * {
             *  // work out how many bytes the entire input stream will convert to
             *  length = conversionStream.SourceToDest((int)sourceStream.Length);
             * }
             * catch
             * {
             *  Dispose();
             *  throw;
             * }*/
            length = EstimateSourceToDest((int)sourceStream.Length);

            position = 0;
            preferredSourceReadSize  = System.Math.Min(sourceStream.WaveFormat.AverageBytesPerSecond, conversionStream.SourceBuffer.Length);
            preferredSourceReadSize -= (preferredSourceReadSize % sourceStream.WaveFormat.BlockAlign);
        }
Ejemplo n.º 15
0
 public static extern MmResult waveInOpen(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormatProvider lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);
Ejemplo n.º 16
0
 /// <summary>
 /// Creates a new WaveFileWriter
 /// </summary>
 /// <param name="filename">The filename to write to</param>
 /// <param name="format">The Wave Format of the output data</param>
 public WaveFileWriter(string filename, WaveFormatProvider format)
     : this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read), format)
 {
     this.filename = filename;
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Reads from this wave stream
        /// </summary>
        /// <param name="buffer">Buffer to read into</param>
        /// <param name="offset">Offset in buffer</param>
        /// <param name="count">Bytes required</param>
        /// <returns>Number of bytes read; 0 indicates end of stream</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (pReader == null)
            {
                pReader = CreateReader(settings);
            }
            if (repositionTo != -1)
            {
                Reposition(repositionTo);
            }

            int bytesWritten = 0;

            // read in any leftovers from last time
            if (decoderOutputCount > 0)
            {
                bytesWritten += ReadFromDecoderBuffer(buffer, offset, count - bytesWritten);
            }

            while (bytesWritten < count)
            {
                IMFSample             pSample;
                MF_SOURCE_READER_FLAG dwFlags;
                ulong timestamp;
                int   actualStreamIndex;
                pReader.ReadSample(MediaFoundationInterop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, out actualStreamIndex, out dwFlags, out timestamp, out pSample);
                if ((dwFlags & MF_SOURCE_READER_FLAG.MF_SOURCE_READERF_ENDOFSTREAM) != 0)
                {
                    // reached the end of the stream
                    break;
                }
                else if ((dwFlags & MF_SOURCE_READER_FLAG.MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED) != 0)
                {
                    waveFormat = GetCurrentWaveFormat(pReader);
                    OnWaveFormatChanged();
                    // carry on, but user must handle the change of format
                }
                else if (dwFlags != 0)
                {
                    throw new InvalidOperationException(String.Format("MediaFoundationReadError {0}", dwFlags));
                }

                IMFMediaBuffer pBuffer;
                pSample.ConvertToContiguousBuffer(out pBuffer);
                IntPtr pAudioData;
                int    cbBuffer;
                int    pcbMaxLength;
                pBuffer.Lock(out pAudioData, out pcbMaxLength, out cbBuffer);
                EnsureBuffer(cbBuffer);
                Marshal.Copy(pAudioData, decoderOutputBuffer, 0, cbBuffer);
                decoderOutputOffset = 0;
                decoderOutputCount  = cbBuffer;

                bytesWritten += ReadFromDecoderBuffer(buffer, offset + bytesWritten, count - bytesWritten);


                pBuffer.Unlock();
                Marshal.ReleaseComObject(pBuffer);
                Marshal.ReleaseComObject(pSample);
            }
            position += bytesWritten;
            return(bytesWritten);
        }
Ejemplo n.º 18
0
 public static extern MmResult waveInOpenWindow(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormatProvider lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);