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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

4回答

4755閲覧

音楽ファイルからバイナリデータが出力できない

Jidousya_364

総合スコア43

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2017/03/23 05:03

編集2017/03/24 06:25
class ViewController: UIViewController { let fileManager = FileManager() var audioRecorder: AVAudioRecorder? //録音設定 var audioPlayer: AVAudioPlayer? //var audioFile:AVAudioFile! //読み込んだオーディオファイルの情報を格納し保持する let fileName = "OTO1.mp3 " override func viewDidLoad() { super.viewDidLoad() self.setupAudioRecorder() } func audiostatas(sender: AnyObject) { //var audioClass = AudioDataClass(address:documentFilePath().path) var audioClass = AudioDataClass(address: Bundle.main.path(forResource: "0322", ofType: "wav")!) //読み込み audioClass.loadAudioData() } func pushRecordButton(sender: AnyObject) { audioRecorder?.record() } // 録音するファイルのパスを取得(録音時、再生時に参照) // swift2からstringByAppendingPathComponentが使えなくなったので少し面倒 func documentFilePath()-> URL { let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask) as [NSURL] let dirURL = urls[0] return dirURL.appendingPathComponent(fileName)! } func setupAudioRecorder() { // 再生と録音機能をアクティブにする let session = AVAudioSession.sharedInstance() try! session.setCategory(AVAudioSessionCategoryPlayAndRecord) try! session.setActive(true) let recordSetting : [String : AnyObject] = [ AVEncoderAudioQualityKey : AVAudioQuality.min.rawValue as AnyObject, AVEncoderBitRateKey : 16 as AnyObject, AVNumberOfChannelsKey: 2 as AnyObject, AVSampleRateKey: 44100.0 as AnyObject, AVLinearPCMIsBigEndianKey: true as AnyObject// ビックエンディアン ] do { try audioRecorder = AVAudioRecorder(url: self.documentFilePath() as URL, settings: recordSetting) } catch { print("初期設定でerror出たよ(-_-;)") } } }

swift

1import Foundation 2import AVFoundation 3 4class AudioDataClass{ 5 6 //object for audio file 7 var audioFile:AVAudioFile! //読み込んだオーディオファイルの情報を格納し保持する 8 9 //buffer for PCM data 便宜上AVAudioPCMBuffer型の変数を用意 10 //クラス外から実際にバイナリデータにアクセスする際はbufferプロパティを使う。 11 var PCMBuffer:AVAudioPCMBuffer! 12 13 // audio file address 14 var address:String 15 16 //オーディオのバイナリデータを格納するためのbuffer, マルチチャンネルに対応するため、二次元配列になっています。 17 var buffer:[[Float]]! = Array<Array<Float>>() 18 19 //オーディオデータの情報 20 var samplingRate:Double? 21 var nChannel:Int? 22 var nframe:Int? 23 24 //initializer 25 init(address:String){ 26 self.address = address 27 } 28 29 30 func loadAudioData(){ 31 32 print(buffer) 33 34 //create AVAudioFile 35 //error handling do catch 36 do{ 37 38 //オーディオファイルを読み込み、データをaudioFileに格納 39 self.audioFile = try AVAudioFile(forReading: NSURL(fileURLWithPath: self.address) as URL) 40 //get samplingRate 41 self.samplingRate = self.audioFile.fileFormat.sampleRate 42 //get channel 43 self.nChannel = Int(self.audioFile.fileFormat.channelCount) 44 45 }catch{ 46 //読み込み失敗 47 print("Error : loading audio file \(self.address) failed.") 48 } 49 50 //もしオーディオファイル読み込みが成功していたら、バイナリデータを取得する 51 if(self.audioFile != nil){ 52 53 //get frame length 54 self.nframe = Int(self.audioFile.length) 55 56 //allocate 割り振る 57 self.PCMBuffer = AVAudioPCMBuffer(pcmFormat: self.audioFile.processingFormat, frameCapacity: AVAudioFrameCount(self.nframe!)) 58 59 //error handling 60 do{ 61 //audioFileから、PCMBufferにバイナリデータを取得する 62 try self.audioFile.read(into: self.PCMBuffer) 63 64 //各チャンネル毎にバイナリデータをbufferに追加する 65 for i in 0..<self.nChannel!{ 66 67 let buf:[Float] = Array(UnsafeMutableBufferPointer(start:self.PCMBuffer.floatChannelData![i], count:self.nframe!)) 68 69 self.buffer.append(buf) 70 } 71 72 for i in 0..<self.nChannel!{ 73 for j in 0..<self.nframe!{ 74 print(self.buffer[i][j]) 75 } 76 print("") 77 } 78 }catch{ 79 print("loading audio data failed.") 80 } 81 } 82 } 83

http://qiita.com/programanx1/items/8912e60843bd824d74ce
私はここのサイトを参考にしてAudioRecoderで録音したWAVE形式の音楽ファイルをloadAudioData内でバイナリデータを見ようと思ったのですが

for i in 0..<self.nChannel!{ for j in 0..<self.nframe!{ print(self.buffer[i][j]) } print("") }

self.audioFile = try AVAudioFile(forReading: NSURL(fileURLWithPath: self.address) as URL)

self.audioFile = try AVAudioFile(forReading: NSURL(fileURLWithPath: self.address) as URL,commonFormat: AVAudioCommonFormat.pcmFormatInt16,interleaved: true)
に書き換え、
for i in 0..<1{
for j in 0..<self.nframe!{
print(String(self.buffer[i][j], radix: 16))
}
}

出力されるデータが以下のような形になってしまうのですがこの値がバイナリデータなのでしょうか?
-0.00427246
-0.0166626
-0.0283508
-0.0391541
-0.0498657
-0.0618896
-0.0748596
-0.0875854
-0.0992737
-0.110352
-0.122406
-0.135529
-0.148499
-0.160095
-0.170746
-0.18161
-0.193207
-0.204956
-0.215881
-0.225922
-0.236664
-0.24823
-0.259766
-0.270142
-0.278961
-0.288513
-0.300049
-0.312592

追記
self.audioFile = try AVAudioFile(forReading: NSURL(fileURLWithPath: self.address) as URL)

self.audioFile = try AVAudioFile(forReading: NSURL(fileURLWithPath: self.address) as URL,commonFormat: AVAudioCommonFormat.pcmFormatInt16,interleaved: true)
に書き換えたところ

for i in 0..<1{ for j in 0..<self.nframe!{ print(String(self.buffer[i][j], radix: 16)) } } }

-140,-546,-929,-1283,-1634,-2028
が出力され、

16進数になっていないのかなと思ったので変換したら

for i in 0..<1{ for j in 0..<self.nframe!{ print(String(self.buffer[i][j], radix: 16)) } } }

