admin管理员组

文章数量:1356441

I'm able to get text to speech to audio file using the following code for iOS 12 iPhone 8 to create a car file:

audioFile = try AVAudioFile(
forWriting: saveToURL,
settings: pcmBuffer.format.settings,
commonFormat: .pcmFormatInt16,
interleaved: false)

where pcmBuffer.format.settings is:

    [AVAudioFileTypeKey: kAudioFileMP3Type,
        AVSampleRateKey: 48000,
    AVEncoderBitRateKey: 128000,
  AVNumberOfChannelsKey: 2,
          AVFormatIDKey: kAudioFormatLinearPCM]

Here is the main method in my code:

func synthesize(utteranceString: String, avAudioPCMBufferFormatSettings: [String:Any], usingVoiceIdentifier voiceIdentifier: String, utteranceRate: Float, pitchMultiplier: Float, andSaveAudioFileTo saveToURL: URL, completionHandler: ((_ pcmBuffer: AVAudioPCMBuffer, _ audioFile: AVAudioFile?)->Void)? = nil) {
    print("#", #function, "voiceIdentifier: \(voiceIdentifier)", terminator: "\n")
    
    let utterance = AVSpeechUtterance(string: utteranceString)
    utterance.rate = utteranceRate
    utterance.pitchMultiplier = pitchMultiplier
 
    let voice = AVSpeechSynthesisVoice(identifier: voiceIdentifier) // TODO: Why is this generating a nil?
    
    utterance.voice = voice
    
    synthesizer.write(utterance) { (buffer: AVAudioBuffer) in
        print("in closure")
        // TODO: Tailor code in this closure to adjust to current device running this app project.
        guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
            fatalError("unknown buffer unknown buffer type: \(buffer)")
        }
        if pcmBuffer.frameLength == 0 {
            print("done because buffer frame length equals 0")
        } else {
            // append buffer to file
            if self.audioFile == nil {
                print("self.audioFile == nil")
                do {
                    self.audioFile = try AVAudioFile(
                        forWriting: saveToURL,
                        settings: pcmBuffer.format.settings,
                        commonFormat: .pcmFormatInt16,
                        interleaved: false)
                } catch {
                    print("try AVAudioFile( catch error: \(error.localizedDescription)")
                    completionHandler?(pcmBuffer, nil)
                }
            }
            do {
                try self.audioFile!.write(from: pcmBuffer)
                print("!!! 2")
                completionHandler?(pcmBuffer, self.audioFile)
            } catch {
                print("try self.audioFile!.write(from: pcmBuffer) catch error: \(error.localizedDescription)")
                completionHandler?(pcmBuffer,nil)
            }
        }
    }
}

This code does not work when I run the app in iOS 18 on iPhone 13 Pro Max. The audio file is created, but it doesn't sound right. It has a lot of static and it seems the speech is very low pitch.

Can anyone give me a hint or an answer?

I'm able to get text to speech to audio file using the following code for iOS 12 iPhone 8 to create a car file:

audioFile = try AVAudioFile(
forWriting: saveToURL,
settings: pcmBuffer.format.settings,
commonFormat: .pcmFormatInt16,
interleaved: false)

where pcmBuffer.format.settings is:

    [AVAudioFileTypeKey: kAudioFileMP3Type,
        AVSampleRateKey: 48000,
    AVEncoderBitRateKey: 128000,
  AVNumberOfChannelsKey: 2,
          AVFormatIDKey: kAudioFormatLinearPCM]

Here is the main method in my code:

func synthesize(utteranceString: String, avAudioPCMBufferFormatSettings: [String:Any], usingVoiceIdentifier voiceIdentifier: String, utteranceRate: Float, pitchMultiplier: Float, andSaveAudioFileTo saveToURL: URL, completionHandler: ((_ pcmBuffer: AVAudioPCMBuffer, _ audioFile: AVAudioFile?)->Void)? = nil) {
    print("#", #function, "voiceIdentifier: \(voiceIdentifier)", terminator: "\n")
    
    let utterance = AVSpeechUtterance(string: utteranceString)
    utterance.rate = utteranceRate
    utterance.pitchMultiplier = pitchMultiplier
 
    let voice = AVSpeechSynthesisVoice(identifier: voiceIdentifier) // TODO: Why is this generating a nil?
    
    utterance.voice = voice
    
    synthesizer.write(utterance) { (buffer: AVAudioBuffer) in
        print("in closure")
        // TODO: Tailor code in this closure to adjust to current device running this app project.
        guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
            fatalError("unknown buffer unknown buffer type: \(buffer)")
        }
        if pcmBuffer.frameLength == 0 {
            print("done because buffer frame length equals 0")
        } else {
            // append buffer to file
            if self.audioFile == nil {
                print("self.audioFile == nil")
                do {
                    self.audioFile = try AVAudioFile(
                        forWriting: saveToURL,
                        settings: pcmBuffer.format.settings,
                        commonFormat: .pcmFormatInt16,
                        interleaved: false)
                } catch {
                    print("try AVAudioFile( catch error: \(error.localizedDescription)")
                    completionHandler?(pcmBuffer, nil)
                }
            }
            do {
                try self.audioFile!.write(from: pcmBuffer)
                print("!!! 2")
                completionHandler?(pcmBuffer, self.audioFile)
            } catch {
                print("try self.audioFile!.write(from: pcmBuffer) catch error: \(error.localizedDescription)")
                completionHandler?(pcmBuffer,nil)
            }
        }
    }
}

This code does not work when I run the app in iOS 18 on iPhone 13 Pro Max. The audio file is created, but it doesn't sound right. It has a lot of static and it seems the speech is very low pitch.

Can anyone give me a hint or an answer?

Share Improve this question asked Mar 31 at 5:50 danieldaniel 9865 gold badges33 silver badges76 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I only needed to replace .pcmFormatInt16 with .pcmFormatFloat32.

本文标签: swiftsave audio file in iOS 18 instead of iOS 12Stack Overflow