//
//  VideoAudioProcesser.m
//  ByteRTC
//
//  Created by bytedance on 2022/2/10.
//

#import "VodAudioProcessor.h"
#import "RTCHeader.h"

int VoidAudioMixingID = 3001;

@interface VodAudioProcessor ()

@property (nonatomic, weak) ByteRTCVideo *rtcKit;
@property (nonatomic, weak) NSDictionary *options;
@property (nonatomic, assign) int length;

@end

@implementation VodAudioProcessor {
    int16_t* buffer;
    int _samplerate;
    int _channels;
    NSTimeInterval _lastDiffTimestamp;
    int64_t _lastTimestamp;
}

- (instancetype)initWithRTCKit:(ByteRTCVideo *)rtcKit options:(NSDictionary *)options {
    if (self = [super init]) {
        self.rtcKit = rtcKit;
        self.options = options;
        _lastDiffTimestamp = 0;
        _lastTimestamp = 0;
        [rtcKit setScreenAudioSourceType:ByteRTCAudioSourceTypeExternal];
    }
    return self;
}

- (void)openAudio:(int)samplerate channels:(int)channels {
    _samplerate = samplerate;
    _channels = channels;
}

- (void)closeAudio {
}

- (void)releaseAudio {
}

- (void)processAudio:(float **)inouts samples:(int)samples timestamp:(int64_t)timestamp {
    NSTimeInterval time = [[NSDate dateWithTimeIntervalSinceNow:0] timeIntervalSince1970] * 1000;
    NSTimeInterval diffTime = (time - _lastDiffTimestamp);
    // NSLog(@"lzb process audio samples : %d ,timestamp : %lld, diff : %f", samples, timestamp, diffTime);

    if (_lastDiffTimestamp > 0 && timestamp > _lastTimestamp && diffTime < (timestamp - _lastTimestamp)) {
        int64_t sleepTime = timestamp - _lastTimestamp - 6;
        if (sleepTime < 40) {
            [NSThread sleepForTimeInterval:sleepTime / 1000.0f];
        }
    }
    _lastTimestamp = timestamp;
    _lastDiffTimestamp = time;

    int channelsCount = _channels;
    float gain = 1.0;
    int samplerate = _samplerate;
    
    int length = samples * channelsCount;
    if (self.length < length) {
        if (self.length > 0) {
            self.length = 0;
            delete [] (buffer);
        }
        buffer = new int16_t[length*2];
        self.length = length*2;
    }
    
    for (int i = 0; i < channelsCount; i++) {
        int offset = i;
        float *dataList = inouts[i];
        for (int j = 0; j < samples; j++) {
            float data = dataList[j];
            int value = gain * data * INT16_MAX;
            if(value > INT16_MAX){
                value = INT16_MAX;
            } else if(value < INT16_MIN){
                value = INT16_MIN;
            }
            buffer[offset] = value;
            offset += _channels;
        }
    }
    
    ByteRTCAudioFrame *frame = [[ByteRTCAudioFrame alloc] init];
    frame.buffer = [NSData dataWithBytes:buffer length:length*2];
    
    frame.samples = samples;
    frame.channel = (ByteRTCAudioChannel)channelsCount;
    frame.sampleRate = (ByteRTCAudioSampleRate)samplerate;

    [self.rtcKit pushScreenAudioFrame:frame];
    [self playAudioFrame:frame];
}

- (void)playAudioFrame:(ByteRTCAudioFrame *)frame {
    // TODO: use other impl
    ByteRTCAudioMixingManager *manager = [self.rtcKit getAudioMixingManager];
    [manager pushAudioMixingFrame:VoidAudioMixingID audioFrame:frame];
}

- (void)dealloc {
    if (self.length > 0) {
        delete [] buffer;
        self.length = 0;
    }
}

@end
