質問するログイン新規登録

質問編集履歴

4

2017/11/12 02:01

投稿

退会済みユーザー
title CHANGED
File without changes
body CHANGED
File without changes

3

参考リンク追加

2017/11/12 02:01

投稿

退会済みユーザー
title CHANGED
@@ -1,1 +1,1 @@
1
- [Swift]m4aからwavへ音声変換行いたい
1
+ [Swift]ExtAudioFileOpenURL実行時エラー解決したい
body CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  [Swift3でCore Audioを使用した音声ファイル変換 - Voicy Tech Blog](http://voicetech.hatenablog.com/entry/2017/06/07/225127)
10
10
  [audio - iOS Code to Convert m4a to WAV - Stack Overflow](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)
11
+ [avAudioPlayer OSStatus error 2003334207 | Apple Developer Forums](https://forums.developer.apple.com/thread/5278)
11
12
 
12
13
  ###実現したいこと
13
14
 
@@ -55,26 +56,21 @@
55
56
  print("<--- 03")
56
57
 
57
58
 
58
- /// MARK: 変換先wavファイルをひらく
59
-
60
- // 変換先のoutput.wavを指すURL
61
- let toUrl = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("output.wav"))
62
-
63
59
  // wavファイル情報
64
60
  var outASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size)
65
61
  var wavFormat = AudioStreamBasicDescription()
66
- wavFormat.mFormatID = kAudioFormatMPEG4AAC
62
+ wavFormat.mFormatID = kAudioFormatLinearPCM
67
63
  wavFormat.mSampleRate = 44100.0
68
64
  wavFormat.mChannelsPerFrame = 1
69
65
  AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, nil, &outASBDSize, &wavFormat)
70
66
 
71
67
  // wavファイルファイルを開く
72
68
  status = ExtAudioFileCreateWithURL(outFileUrl as CFURL,
73
- kAudioFileM4AType,
69
+ kAudioFormatLinearPCM,
74
- &wavFormat,
70
+ &wavFormat,
75
- nil,
71
+ nil,
76
- AudioFileFlags.eraseFile.rawValue,
72
+ AudioFileFlags.eraseFile.rawValue,
77
- &outFile)
73
+ &outFile)
78
74
  print("---> 04")
79
75
  print(status)
80
76
  print("<--- 04")
@@ -85,9 +81,9 @@
85
81
 
86
82
  // 書き込みプロパティ設定
87
83
  status = ExtAudioFileSetProperty(outFile!,
88
- kExtAudioFileProperty_ClientDataFormat,
84
+ kExtAudioFileProperty_ClientDataFormat,
89
- inASBDSize,
85
+ inASBDSize,
90
- &inFormat)
86
+ &inFormat)
91
87
  print("---> 05")
92
88
  print(status)
93
89
  print("<--- 05")

2

参考URLの追記

2017/11/10 16:35

投稿

退会済みユーザー
title CHANGED
File without changes
body CHANGED
@@ -4,8 +4,10 @@
4
4
 
5
5
  アプリ内で、`m4a`から`wav`への音声変換を行おうとしています。
6
6
 
7
- [Stack Overflow@MScottWaller氏の投稿](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)を参考にしています。
7
+ 以下記事を参考にしています。
8
8
 
