//Declare string for application temp path and tack on the file extension
string fileName = string.Format ("Myfile{0}.wav", DateTime.Now.ToString ("yyyyMMddHHmmss"));
string audioFilePath = Path.Combine (Path.GetTempPath (), fileName);
Console.WriteLine("Audio File Path: " + audioFilePath);
url = NSUrl.FromFilename(audioFilePath);
//set up the NSObject Array of values that will be combined with the keys to make the NSDictionary
NSObject[] values = new NSObject[]
{
NSNumber.FromFloat (44100.0f), //Sample Rate
NSNumber.FromInt32 ((int)AudioToolbox.AudioFormatType.LinearPCM), //AVFormat
NSNumber.FromInt32 (2), //Channels
NSNumber.FromInt32 (16), //PCMBitDepth
NSNumber.FromBoolean (false), //IsBigEndianKey
NSNumber.FromBoolean (false) //IsFloatKey
};
//Set up the NSObject Array of keys that will be combined with the values to make the NSDictionary
NSObject[] keys = new NSObject[]
{
AVAudioSettings.AVSampleRateKey,
AVAudioSettings.AVFormatIDKey,
AVAudioSettings.AVNumberOfChannelsKey,
AVAudioSettings.AVLinearPCMBitDepthKey,
AVAudioSettings.AVLinearPCMIsBigEndianKey,
AVAudioSettings.AVLinearPCMIsFloatKey
};
//Set Settings with the Values and Keys to create the NSDictionary
settings = NSDictionary.FromObjectsAndKeys (values, keys);
//Set recorder parameters
recorder = AVAudioRecorder.Create(url, new AudioSettings(settings), out error);
//Set Recorder to Prepare To Record
recorder.PrepareToRecord();
This代码效果很好,但是如何将麦克风的记录直接保存到流? 我没有在互联网上找到任何信息,我希望你能帮助我
答案 0 :(得分:2)
您正在寻找对音频流的缓冲访问(录制或播放),iOS通过Audio Queue Services
提供它(AVAudioRecorder
太高级别),因此当音频缓冲区被填充时,iOS调用你的callback
有一个来自队列的填充缓冲区,你用它做一些事情(将它保存到磁盘,将其写入基于C#的Stream,发送到播放音频队列[发言者]等...)和通常,将其放回队列中以便重复使用。
这样的事情开始录制到queue
音频缓冲区:
var recordFormat = new AudioStreamBasicDescription() {
SampleRate = 8000,
Format = AudioFormatType.LinearPCM,
FormatFlags = AudioFormatFlags.LinearPCMIsSignedInteger | AudioFormatFlags.LinearPCMIsPacked,
FramesPerPacket = 1,
ChannelsPerFrame = 1,
BitsPerChannel = 16,
BytesPerPacket = 2,
BytesPerFrame = 2,
Reserved = 0
};
recorder = new InputAudioQueue (recordFormat);
for (int count = 0; count < BufferCount; count++) {
IntPtr bufferPointer;
recorder.AllocateBuffer(AudioBufferSize, out bufferPointer);
recorder.EnqueueBuffer(bufferPointer, AudioBufferSize, null);
}
recorder.InputCompleted += HandleInputCompleted;
recorder.Start ();
因此,在此示例中假设AudioBufferSize
为8k且BufferCount
为3,因此一旦填充了三个缓冲区中的第一个,就会调用我们的处理程序HandleInputCompleted
(因为有2个仍在queue
录音中的缓冲区继续存在。
我们的InputCompleted
处理程序:
private void HandleInputCompleted (object sender, InputCompletedEventArgs e)
{
// We received a new buffer of audio, do something with it....
// Some unsafe code will be required to rip the buffer...
// Place the buffer back into the queue so iOS knows you are done with it
recorder.EnqueueBuffer(e.IntPtrBuffer, AudioBufferSize, null);
// At some point you need to call `recorder.Stop();` ;-)
}
(我从处理程序中删除了我们的代码,因为它是一个自定义的音频2文本学习中性网络,因为我们在非常大的队列中使用非常小的缓冲区来减少反馈延迟并在单个TCP / UDP中加载音频数据用于云处理的数据包(想想Siri
; - )
在此处理程序中,您可以访问Pointer
到当前通过InputCompletedEventArgs.IntPtrBuffer
填充的缓冲区,使用该指针可以peek
缓冲区中的每个字节poke
如果这是你的目标,那么将它们添加到基于C#的Stream中。