- (void)createAudioEngine {
[self addAudioFileToAudioFile];
[self connectNode];
[self startRecording];
[self addFileToPlayNode];
}
//播放文件加载到audioFile
- (void)addAudioFileToAudioFile {
NSURL *urlq = [[NSBundle mainBundle] URLForResource:@"abc" withExtension:@"mp3"];
NSError*error1;
self.playAudioFile= [[AVAudioFilealloc]initForReading:urlqerror:&error1];
if(error1) {
NSLog(@"AVAudioFile error: %@", [error1 localizedDescription]);
return;
}
}
//加入播放音频
- (void) addFileToPlayNode {
doublesampleRate =self.playAudioFile.fileFormat.sampleRate;
doublesampleTime = sampleRate *20.0;
AVAudioTime*futureTime = [AVAudioTimetimeWithSampleTime:sampleTimeatRate:sampleRate];
self.playerNode.volume=0.2;
[self.playerNode stop];
[self.playerNode scheduleFile:self.playAudioFile atTime:futureTime completionHandler:nil];
[self.playerNode play];
}
//开始
- (void)startRecording {
[self.audioEngine startAndReturnError:nil];
}
//暂停
- (void)pauseRecording {
[self.audioEngine pause];
[selfpcmToWav];
}
//停止
- (void)stopRecording {
[self.audioEngine stop];
[selfpcmToWav];
}
//重置
- (void)resetRecording {
[self.audioEngine reset];
}
- (void)startAndReturnError {
[self.audioEngine startAndReturnError:nil];
}
- (AVAudioEngine*)audioEngine {
if (!_audioEngine) {
_audioEngine= [[AVAudioEnginealloc]init];
}
return _audioEngine;
}
- (AVAudioPlayerNode*)playerNode {
if (!_playerNode) {
_playerNode= [[AVAudioPlayerNodealloc]init];
}
return _playerNode;
}
- (AVAudioUnitEQ*)eqNode {
if(!_eqNode) {
_eqNode= [[AVAudioUnitEQalloc]init];
}
return _eqNode;
}
//链接node
- (void)connectNode {
if (self.bgAudioModel) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryMultiRoute error:nil];
}
else{
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
}
// [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
// AVAudioFormat* format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:16000 channels:1];
// //创建音频文件。
// NSString * path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// NSString * filePath = [path stringByAppendingPathComponent:@"10.caf"];
// NSURL * url = [NSURL fileURLWithPath:filePath];
// AVAudioFile * audioFile = [[AVAudioFile alloc] initForWriting:url settings:@{} error:nil];
self.mixerNode = self.audioEngine.mainMixerNode;
[self.audioEngine.inputNode installTapOnBus:0 bufferSize:2048 format:[self.audioEngine.inputNode inputFormatForBus:AVAudioPlayerNodeBufferLoops] block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
// NSLog(@"buffer.format.sampleRate === %f", buffer.format.sampleRate);
// float * magnitudes = [[self class] performFFT:buffer];
// [audioFile writeFromBuffer:buffer error:nil];
// NSLog(@"我录制到的数据是 === %@", buffer);
NSData* pData = [selfpcm_downsample:buffer];
[self writePCMData:pData filePat:self.pcmFilePathName];
// int channels = UnsafeBufferPointer(start: PCMBuffer.floatChannelData, count: channelCount)
if(self.delegate&& [self.delegaterespondsToSelector:@selector(recordToolRecordingData:)]) {
[self.delegate recordToolRecordingData:pData];
}
}];
[self.audioEngine attachNode:self.eqNode];
[self.audioEngine attachNode:self.playerNode];
AVAudioFormat* inputFormat = [self.audioEngine.inputNode inputFormatForBus:AVAudioPlayerNodeBufferLoops];
[self.audioEngineconnect:self.audioEngine.inputNodeto:self.eqNodeformat:inputFormat];
[self.audioEngine connect:self.playerNode to:self.mixerNode format:inputFormat];
[self.audioEngine connect:self.audioEngine.mainMixerNode to:self.audioEngine.outputNode format:inputFormat];
[self.audioEngine startAndReturnError:nil];
}
//写入文件
- (void)writePCMData:(NSData*)datafilePat:(NSString*)filePath{
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManagerfileExistsAtPath:filePath])//如果不存在
{
[datawriteToFile:filePathatomically:NO];
return;
}
NSFileHandle*fileHandle = [NSFileHandlefileHandleForUpdatingAtPath:filePath];
[fileHandleseekToEndOfFile]; //将节点跳到文件的末尾
[fileHandlewriteData:data];//追加写入数据
[fileHandlecloseFile];
}
//buffer 转nsdata
- (NSData*)audioPCMBufferToData:(AVAudioPCMBuffer*)buffer {
NSData* pData = [[NSData alloc] initWithBytes:buffer.floatChannelData[0] length:buffer.frameLength * 4];
NSLog(@"我录制到的数据是 === %@", pData);
returnpData;
}
///转换测试代码--------------------------------------------------------
- (NSData*) pcm_downsample:(AVAudioPCMBuffer*)buffer {
//位深转换 float32 转 int16_t
NSData* pData = [[NSData alloc] initWithBytes:buffer.floatChannelData[0] length:buffer.frameLength * 4];
Byte*dataByte = (Byte*)[pDatabytes];
NSUIntegersrcSize = pData.length/4;
Float32vf32[srcSize];
memcpy(vf32, &dataByte[0], pData.length);
int16_tbArr[srcSize];
intr;
for(size_ti =0; i < srcSize; ++i) {
floatx = vf32[i];
floatc;
c = ((x < -1) ? -1: ((x >1) ?1: x));
c = c +1;
r = (int)(c *32767.5f);
r = r -32768;
bArr[i] = (short)r;
}
// NSMutableData *data2 = [[NSMutableData alloc] init];
// for (NSUInteger i = 0; i < srcSize; i++) {
//
// unsigned char valChar[2];
// valChar[0] = 0xff & bArr[i];
// valChar[1] = (0xff00 & bArr[i]) >> 8;
// [data2 appendBytes:valChar length:2];
// }
// return data2;
//码率转换 44100 转 16000
CGFloatsampleRate = buffer.format.sampleRate;//def 44100
uint32_tlast_pos = (uint32_t)(srcSize -1);
uint32_tdstSize = (srcSize/sampleRate)*16000;
int16_tbArr16[dstSize];
for(uint32_tidx =0; idx < dstSize; idx++) {
floatindex = ((float) idx *44100.0) / (16000.0);
uint32_tp1 = (uint32_t) index;
floatcoef = index - p1;
uint32_tp2 = (p1 == last_pos) ? last_pos : p1 +1;
bArr16[idx] = (int16_t) ((1.0f- coef) * bArr[p1] + coef * bArr[p2]);
//NSLog(@"%d",bArr16[idx]);
}
//音量增大
for(inti =0; i < dstSize; i++){
inttmp;
signedshortwData = bArr16[i];
tmp = wData*2.0;// 音量增大一倍
// 下面的code主要是为了溢出判断
if(tmp >32767)
tmp =32767;
elseif(tmp < -32768)
tmp = -32768;
bArr16[i] = tmp;
}
NSMutableData *data1 = [[NSMutableData alloc] init];
for(NSUIntegeri =0; i < dstSize; i++) {
unsignedcharvalChar[2];
valChar[0] =0xff& bArr16[i];
valChar[1] = (0xff00& bArr16[i]) >>8;
[data1appendBytes:valCharlength:2];
}
returndata1;
}