2015-12-30 1 views
1

Je travaille sur une application qui permet à l'utilisateur d'enregistrer de l'audio, de le lire en changeant la hauteur puis d'enregistrer ce qu'il a fait dans un fichier séparé.Appuyez sur installé sur le moteur audio ne produisant que des fichiers courts

Le code semble fonctionner mais le nouveau fichier a une durée de seulement 0,37 secondes (5 secondes d'origine). Je suppose que lorsque j'écris à partir du tampon, il continue à économiser sur lui-même, me laissant ainsi avec juste le dernier segment. Si c'est mon problème, comment puis-je ajouter le fichier au lieu d'écrire dessus?

let recordSettings:[String : AnyObject] = [ 
     AVFormatIDKey: NSNumber(unsignedInt:kAudioFormatAppleLossless), 
     AVEncoderAudioQualityKey : AVAudioQuality.Max.rawValue, 
     AVEncoderBitRateKey : 320000, 
     AVNumberOfChannelsKey: 2, 
     AVSampleRateKey : 44100.0 
    ] 


    var outputFile = AVAudioFile() 

    let format = NSDateFormatter() 
    format.dateFormat="dd-HH-mm-ss" 
    let currentFileName = "recording-\(format.stringFromDate(NSDate())).m4a" 
    print(currentFileName) 

    let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] 
    self.url2 = documentsDirectory.URLByAppendingPathComponent(currentFileName) 

    let inputNode = engine.inputNode 
    let bus = 0 

    engine.mainMixerNode.installTapOnBus(bus, bufferSize: 2048, format: self.engine.mainMixerNode.inputFormatForBus(0)) { 
     (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in 

     do { 

      let outputFile = try AVAudioFile(forWriting: self.url2, settings: recordSettings, commonFormat: AVAudioCommonFormat.PCMFormatFloat32, interleaved: false) 

      try outputFile.writeFromBuffer(buffer) 
      outputFile.framePosition = outputFile.length 

     } catch let error as NSError { 
      NSLog("Error writing %@", error.localizedDescription) 
     } 

    } 

code mis à jour la création d'un fichier avec une durée de 0,0:

func play() { 

    let duration = CMTimeGetSeconds(AVAsset(URL: url).duration) 
    print("Duration") 
    print(duration) 

    let file = try! AVAudioFile(forReading: url) 

    let buffer = AVAudioPCMBuffer(PCMFormat: file.processingFormat, frameCapacity: AVAudioFrameCount(file.length)) 
    do { 
     try file.readIntoBuffer(buffer) 
    } catch _ { 
    } 

    engine = AVAudioEngine() 
    player = AVAudioPlayerNode() 

    pitch.pitch = 500 


    engine.attachNode(player) 
    engine.attachNode(pitch) 

    engine.connect(player, to: pitch, format: buffer.format) 
    engine.connect(pitch, to: engine.mainMixerNode, format: nil) 

    let format = NSDateFormatter() 
    format.dateFormat="dd-HH-mm-ss" 
    let currentFileName = "recording-\(format.stringFromDate(NSDate())).m4a" 
    print(currentFileName) 

    let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] 
    self.url2 = documentsDirectory.URLByAppendingPathComponent(currentFileName) 

    let outputFile = try! AVAudioFile(forWriting: url2, settings: [ 
     AVFormatIDKey: NSNumber(unsignedInt:kAudioFormatAppleLossless), 
     AVEncoderAudioQualityKey : AVAudioQuality.Max.rawValue, 
     AVEncoderBitRateKey : 320000, 
     AVNumberOfChannelsKey: 2, 
     AVSampleRateKey : 44100.0 
    ]) 

    done = false 
    distortion.installTapOnBus(0, bufferSize: 2048, format: outputFile.processingFormat) { 
     (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in 

     let dataptrptr = buffer.floatChannelData 
     let dataptr = dataptrptr.memory 
     let datum = dataptr[Int(buffer.frameLength) - 1] 
     if self.done && fabs(datum) < 0.000001 { 
      print("stopping") 
      self.engine.stop() 
      return 
     } 

     do { 
      try outputFile.writeFromBuffer(buffer) 

     } catch let error as NSError { 
      NSLog("Error writing %@", error.localizedDescription) 
     } 
    } 

     player.scheduleBuffer(buffer, atTime: nil, options: AVAudioPlayerNodeBufferOptions.Loops, completionHandler: { 
      dispatch_async(dispatch_get_main_queue(),{ 
      self.done = true 
      self.player.stop() 
       self.engine.stop() 
      print("complete") 
      }) 
     }) 

    engine.prepare() 
    do { 
     try engine.start() 
     player.play() 
    } catch _ { 
     print("Play session Error") 
    } 

} 
+0

Avez-vous trouvé une solution? –

Répondre

3

Gardez à l'esprit que le gestionnaire installTapOnBus sera appelé plusieurs fois: à chaque fois que la mémoire tampon se remplit. Pensez-y comme une boucle. Cela n'a donc aucun sens de créer le fichier de sortie à chaque fois à travers cette boucle! Vous voulez créer le fichier de sortie une fois et puis lui écrire à plusieurs reprises. Ainsi, votre structure globale doit ressembler à ceci:

let outfile = try! AVAudioFile(forWriting: outurl, settings: // ... 
node.installTapOnBus(bus, bufferSize: size, format: outfile.processingFormat) { 
    (buffer : AVAudioPCMBuffer!, time : AVAudioTime!) in 
     do { 
      try outfile.writeFromBuffer(buffer) 
     } catch { 
      print(error) 
     } 
    } 

L'autre chose à retenir est que votre tampon remplira-et écrire exactement tant que le moteur continue à tourner, il ne faut pas arrêter le moteur prématurément (Je ne sais pas si vous faites cela, mais il est important de garder à l'esprit).

+0

Merci pour la réponse bien écrite. Cela a beaucoup de sens, mais je suis encore très jeune à ce sujet. J'ai mis à jour mon code ci-dessus pour suivre votre conseil, mais maintenant je crée des fichiers d'une durée de 0.0. Pourriez-vous me dire où je vais mal? –

+1

"Pourriez-vous me dire où je vais mal?" Non, car une grande partie de votre code n'est pas affichée. Comme je l'ai dit dans ma réponse, démarrer le moteur et le faire fonctionner assez longtemps pour produire le son à travers le tampon est à vous, mais vous ne montrez pas tout cela. Si cela peut vous aider à voir un exemple de travail, voici le code de l'exemple de tap dans mon livre (voir 'doButton5'): https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ bk2ch14p655AVAudioEngineTest/AVAudioEngineTest/ViewController.swift – matt