0

I was refering to below link : - OBJC AVSpeechUtterance writeUtterance how? for an answer to my problem. But the above link works well w.r.t. writing only one audio file from AVSpeechSynthesizer. What if I need to write multiple raw pcm audio files to my database.

The issue I am facing is that the buffer callback is called multiple times. So i can not figure out if the file writing is done for first utterance and can I start writing to another file. Below is my code base: -

AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:@"test 123"];
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"];
[utterance setVoice:voice];

__block AVAudioFile *output = nil;

[synthesizer writeUtterance:utterance
           toBufferCallback:^(AVAudioBuffer * _Nonnull buffer) {
    AVAudioPCMBuffer *pcmBuffer = (AVAudioPCMBuffer*)buffer;
    if (!pcmBuffer) {
        NSLog(@"Error");
        return;
    }
    if (pcmBuffer.frameLength != 0) {
        //append buffer to file
        if (output == nil) {
            output = [[AVAudioFile alloc] initForWriting:[NSURL fileURLWithPath:@"test.caf"]
                                                settings:pcmBuffer.format.settings
                                            commonFormat:AVAudioPCMFormatInt16
                                             interleaved:NO error:nil];
        }
        [output writeFromBuffer:pcmBuffer error:nil];
    }
}];
Amish
  • 21
  • 5

1 Answers1

0

Ahh. Got it finally. It's the frameLength property of AVAudioPCMBuffer class which helped me figuring out if the audio stream is written completely or not. Make use of this property and keep track of total frameLength written into file by declaring a new var outside the synthesizer block. You can refer to below code: -

        __block long currentFrameLength = 0;
        [synthesizer writeUtterance:utterance
                   toBufferCallback:^(AVAudioBuffer * _Nonnull buffer) {
            if(currentFrameLength == 0) {
            { // This check signifies that previous file is completely written 
            }
    currentFrameLength = currentFrameLength + pcmBuffer.frameLength;
Amish
  • 21
  • 5