質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

受付中

ipad同士でマイクから入力された音声で通話したい

nu-
nu-

総合スコア0

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0回答

0評価

0クリップ

2閲覧

投稿2018/05/02 07:18

実現したいこと

作成しているアプリの機能の一部で、ipadのマイクから入力された音声で、リアルタイム通話をする
機能を作成しています。
マイクからの音声は、AVAudioEngineを使用しています。
音声データはData型に変換後、UDP通信を使用し送信しています。

現在、マイクから入力された音声をUDP通信で送信し受信するところまではできていると思うのですが、
受け取ったデータを再生する方法がわかりません。

試したこと

受信したData型をAVAudioPCMBufferに変換しAVAudioEngineで再生しようとしてみたのですが
下記のようなエラーがでてしまいアプリが落ちてしまいます。
また、この方法で試してはみたのですが、データを受信するたびにAngineを止めているため音声をうまく再生できた場合でも
音が途切れてしまうような気がします。

ソースコードの一部を貼らせていただきます。
長くなり申し訳ございませんが、
再生するための方法やアドバイスをいただけませんでしょうか。
###環境
言語:Swift4
Xcode:9.2
プログラムの実行は、シュミレータを使用しています。

エラーメッセージ

2018-05-02 15:07:35.508183+0900 AudioConnectTest[3614:125779] AUBase.cpp:832:DispatchSetProperty: ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat 2018-05-02 15:07:35.508687+0900 AudioConnectTest[3614:125779] [avae] AVAEInternal.h:124:_AVAE_CheckSuccessAndNoNSError: [AUInterface.mm:512:SetFormat: ([[busArray objectAtIndexedSubscript:(NSUInteger)element] setFormat:format error:&nsErr])] returned false, error Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)" 2018-05-02 15:07:35.512176+0900 AudioConnectTest[3614:125779] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: '[[busArray objectAtIndexedSubscript:(NSUInteger)element] setFormat:format error:&nsErr]: returned false, error Error Domain=NSOSStatusErrorDomain Code=-10868 "(null)"' *** First throw call stack: ( 0 CoreFoundation 0x000000010530312b __exceptionPreprocess + 171 1 libobjc.A.dylib 0x0000000103efef41 objc_exception_throw + 48 2 CoreFoundation 0x00000001053082f2 +[NSException raise:format:arguments:] + 98 3 AVFAudio 0x00000001142384fe _Z19AVAE_RaiseExceptionP8NSStringz + 158 4 AVFAudio 0x000000011429b596 _Z30_AVAE_CheckSuccessAndNoNSErrorPKciS0_S0_bP7NSError + 472 5 AVFAudio 0x000000011429b3b1 _ZN17AUInterfaceBaseV39SetFormatEbjP13AVAudioFormat + 147 6 AVFAudio 0x0000000114293913 _ZN21AVAudioPlayerNodeImpl15SetOutputFormatEmP13AVAudioFormat + 25 7 AVFAudio 0x000000011422d790 _ZN18AVAudioEngineGraph8_ConnectEP19AVAudioNodeImplBaseS1_jjP13AVAudioFormat + 1664 8 AVFAudio 0x0000000114297814 _ZN17AVAudioEngineImpl7ConnectEP11AVAudioNodeS1_mmP13AVAudioFormat + 194 9 AVFAudio 0x000000011429787b -[AVAudioEngine connect:to:format:] + 83 10 AudioConnectTest 0x000000010344012b _T016AudioConnectTest0A5UnittC13playSineWave3ySo16AVAudioPCMBufferC8audiobuf_tF + 1211 11 AudioConnectTest 0x000000010343d72a _T016AudioConnectTest0A5UnittC9udpSocketySo011GCDAsyncUdpF0C_10Foundation4DataV10didReceiveAI11fromAddressypSg17withFilterContexttF + 202 12 AudioConnectTest 0x000000010343d95f _T016AudioConnectTest0A5UnittC9udpSocketySo011GCDAsyncUdpF0C_10Foundation4DataV10didReceiveAI11fromAddressypSg17withFilterContexttFTo + 383 13 CocoaAsyncSocket 0x00000001037826cc __72-[GCDAsyncUdpSocket notifyDidReceiveData:fromAddress:withFilterContext:]_block_invoke + 76 14 libdispatch.dylib 0x000000010987e2f7 _dispatch_call_block_and_release + 12 15 libdispatch.dylib 0x000000010987f33d _dispatch_client_callout + 8 16 libdispatch.dylib 0x000000010988a5f9 _dispatch_main_queue_callback_4CF + 628 17 CoreFoundation 0x00000001052c5e39 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 18 CoreFoundation 0x000000010528a462 __CFRunLoopRun + 2402 19 CoreFoundation 0x0000000105289889 CFRunLoopRunSpecific + 409 20 GraphicsServices 0x000000010aec49c6 GSEventRunModal + 62 21 UIKit 0x00000001057815d6 UIApplicationMain + 159 22 AudioConnectTest 0x000000010344a647 main + 55 23 libdyld.dylib 0x00000001098fbd81 start + 1 24 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException

