//
//  SHMp3RecordManager.m
//  ShorthandMaster
//
//  Created by 明津李 on 2020/9/1.
//  Copyright © 2020 明津李. All rights reserved.
//

#import "SHMp3RecordManager.h"
//#import "XBPCMPlayer.h"
//#import "XBAudioFormatConversion.h"
#import "XBAudioUnitRecorder.h"
//#import "XBAudioUnitMixerTest.h"
#import "XBAudioTool.h"
//#import "XBAudioConverterPlayer.h"
//#import "XBAudioPlayer.h"
//#import "XBAudioUnitMixer.h"
//#import "XBAudioPCMDataReader.h"
//#import "XBAudioFileDataReader.h"
#import "XBExtAudioFileRef.h"
//#import "ExtAudioFileMixer.h"
#import "XBDataWriter.h"
//#import "XBAACEncoder_system.h"
#import "MP3Encoder.h"

@interface SHMp3RecordManager ()

//@property (nonatomic,strong) XBPCMPlayer *palyer;
@property (nonatomic,strong) XBAudioUnitRecorder *recorder;
//@property (nonatomic,strong) XBAudioUnitMixerTest *mixer;
//@property (nonatomic,strong) XBAudioConverterPlayer *audioPlayer;
//@property (nonatomic,strong) XBAudioPlayer *audioPlayerNew;
//@property (nonatomic,strong) XBAudioUnitMixer *musicMixer;
//@property (nonatomic,strong) XBAudioPCMDataReader *dataReader;
@property (nonatomic,strong) XBExtAudioFileRef *xbFile;
@property (nonatomic,strong) XBDataWriter *dataWriter;
//@property (nonatomic,strong) XBAACEncoder_system *aacEncoder;
@property (nonatomic,strong) MP3Encoder *mp3Encoder;

@property (nonatomic, copy) NSString * mp3StroePath;
@property (nonatomic, copy) NSString * PCMStorePath;

@end

static SHMp3RecordManager * manager;

@implementation SHMp3RecordManager

+ (instancetype)shared{
    static dispatch_once_t o;
    dispatch_once(&o, ^{
        manager = [[SHMp3RecordManager alloc] init];
    });
    return manager;
}

+ (instancetype)alloc{
    if (manager) {
        // 如果单例对象存在则抛出异常
        NSException *exception = [NSException exceptionWithName:[NSString stringWithFormat:@"重复创建%@单例对象 异常", [self class]] reason:@"请使用单例" userInfo:nil];
        [exception raise];
    }
    return [super alloc]; // 如果单例对象不存在 正常创建
}

- (id)copyWithZone:(struct _NSZone *)zone{
    return manager;
}

+ (id)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [super allocWithZone:zone];
    });
    return manager;
}

- (instancetype)init{
    if (self = [super init]) {
        
    }
    return self;
}

- (void)configMp3Path:(NSString *)mp3Path PCMPath:(NSString *)PCMPath{
    self.mp3StroePath = mp3Path;
    self.PCMStorePath = PCMPath;
    [self mp3EncodeTest];
}

- (void)start{
    [self.recorder start];
}

- (void)pause{
    [self.recorder stop];
}

- (void)stop{
    [self.recorder stop];
    self.recorder = nil;
}

- (void)reset{
    
}

#pragma mark - mp3编码
- (void)mp3EncodeTest{
    
//    NSLog(@"%@", mp3StroePath);
    [self deleteFileAtPath:self.mp3StroePath];
    
    self.recorder = [[XBAudioUnitRecorder alloc] initWithRate:XBAudioRate_44k bit:XBAudioBit_16 channel:XBAudioChannel_1];

    _mp3Encoder = [[MP3Encoder alloc] initWithSampleRate:XBAudioRate_44k channels:1 bitRate:128];

    self.dataWriter = [[XBDataWriter alloc] init];

    typeof(self) __weak weakSelf = self;
    self.recorder.bl_output = ^(AudioBufferList *bufferList) {
        AudioBuffer buffer = bufferList->mBuffers[0];
        [weakSelf.mp3Encoder encodePCMData:buffer.mData len:buffer.mDataByteSize completeBlock:^(unsigned char *encodedData, int len) {
            [weakSelf.dataWriter writeBytes:encodedData len:len toPath:weakSelf.mp3StroePath];
        }];
    };
    
    [self writeTest];
    
//    [self.recorder start];
}

#pragma mark - 测试文件写入
- (void)writeTest{
    
    [self deleteFileAtPath:self.PCMStorePath];
//    self.recorder = [[XBAudioUnitRecorder alloc] initWithRate:XBAudioRate_44k bit:XBAudioBit_16 channel:XBAudioChannel_1];

    AudioStreamBasicDescription desc = [XBAudioTool allocAudioStreamBasicDescriptionWithMFormatID:XBAudioFormatID_PCM mFormatFlags:(XBAudioFormatFlags)(kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) mSampleRate:XBAudioRate_44k mFramesPerPacket:1 mChannelsPerFrame:XBAudioChannel_2 mBitsPerChannel:XBAudioBit_16];
    self.xbFile = [[XBExtAudioFileRef alloc] initWithStorePath:self.PCMStorePath inputFormat:&desc];
    
    typeof(self) __weak weakSelf = self;

    self.recorder.bl_outputFull = ^(XBAudioUnitRecorder *player, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {
        [weakSelf.xbFile writeIoData:ioData inNumberFrames:inNumberFrames];
    };
//    [self.recorder start];
}

- (void)deleteFileAtPath:(NSString *)path{
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
        [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
    }
}

- (void)write:(NSData *)data path:path{
    self.dataWriter = [[XBDataWriter alloc] init];
    [self.dataWriter writeData:data toPath:path];
}

@end
