2017-05-25 1 views
1

Je souhaite traiter les octets lus à partir du microphone en utilisant Swift 3 sur mon iOS. J'utilise actuellement AVAudioEngine.Swift 3 AVAudioEngine format d'entrée microphone

print(inputNode.inputFormat(forBus: bus).settings) 
print(inputNode.inputFormat(forBus: bus).formatDescription) 

Cela me donne le résultat suivant:

["AVNumberOfChannelsKey": 1, "AVLinearPCMBitDepthKey": 32, "AVSampleRateKey": 16000, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsBigEndianKey": 0, "AVFormatIDKey": 1819304813, "AVLinearPCMIsFloatKey": 1] 
<CMAudioFormatDescription 0x14d5bbb0 [0x3a5fb7d8]> { 
    mediaType:'soun' 
    mediaSubType:'lpcm' 
    mediaSpecific: { 
     ASBD: { 
      mSampleRate: 16000.000000 
      mFormatID: 'lpcm' 
      mFormatFlags: 0x29 
      mBytesPerPacket: 4 
      mFramesPerPacket: 1 
      mBytesPerFrame: 4 
      mChannelsPerFrame: 1 
      mBitsPerChannel: 32  } 
     cookie: {(null)} 
     ACL: {(null)} 
     FormatList Array: {(null)} 
    } 
    extensions: {(null)} 
} 

Le problème est que le serveur que je veux envoyer les données à ne pas attendre 32 flotteurs de bits mais 16 bits non signés ints. Je pense que je dois changer le mFormatFlags. Est-ce que quelqu'un sait comment je peux faire cela et quelle valeur serait la bonne?

Le flux d'octets résultant doit être équivalent à celui que je reçois sur Android à l'aide

AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLES_PER_SECOND, 
      AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 
      recordSegmentSizeBytes); 

J'ai essayé ceci:

let cfmt = AVAudioCommonFormat.pcmFormatInt16 
     inputNode.inputFormat(forBus: bus) = AVAudioFormat(commonFormat: cfmt, sampleRate: 16000.0, channels: 1, interleaved: false) 

mais a obtenu cette erreur

Cannot assign to value: function call returns immutable value

Toutes les idées ?

Répondre

3

Oh mon dieu, je pense que j'ai compris. J'étais trop aveugle pour voir que vous pouvez spécifier le format du rappel installTap. Cela semble fonctionner

let audioEngine = AVAudioEngine() 

func startRecording() { 
    let inputNode = audioEngine.inputNode! 
    let bus = 0 

    let format = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 16000.0, channels: 1, interleaved: false) 

    inputNode.installTap(onBus: bus, bufferSize: 2048, format: format) { // inputNode.inputFormat(forBus: bus) 
     (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in 

     let values = UnsafeBufferPointer(start: buffer.int16ChannelData![0], count: Int(buffer.frameLength)) 
     let arr = Array(values) 
     print(arr) 
    } 


    audioEngine.prepare() 
    do { 
     try audioEngine.start() 
    } catch { 
     print("Error info: \(error)") 
    } 
} 
+0

ce qui rend l'accident dans le code: ERREUR: [0x3b49de40]> avae> AVAudioIONodeImpl.mm:884: SetOutputFormat: condition requise est faux: format.sampleRate == hwFormat.sampleRate si vous avez n'importe quel sol envoyer –