該当のソースコード

宣言部分

swift

var audioEngine : AVAudioEngine! var audioFile : AVAudioFile! var audioPlayer : AVAudioPlayerNode! var outref: ExtAudioFileRef? var audioFilePlayer: AVAudioPlayerNode! var mixer : AVAudioMixerNode! var filePath : String? = nil var isPlay = false var isRec = false var captureSession = AVCaptureSession() var audioData:AVCaptureAudioDataOutput! var audioEngine1 : AVAudioEngine! var audioFilePlayer1: AVAudioPlayerNode! var mixer1 : AVAudioMixerNode! let audioEngine2 = AVAudioEngine() let player = AVAudioPlayerNode() var sinFlg = false

音声データ受信と再生部分

swift

//音声データ受信 func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?){ let convertPcmData = toPCMBuffer(data: data as NSData)//受信したデータをPCMBufferに変換 audioPlay(audiobuf: convertPcmData)//再生 } //再生 func audioPlay(audiobuf:AVAudioPCMBuffer) { let format2 = AVAudioFormat( commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 8000.0, channels: 1, interleaved: false) if (audioEngine2.isRunning) {//2回目以降受信した場合は一度止めてから再生する。 audioEngine2.stop() audioEngine2.reset() } if(!sinFlg){ sinFlg = true // オーディオエンジンにプレイヤーをアタッチ audioEngine2.attach(player) } let mixer = audioEngine2.mainMixerNode audioEngine2.connect(player, to: mixer, format: format2)//☆ここで上記のエラーが出てアプリが落ちてしまいます。 player.scheduleBuffer(audiobuf) { print("Play completed") } do { // エンジンを開始 try audioEngine2.start() // 再生 player.play() } catch let error { print(error) } }

マイクからの音声データ取得部分

swift

func startRecord() { let audioF = audioFilePlayer.outputFormat(forBus: 0) let asdf = audioF.channelCount let fasd = audioF.channelLayout let wre = audioF.sampleRate self.filePath = nil self.isRec = true try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord) try! AVAudioSession.sharedInstance().setActive(true) let format = AVAudioFormat( commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 44100.0, channels: 1, interleaved: true) self.audioEngine.connect(self.audioEngine.inputNode, to: self.mixer, format: format) //データ変換用フォーマット let downFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 8000.0, channels: 1, interleaved: true) audioEngine.inputNode.installTap(onBus: 0, bufferSize: AVAudioFrameCount((format?.sampleRate)! * 0.1), format: format, block: { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in //音声データを取得してサンプリングレートを8000kHに変換 let converter = AVAudioConverter.init(from: format!, to: downFormat!) let newbuffer = AVAudioPCMBuffer(pcmFormat: downFormat!, frameCapacity: AVAudioFrameCount((downFormat?.sampleRate)! * 0.1)) let inputBlock : AVAudioConverterInputBlock = { (inNumPackets, outStatus) -> AVAudioBuffer? in outStatus.pointee = AVAudioConverterInputStatus.haveData let audioBuffer : AVAudioBuffer = buffer return audioBuffer } var error : NSError? converter?.convert(to: newbuffer!, error: &error, withInputFrom: inputBlock) _ = ExtAudioFileWrite(self.outref!, (newbuffer?.frameLength)!, (newbuffer?.audioBufferList)!) let test = self.toNSData(PCMBuffer: newbuffer!)//PCMBufferからNSData型に変換 self.sendData(data: test as Data)//NSDataからData型に変換してUDP通信で送信 }) try! self.audioEngine.start() }

データ変換部分

swift

func toNSData(PCMBuffer: AVAudioPCMBuffer) -> NSData {//PCMBufferをDataに変換 let channelCount = 1 // given PCMBuffer channel count is 1 var channels = UnsafeBufferPointer(start: PCMBuffer.int16ChannelData, count: channelCount) var ch0Data = NSData(bytes: channels[0], length:Int(PCMBuffer.frameCapacity * PCMBuffer.format.streamDescription.pointee.mBytesPerFrame)) return ch0Data } func toPCMBuffer(data: NSData) -> AVAudioPCMBuffer {//データをPCMBufferに変換 let audioFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 8000, channels: 1, interleaved: true) // given NSData audio format var PCMBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat!, frameCapacity: UInt32(data.length) / (audioFormat?.streamDescription.pointee.mBytesPerFrame)!) PCMBuffer?.frameLength = (PCMBuffer?.frameCapacity)! let channels = UnsafeBufferPointer(start: PCMBuffer?.int16ChannelData, count: Int(PCMBuffer!.format.channelCount)) data.getBytes(UnsafeMutableRawPointer(channels[0]) , length: data.length) return PCMBuffer! }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています