Recently, after work, do a project, the project is the first phase of the main function of audio recording and playback, audio formats include: m4a, mp3, wav three formats, to support inflexion in the process of recording, but also can get metering with drawing in the process of recording sound intensity variation, playback functions including audio waveform figure drawing, and audio playback.

Before doing this, I knew very little about the recording knowledge in iOS, so THAT I made many detours. Although I wasted a lot of time, I also learned a lot from it, and finally completed the coding of the project.

The following, mainly introduces the recording of the development summary, playback of the follow-up record.

If you want to implement recording in iOS, there are four ways to implement recording:

  1. AVAudioRecorder: this is the simplest recording method, only need to configure good recording format can get the corresponding file, but the corresponding, this way can not get the audio source data in the recording process, unable to achieve the function of changing sound and recording MP3 files.
  2. AVAudioEngine: AVAudioEngine has powerful functions, which can realize recording, playing, reverb, sound change and other functions. When I found my class, I was very happy. I read a lot of documents. For example, you can’t change AudioEngine’s default inputNode, outputNode, and mainMixNode formats. Even if you managed to do so, the output would slap you in the face. It’s too early to tell you, and inputNode, outputNode, and mainMixNode don’t automatically convert data to…… If you want to record M4A and MP3, you still need other ways to achieve it.
  3. AudioQueue & AudioFile: AudioQueue has a callback method in the recording process, which throws encoded audio data. If you want to process audio data, such as tone change and transcoding, it can be realized in this callback, and it can obtain metering data. AudioFile is used to store the audio data thrown in the callback method in accordance with the inFormat configured when AudioFile was created. If you want to understand the AudioQueue, look at this documentation
  4. AudioUnit & ExtAudioFile: AudioUnit only supports PCM recording, so use ExtAudioFile to record other audio formats. ExtAudioFile is a treasure class that can automatically convert audio formats.

If only a simple hire, then the use of AVAudioRecorder can be very simple to achieve, if you want to do audio data processing, then for the recording process thrown data must be PCM, as long as you can get PCM source data, any audio processing can be done as long as you want to achieve.

On iOS, the system supports the following recording encoding formats:

Click on the official reference document

Wav files are lossless encoding formats PCM, M4A, AAC, and MP3 files. The iOS system does not support recording, and mp3 files are supported by the system. There is a decoder but no encoder.

metaphone

The iOS system itself supports the sound change function. AudioUnit has an attribute kNewTimePitchParam_Pitch, which can change the sound color. However, this attribute is a MixerUnit attribute, and the recording OutputUnit does not support this attribute. To link MixerUnit to OutputUnit, we need the AUGraph class to do this, but AUGraph is deprecated… The system recommended to use AVAudioEngine class, this class is also a pit, I can not achieve m4A file recording in the demo, so I gave up.

SoundTouch supports PCM encoding and the audio data is lettle-Endian. Therefore, the format of the audio buffer thrown in the recording process must be PCM, otherwise, it is impossible to change the sound while recording.

In this way, AudioUnit seems to be more suitable for this project, but AudioUnit cannot obtain the metering data in the recording process, which is really a sad thing. AudioUnit is very powerful, if AUGraph is not abandoned, MAYBE I will use it for recording.

Finally, my implementation scheme is as follows:

1. Wav file recording: AudioQueue recording and AudioFile storage files. The dataFormat of AudioQueue and AudioFile is:

AudioStreamBasicDescription mDataFormat;

mDataFormat.mSampleRate = 44100;
mDataFormat.mChannelsPerFrame = 1;
mDataFormat.mReserved = 0;
mDataFormat.mBitsPerChannel = 16; 
mDataFormat.mFramesPerPacket = 1;
mDataFormat.mSampleRate = self.model.sampleRate;
mDataFormat.mBytesPerFrame = mDataFormat.mBytesPerPacket = 2;       
mDataFormat.mFormatID = kAudioFormatLinearPCM;        
mDataFormat.mFormatFlags =  kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;       
Copy the code

The fileType of an AudioFile is kAudioFileCAFType

2. Mp3 FILE: AudioQueue recording, lame transcoding, FILE FILE storage, AudioQueue encoding format:

AudioStreamBasicDescription mDataFormat; mDataFormat.mSampleRate = 44100; mDataFormat.mChannelsPerFrame = 1; mDataFormat.mReserved = 0; mDataFormat.mBitsPerChannel = 16; mDataFormat.mFramesPerPacket = 1; mDataFormat.mSampleRate = self.model.sampleRate; mDataFormat.mBytesPerFrame = mDataFormat.mBytesPerPacket = 2; mDataFormat.mFormatID = kAudioFormatLinearPCM; mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kAudioFormatFlagIsNonInterleavedCopy the code

3. M4a file: AudioQueue recording, ExtAudioFile transcoding and storage. The encoding format of kExtAudioFileProperty_ClientDataFormat property of AudioQueue and ExtAudioFile is:

AudioStreamBasicDescription mDataFormat;

mDataFormat.mSampleRate = 44100;
mDataFormat.mChannelsPerFrame = 1;
mDataFormat.mReserved = 0;
mDataFormat.mBitsPerChannel = 16; 
mDataFormat.mFramesPerPacket = 1;
mDataFormat.mSampleRate = self.model.sampleRate;
mDataFormat.mBytesPerFrame = mDataFormat.mBytesPerPacket = 2;       
mDataFormat.mFormatID = kAudioFormatLinearPCM;        
mDataFormat.mFormatFlags =  kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;       
Copy the code

The audio encoding format of ExtAudioFile files is:

AudioStreamBasicDescription outputFormat; outputFormat.mSampleRate = 44100; outputFormat.mFormatID = kAudioFormatMPEG4AAC; outputFormat.mFormatFlags = 0; outputFormat.mBytesPerPacket = 0; outputFormat.mFramesPerPacket = 1024; outputFormat.mBytesPerFrame = 0; outputFormat.mChannelsPerFrame = 1; outputFormat.mBitsPerChannel = 0; outputFormat.mReserved = 0;Copy the code

The code implementation of the four recording methods will be updated later, and the audio editing function may be met in the second phase. At that time, I will also study and record, and I hope I will not be too lazy……