-8c,-222,-3a1,-503,-662,-7ec,-995,-b36
になりました

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

バイナリデータが何を意味するのか分かりませんが、質問者さんがみているのは、
リニアPCMの32bit float値([-1.0, 1.0])です。

AVAudioFileクラスの

swift

1public init(forReading fileURL: URL) throws

のコメントにこう書かれています。

swift

1/* This opens the file for reading using the standard format (deinterleaved floating point). */

standard format(floating point)とは、リニアPCMの32bit floatのことです。

AVAudioFileはフォーマットのコンバーターを内蔵しています。
指定したファイルがmp3,aif,wavなんであろうと、ビット数が16,24,32どれであろうと、
init(forReading fileURL:URL)で初期化すると、

swift

1open func read(into buffer: AVAudioPCMBuffer) throws

で読み出したデータは勝手に変換されてリニアPCMの32bit floatになります。

投稿2017/03/23 13:55

pebble8888

総合スコア390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

wavファイルデータの様なので、バイナリーではなく、リニアPCMのfloat値と思われます。

WAVEファイルの構造

で、ヘッダと16,24,32bit音声データの配置を把握して、
16,24,32bit音声データの「符号」「指数」「仮数」を把握して、
バイナリエディタで見れば、合ってるかどうかが分かります。
16,24bitの「符号」「指数」「仮数」はどこかで、探してみてください。

32bitについて、興味深い記事(?)がありましたので、URLを記しておきます。

第572回:ハイレゾで注目の「32bit-float」で、オーディオの常識が変わる?

投稿2017/03/23 06:35

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

使ったことないので知りませんが、

swift

1 let buf:[Float] = Array(UnsafeMutableBufferPointer(start:self.PCMBuffer.floatChannelData[i], count:self.nframe!))

floatChannelDataで取得しているようなのでfloat値になっているのでしょう。
int16Channel​Dataint32Channel​Dataを使えば整数値で取得出来るような気がします。


今のままでも、このfloat値が±1.0だと仮定すると、

swift

1print(String(Int(self.buffer[i][j] * 0x8000), radix: 16))

こうすれば±0x8000で表示されてバイナリデータっぽくなりますw


【追記されたInt16のデータについて】

-0.00427246 * 0x8000 = -139.99996928 ≒ -140 = -0x008c -0.0166626 * 0x8000 = -546.0000768 ≒ -546 = -0x0222 -0.0283508 * 0x8000 = -928.9990144 ≒ -929 = -0x03a1 (以下略)

floatだろうがInt16だろうが、スケールが違うだけで同じ値なのですよ。

投稿2017/03/23 05:34

編集2017/03/24 06:40
fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jidousya_364

2017/03/27 23:45

そういうことでしたか では上の方が張っていくださったhttp://www.graffiti.jp/pc/p030506a.htmのような形式では取れないのでしょうか?
fuzzball

2017/03/27 23:54 編集

16bitならInt16でいいと思いますが。8bitならInt16の上位バイトだけ使えばいいです。 あと、どうでもいいことですが、並べ替え出来るので「上の方」って書くのは無意味です。 きちんと名前で書きましょう。
Jidousya_364

2017/03/28 01:01 編集

Houraijilcさんの貼ってくださったものといったほうがよかったですね ありがとうございました。自分の求めるものができなさそうなのでもう一度質問させていただきます 
guest

0

AVAudioFileはフォーマットのコンバーターを内蔵しています。

とのことなので、
swiftでバイナリファイルの読み書きを行いたい
で、ファイルを読み、先の、ヘッダー情報から、wavのリニアPCMのバイト数を判断して、音声データを、バイナリーで読めば良いと思います。

投稿2017/03/28 20:48

編集2017/03/28 22:40
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問