public AudioConverterError FillComplexBuffer(ref int outputDataPacketSize, AudioBuffers outputData, AudioStreamPacketDescription[] packetDescription) { AudioConverterError res; var this_handle = GCHandle.Alloc(this); var this_ptr = GCHandle.ToIntPtr(this_handle); if (packetDescription == null) { res = AudioConverterFillComplexBuffer(handle, ComplexInputDataShared, this_ptr, ref outputDataPacketSize, (IntPtr)outputData, IntPtr.Zero); } else { unsafe { fixed(AudioStreamPacketDescription *pdesc = &packetDescription[0]) { res = AudioConverterFillComplexBuffer(handle, ComplexInputDataShared, this_ptr, ref outputDataPacketSize, (IntPtr)outputData, (IntPtr)pdesc); } } } return(res); }
public AudioConverterError ConvertComplexBuffer(int numberPCMFrames, AudioBuffers inputData, AudioBuffers outputData) { if (inputData == null) { throw new ArgumentNullException("inputData"); } if (outputData == null) { throw new ArgumentNullException("outputData"); } return(AudioConverterConvertComplexBuffer(handle, numberPCMFrames, (IntPtr)inputData, (IntPtr)outputData)); }
public static bool GetDataFromExtAudioFile (ExtAudioFile ext, AudioStreamBasicDescription outputFormat, int maxBufferSize, byte[] dataBuffer, out int dataBufferSize, out ALFormat format, out double sampleRate) { uint errorStatus = 0; uint bufferSizeInFrames = 0; dataBufferSize = 0; format = ALFormat.Mono16; sampleRate = 0; /* Compute how many frames will fit into our max buffer size */ bufferSizeInFrames = (uint)(maxBufferSize / outputFormat.BytesPerFrame); if (dataBuffer != null) { var audioBufferList = new AudioBuffers(maxBufferSize); // This a hack so if there is a problem speak to kjpou1 -Kenneth // the cleanest way is to copy the buffer to the pointer already allocated // but what we are going to do is replace the pointer with our own and restore it later // GCHandle meBePinned = GCHandle.Alloc (dataBuffer, GCHandleType.Pinned); IntPtr meBePointer = meBePinned.AddrOfPinnedObject (); audioBufferList.SetData (0, meBePointer); try { // Read the data into an AudioBufferList // errorStatus here returns back the amount of information read ExtAudioFileError extAudioFileError = ExtAudioFileError.OK; errorStatus = ext.Read (bufferSizeInFrames, audioBufferList, out extAudioFileError); if (errorStatus >= 0) { /* Success */ /* Note: 0 == bufferSizeInFrames is a legitimate value meaning we are EOF. */ /* ExtAudioFile.Read returns the number of frames actually read. * Need to convert back to bytes. */ dataBufferSize = (int)bufferSizeInFrames * outputFormat.BytesPerFrame; // Now we set our format format = outputFormat.ChannelsPerFrame > 1 ? ALFormat.Stereo16 : ALFormat.Mono16; sampleRate = outputFormat.SampleRate; } else { #if DEBUG Console.WriteLine ("ExtAudioFile.Read failed, Error = " + errorStatus); #endif return false; } } catch (Exception exc) { #if DEBUG Console.WriteLine ("ExtAudioFile.Read failed: " + exc.Message); #endif return false; } finally { // Don't forget to free our dataBuffer memory pointer that was pinned above meBePinned.Free (); // and restore what was allocated to beginwith audioBufferList.SetData (0, IntPtr.Zero); } } return true; }
public ExtAudioFileError WriteAsync(uint numberFrames, AudioBuffers audioBufferList) { if (audioBufferList == null) throw new ArgumentNullException ("audioBufferList"); return ExtAudioFileWriteAsync (_extAudioFile, numberFrames, (IntPtr) audioBufferList); }
public uint Read(uint numberFrames, AudioBuffers audioBufferList, out ExtAudioFileError status) { if (audioBufferList == null) throw new ArgumentNullException ("audioBufferList"); status = ExtAudioFileRead (_extAudioFile, ref numberFrames, (IntPtr) audioBufferList); return numberFrames; }
public AudioUnitStatus Render (ref AudioUnitRenderActionFlags actionFlags, AudioTimeStamp timeStamp, uint busNumber, uint numberFrames, AudioBuffers data) { return AudioUnitRender (handle, ref actionFlags, ref timeStamp, busNumber, numberFrames, (IntPtr) data); }
static AudioConverterError HandleInputData (ref int numberDataPackets, AudioBuffers data, ref AudioStreamPacketDescription[] dataPacketDescription) { int maxPackets = afio.SrcBufferSize / afio.SrcSizePerPacket; if (numberDataPackets > maxPackets) numberDataPackets = maxPackets; // read from the file int outNumBytes; var res = afio.SourceFile.ReadPackets (false, out outNumBytes, afio.PacketDescriptions, afio.SrcFilePos, ref numberDataPackets, afio.SrcBuffer); if (res != 0) { throw new ApplicationException (res.ToString ()); } // advance input file packet position afio.SrcFilePos += numberDataPackets; // put the data pointer into the buffer list data.SetData (0, afio.SrcBuffer, outNumBytes); // don't forget the packet descriptions if required if (dataPacketDescription != null) { if (afio.PacketDescriptions != null) { dataPacketDescription = afio.PacketDescriptions; } else { dataPacketDescription = null; } } return AudioConverterError.None; }
public static bool Convert(string input, string output, AudioFormatType targetFormat, AudioFileType containerType, Microsoft.Xna.Framework.Content.Pipeline.Audio.ConversionQuality quality) { CFUrl source = CFUrl.FromFile (input); CFUrl dest = CFUrl.FromFile (output); var dstFormat = new AudioStreamBasicDescription (); var sourceFile = AudioFile.Open (source, AudioFilePermission.Read); AudioFormatType outputFormat = targetFormat; // get the source data format var srcFormat = (AudioStreamBasicDescription)sourceFile.DataFormat; var outputSampleRate = 0; switch (quality) { case Microsoft.Xna.Framework.Content.Pipeline.Audio.ConversionQuality.Low: outputSampleRate = (int)Math.Max (8000, srcFormat.SampleRate / 2); break; default: outputSampleRate = (int)Math.Max (8000, srcFormat.SampleRate); break; } dstFormat.SampleRate = (outputSampleRate == 0 ? srcFormat.SampleRate : outputSampleRate); // set sample rate if (outputFormat == AudioFormatType.LinearPCM) { // if the output format is PC create a 16-bit int PCM file format description as an example dstFormat.Format = outputFormat; dstFormat.ChannelsPerFrame = srcFormat.ChannelsPerFrame; dstFormat.BitsPerChannel = 16; dstFormat.BytesPerPacket = dstFormat.BytesPerFrame = 2 * dstFormat.ChannelsPerFrame; dstFormat.FramesPerPacket = 1; dstFormat.FormatFlags = AudioFormatFlags.LinearPCMIsPacked | AudioFormatFlags.LinearPCMIsSignedInteger; } else { // compressed format - need to set at least format, sample rate and channel fields for kAudioFormatProperty_FormatInfo dstFormat.Format = outputFormat; dstFormat.ChannelsPerFrame = (outputFormat == AudioFormatType.iLBC ? 1 : srcFormat.ChannelsPerFrame); // for iLBC num channels must be 1 // use AudioFormat API to fill out the rest of the description var fie = AudioStreamBasicDescription.GetFormatInfo (ref dstFormat); if (fie != AudioFormatError.None) { return false; } } var converter = AudioConverter.Create (srcFormat, dstFormat); converter.InputData += HandleInputData; // if the source has a cookie, get it and set it on the Audio Converter ReadCookie (sourceFile, converter); // get the actual formats back from the Audio Converter srcFormat = converter.CurrentInputStreamDescription; dstFormat = converter.CurrentOutputStreamDescription; // if encoding to AAC set the bitrate to 192k which is a nice value for this demo // kAudioConverterEncodeBitRate is a UInt32 value containing the number of bits per second to aim for when encoding data if (dstFormat.Format == AudioFormatType.MPEG4AAC) { uint outputBitRate = 192000; // 192k // ignore errors as setting may be invalid depending on format specifics such as samplerate try { converter.EncodeBitRate = outputBitRate; } catch { } // get it back and print it out outputBitRate = converter.EncodeBitRate; } // create the destination file var destinationFile = AudioFile.Create (dest, containerType, dstFormat, AudioFileFlags.EraseFlags); // set up source buffers and data proc info struct afio = new AudioFileIO (32768); afio.SourceFile = sourceFile; afio.SrcFormat = srcFormat; if (srcFormat.BytesPerPacket == 0) { // if the source format is VBR, we need to get the maximum packet size // use kAudioFilePropertyPacketSizeUpperBound which returns the theoretical maximum packet size // in the file (without actually scanning the whole file to find the largest packet, // as may happen with kAudioFilePropertyMaximumPacketSize) afio.SrcSizePerPacket = sourceFile.PacketSizeUpperBound; // how many packets can we read for our buffer size? afio.NumPacketsPerRead = afio.SrcBufferSize / afio.SrcSizePerPacket; // allocate memory for the PacketDescription structures describing the layout of each packet afio.PacketDescriptions = new AudioStreamPacketDescription [afio.NumPacketsPerRead]; } else { // CBR source format afio.SrcSizePerPacket = srcFormat.BytesPerPacket; afio.NumPacketsPerRead = afio.SrcBufferSize / afio.SrcSizePerPacket; // allocate memory for the PacketDescription structures describing the layout of each packet afio.PacketDescriptions = new AudioStreamPacketDescription [afio.NumPacketsPerRead]; } // set up output buffers int outputSizePerPacket = dstFormat.BytesPerPacket; // this will be non-zero if the format is CBR const int theOutputBufSize = 32768; var outputBuffer = Marshal.AllocHGlobal (theOutputBufSize); AudioStreamPacketDescription[] outputPacketDescriptions = null; if (outputSizePerPacket == 0) { // if the destination format is VBR, we need to get max size per packet from the converter outputSizePerPacket = (int)converter.MaximumOutputPacketSize; } // allocate memory for the PacketDescription structures describing the layout of each packet outputPacketDescriptions = new AudioStreamPacketDescription [theOutputBufSize / outputSizePerPacket]; int numOutputPackets = theOutputBufSize / outputSizePerPacket; // if the destination format has a cookie, get it and set it on the output file WriteCookie (converter, destinationFile); // write destination channel layout if (srcFormat.ChannelsPerFrame > 2) { WriteDestinationChannelLayout (converter, sourceFile, destinationFile); } long totalOutputFrames = 0; // used for debugging long outputFilePos = 0; AudioBuffers fillBufList = new AudioBuffers (1); bool error = false; // loop to convert data while (true) { // set up output buffer list fillBufList [0] = new AudioBuffer () { NumberChannels = dstFormat.ChannelsPerFrame, DataByteSize = theOutputBufSize, Data = outputBuffer }; // convert data int ioOutputDataPackets = numOutputPackets; var fe = converter.FillComplexBuffer (ref ioOutputDataPackets, fillBufList, outputPacketDescriptions); // if interrupted in the process of the conversion call, we must handle the error appropriately if (fe != AudioConverterError.None) { error = true; break; } if (ioOutputDataPackets == 0) { // this is the EOF conditon break; } // write to output file var inNumBytes = fillBufList [0].DataByteSize; var we = destinationFile.WritePackets (false, inNumBytes, outputPacketDescriptions, outputFilePos, ref ioOutputDataPackets, outputBuffer); if (we != 0) { error = true; break; } // advance output file packet position outputFilePos += ioOutputDataPackets; if (dstFormat.FramesPerPacket != 0) { // the format has constant frames per packet totalOutputFrames += (ioOutputDataPackets * dstFormat.FramesPerPacket); } else { // variable frames per packet require doing this for each packet (adding up the number of sample frames of data in each packet) for (var i = 0; i < ioOutputDataPackets; ++i) totalOutputFrames += outputPacketDescriptions [i].VariableFramesInPacket; } } Marshal.FreeHGlobal (outputBuffer); if (!error) { // write out any of the leading and trailing frames for compressed formats only if (dstFormat.BitsPerChannel == 0) { // our output frame count should jive with WritePacketTableInfo (converter, destinationFile); } // write the cookie again - sometimes codecs will update cookies at the end of a conversion WriteCookie (converter, destinationFile); } converter.Dispose (); destinationFile.Dispose (); sourceFile.Dispose (); return true; }