9
+ [Swift3でCore Audioを使用した音声ファイル変換 - Voicy Tech Blog](http://voicetech.hatenablog.com/entry/2017/06/07/225127)
10
+ [audio - iOS Code to Convert m4a to WAV - Stack Overflow](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)
9
11
 
10
12
  ###実現したいこと
11
13
 

1

モジュールの追加、ソースコード修正

2017/11/10 16:25

投稿

退会済みユーザー
title CHANGED
File without changes
body CHANGED
@@ -7,17 +7,6 @@
7
7
  [Stack Overflowの@MScottWaller氏の投稿](https://stackoverflow.com/questions/35738133/ios-code-to-convert-m4a-to-wav/36001262#36001262)を参考にしています。
8
8
 
9
9
 
10
- ###発生している問題・エラーメッセージ
11
-
12
- `convertAudio`メソッドの`ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)`にて、
13
-
14
- **Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value**
15
-
16
- というエラーが表示され、アプリが落ちます。
17
-
18
- `inFile`に`nil`が入っていることが原因のエラーだということはわかっています。
19
-
20
-
21
10
  ###実現したいこと
22
11
 
23
12
  `convertAudio`メソッドを上手く動作させて、音声変換を行いたいです。
@@ -28,89 +17,109 @@
28
17
  - 音声変換メソッド
29
18
 
30
19
  ```swift
20
+ import AVKit
21
+ import AVFoundation
22
+ import AudioToolbox
23
+ import CoreAudioKit
24
+
25
+ /* m4a -> wav の音声変換 */
31
- func convertAudio(_ url: URL, _ outputURL: URL) {
26
+ func convertAudio(_ inFileUrl: URL, _ outFileUrl: URL) {
32
- var error : OSStatus = noErr
33
- var outFile: ExtAudioFileRef? = nil
34
- var inFile : ExtAudioFileRef? = nil
35
27
 
36
- var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
28
+ // ステータス
37
- var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
29
+ var status: OSStatus = noErr
38
30
 
31
+ // 変換元のm4aファイルを開く
32
+ var inFile: ExtAudioFileRef?
39
- ExtAudioFileOpenURL(url as CFURL, &inFile)
33
+ status = ExtAudioFileOpenURL(inFileUrl as CFURL, &inFile)
34
+ print("---> 01")
35
+ print(status)
36
+ print("<--- 01")
40
37
 
41
- var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))
42
-
43
- /* *** ERROR HERE!! *** */
38
+ // 変換先のwavファイルを開く
39
+ var outFile: ExtAudioFileRef?
44
- ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)
40
+ status = ExtAudioFileOpenURL(outFileUrl as CFURL, &outFile)
41
+ print("---> 02")
42
+ print(status)
43
+ print("<--- 02")
45
44
 
45
+ // 出力するwavファイルの情報を取得
46
- dstFormat.mSampleRate = 44100 //Set sample rate
46
+ var inASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size)
47
- dstFormat.mFormatID = kAudioFormatLinearPCM
47
+ var inFormat = AudioStreamBasicDescription()
48
- dstFormat.mChannelsPerFrame = 1
49
- dstFormat.mBitsPerChannel = 16
50
- dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
51
- dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
52
- dstFormat.mFramesPerPacket = 1
53
- dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked |
54
- kAudioFormatFlagIsSignedInteger
55
48
 
56
- // Create destination file
49
+ /* *** ERROR!! *** */
50
+ status = ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &inASBDSize, &inFormat)
57
- error = ExtAudioFileCreateWithURL(
51
+ print("---> 03")
58
- outputURL as CFURL,
59
- kAudioFileWAVEType,
60
- &dstFormat,
61
- nil,
62
- AudioFileFlags.eraseFile.rawValue,
63
- &outFile)
52
+ print(status)
64
- print("Error 1 in convertAudio: (error.description)")
53
+ print("<--- 03")
65
54
 
66
- error = ExtAudioFileSetProperty(inFile!,
67
- kExtAudioFileProperty_ClientDataFormat,
68
- thePropertySize,
69
- &dstFormat)
70
- print("Error 2 in convertAudio: (error.description)")
71
55
 
72
- error = ExtAudioFileSetProperty(outFile!,
73
- kExtAudioFileProperty_ClientDataFormat,
56
+ /// MARK: 変換先wavファイルをひらく
74
- thePropertySize,
75
- &dstFormat)
76
- print("Error 3 in convertAudio: (error.description)")
77
57
 
78
- let bufferByteSize : UInt32 = 32768
79
- var srcBuffer = [UInt8](repeating: 0, count: 32768)
80
- var sourceFrameOffset : ULONG = 0
58
+ // 変換先のoutput.wavを指すURL
59
+ let toUrl = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("output.wav"))
81
60
 
61
+ // wavファイル情報
62
+ var outASBDSize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size)
63
+ var wavFormat = AudioStreamBasicDescription()
64
+ wavFormat.mFormatID = kAudioFormatMPEG4AAC
65
+ wavFormat.mSampleRate = 44100.0
66
+ wavFormat.mChannelsPerFrame = 1
67
+ AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, nil, &outASBDSize, &wavFormat)
68
+
69
+ // wavファイルファイルを開く
70
+ status = ExtAudioFileCreateWithURL(outFileUrl as CFURL,
71
+ kAudioFileM4AType,
72
+ &wavFormat,
73
+ nil,
74
+ AudioFileFlags.eraseFile.rawValue,
75
+ &outFile)
76
+ print("---> 04")
77
+ print(status)
78
+ print("<--- 04")
79
+
80
+
81
+
82
+ /// MARK: 変換ルールの指定
83
+
84
+ // 書き込みプロパティ設定
85
+ status = ExtAudioFileSetProperty(outFile!,
86
+ kExtAudioFileProperty_ClientDataFormat,
87
+ inASBDSize,
88
+ &inFormat)
89
+ print("---> 05")
90
+ print(status)
91
+ print("<--- 05")
92
+
93
+
94
+ /// MARK: 変換処理
95
+
96
+ // バッファ作成
97
+ var readFrameSize: UInt32 = 1024 // 一度に読み込むフレーム数
98
+ var bufferSize = readFrameSize * inFormat.mBytesPerPacket
99
+ var buffer: UnsafeMutableRawPointer = malloc(Int(bufferSize))
100
+ defer { free(buffer) }
101
+
102
+ var audioBuffer = AudioBufferList()
103
+ audioBuffer.mNumberBuffers = 1
104
+ audioBuffer.mBuffers.mNumberChannels = inFormat.mChannelsPerFrame
105
+ audioBuffer.mBuffers.mDataByteSize = bufferSize
106
+ audioBuffer.mBuffers.mData = buffer
107
+
108
+ // ファイルを読み込んで出力
82
- while(true){
109
+ while (true) {
83
- var fillBufList = AudioBufferList(
84
- mNumberBuffers: 1,
85
- mBuffers: AudioBuffer(
86
- mNumberChannels: 2,
87
- mDataByteSize: UInt32(srcBuffer.count),
88
- mData: &srcBuffer
89
- )
90
- )
91
- var numFrames : UInt32 = 0
110
+ // WAVファイル読み込み
92
-
93
- if(dstFormat.mBytesPerFrame > 0){
94
- numFrames = bufferByteSize / dstFormat.mBytesPerFrame
95
- }
96
-
97
- error = ExtAudioFileRead(inFile!, &numFrames, &fillBufList)
111
+ ExtAudioFileRead(inFile!, &readFrameSize, &audioBuffer)
98
- print("Error 4 in convertAudio: (error.description)")
99
-
100
- if(numFrames == 0){
112
+ // 読み込むデータがなくなれば終了
101
- error = noErr;
102
- break;
103
- }
104
-
105
- sourceFrameOffset += numFrames
113
+ if readFrameSize <= 0 { break }
114
+ // AACファイル書き込み
106
- error = ExtAudioFileWrite(outFile!, numFrames, &fillBufList)
115
+ ExtAudioFileWrite(outFile!, readFrameSize, &audioBuffer)
107
- print("Error 5 in convertAudio: (error.description)")
108
116
  }
117
+
109
118
 
119
+ /// MARK: ファイルを閉じる
120
+
121
+ ExtAudioFileDispose(inFile!)
110
- error = ExtAudioFileDispose(outFile!)
122
+ ExtAudioFileDispose(outFile!)
111
- print("Error 6 in convertAudio: (error.description)")
112
- error = ExtAudioFileDispose(inFile!)
113
- print("Error 7 in convertAudio: (error.description)")
114
123
  }
115
124
  ```
116
125
 
@@ -126,5 +135,33 @@
126
135
  ```
127
136
 
128
137
 
138
+ ###発生している問題・エラーメッセージ
139
+
140
+ `convertAudio`メソッドの`ExtAudioFileGetProperty(inFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)`にて、
141
+
142
+ **Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value**
143
+
144
+ というエラーが表示され、アプリが落ちます。
145
+
146
+ `inFile`に`nil`が入っていることが原因のエラーだということはわかっています。
147
+
148
+
149
+ - コンソール
150
+
151
+ ```
152
+ 2017-11-11 01:17:00.088640+0900 enPiT2SUProduct[34488:655917] 231: EXCEPTION (2003334207): "open audio file"
153
+ ---> 01
154
+ 2003334207
155
+ <--- 01
156
+ 2017-11-11 01:17:00.089532+0900 enPiT2SUProduct[34488:655917] 231: EXCEPTION (2003334207): "open audio file"
157
+ ---> 02
158
+ 2003334207
159
+ <--- 02
160
+ // ここでアプリが落ちる
161
+ ```
162
+
163
+
164
+
165
+
129
166
  ###考えたこと
130
167
  音声変換の途中で、 `ExtAudioFileOpenURL(url as CFURL, &inFile)`という処理を行ったときに、`url`が指す音声ファイルを`inFile`にセットすれば、とりあえず、次の処理に進めるのではないかと考えました。