最近大型Updateのあった*1AppleのGarage Bandをポチポチ触っていたのですが、エクスポートしたオーディオファイルは非圧縮AIFFを選択してもM4Aファイルとして書き出されることを知りました。同様にiOSプラットフォームで動作するYAMAHA Mobile Sequencerや、KORG GadgetなどはWAVで書き出せるのに、Appleらしいというかなんというか。
で、書き出されたファイルをPCのアプリケーションで取り扱おうとしても、M4Aには対応していないことも多く取り扱いが不便なのです。というわけで標準的なWAVファイル形式に変換することにしました。
SoX編
M4A --> WAV
単純に変換するだけなら以下のように入力ファイルと出力ファイルを指定すれば変換できます*2。
>sox -V3 INPUT.m4a OUTPUT.wav sox: SoX v14.4.2 sox INFO formats: detected file format type `aiff' sox INFO aiff: Unity MIDI Note: 0 sox INFO aiff: Low MIDI Note: 0 sox INFO aiff: High MIDI Note: 0 Input File : 'INPUT.m4a' (aiff) Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:01:30.00 = 3969000 samples = 6750 CDDA sectors File Size : 15.9M Bit Rate : 1.41M Sample Encoding: 16-bit Signed Integer PCM Endian Type : big Reverse Nibbles: no Reverse Bits : no Comment : ' Creator: Logic' Output File : 'OUTPUT.wav' Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:01:30.00 = 3969000 samples = 6750 CDDA sectors Sample Encoding: 16-bit Signed Integer PCM Endian Type : little Reverse Nibbles: no Reverse Bits : no Comment : ' Creator: Logic' sox INFO sox: effects chain: input 44100Hz 2 channels sox INFO sox: effects chain: output 44100Hz 2 channels
標準出力を眺めてみると、サンプリングレート44.1kHz、量子化ビット数16bitでステレオ2chのビッグエンディアンのAIFFとしてGarage Bandの出力ファイルは生成されているようです。変換後もそのままのサンプリングレートと量子化ビット数を維持しつつ、リトルエンディアンのWAVファイルとして記録されていますので、非圧縮AIFFを無劣化でWAVに変換できています。
ところで"Creator: Logic"なんてメタデータも付与されているのが目に付きます。割とどうでもいいですが、このメタデータを変換後のWAVファイルには引き継がないようにするには以下のようにcommentオプションを指定します。
>sox -Vs INPUT.m4a --comment "" OUTPUT.wav sox: SoX v14.4.2 sox INFO formats: detected file format type `aiff' sox INFO aiff: Unity MIDI Note: 0 sox INFO aiff: Low MIDI Note: 0 sox INFO aiff: High MIDI Note: 0 Input File : 'INPUT.m4a' (aiff) Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:01:30.00 = 3969000 samples = 6750 CDDA sectors File Size : 15.9M Bit Rate : 1.41M Sample Encoding: 16-bit Signed Integer PCM Endian Type : big Reverse Nibbles: no Reverse Bits : no Comment : ' Creator: Logic' sox INFO sox: Overwriting `OUTPUT.wav' Output File : 'OUTPUT.wav' Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:01:30.00 = 3969000 samples = 6750 CDDA sectors Sample Encoding: 16-bit Signed Integer PCM Endian Type : little Reverse Nibbles: no Reverse Bits : no sox INFO sox: effects chain: input 44100Hz 2 channels sox INFO sox: effects chain: output 44100Hz 2 channels
WAV --> M4A
SoXでは逆方向の変換(WAV→M4A)はできないようです。M4Aの書き出しには対応していないようで、以下のエラーメッセージが表示されてしまいます。
sox FAIL formats: no handler for file extension `m4a'
ffmpeg編
M4A --> WAV
SoXと同様に単純に変換するだけなら、以下のように入力ファイルと出力ファイルを指定すれば変換できます。
>ffmpeg -i INPUT.m4a OUTPUT.wav ffmpeg version N-75573-g1d0487f Copyright (c) 2000-2015 the FFmpeg developers built with gcc 4.9.3 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib libavutil 55. 2.100 / 55. 2.100 libavcodec 57. 3.100 / 57. 3.100 libavformat 57. 2.100 / 57. 2.100 libavdevice 57. 0.100 / 57. 0.100 libavfilter 6. 9.100 / 6. 9.100 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.100 / 2. 0.100 libpostproc 54. 0.100 / 54. 0.100 Input #0, aiff, from 'INPUT.m4a': Duration: 00:01:30.00, start: 0.000000, bitrate: 1411 kb/s Stream #0:0: Audio: pcm_s16be, 44100 Hz, stereo, s16, 1411 kb/s Output #0, wav, to 'OUTPUT.wav': Metadata: ISFT : Lavf57.2.100 Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s Metadata: encoder : Lavc57.3.100 pcm_s16le Stream mapping: Stream #0:0 -> #0:0 (pcm_s16be (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help size= 15504kB time=00:01:30.00 bitrate=1411.2kbits/s video:0kB audio:15504kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000491%
ffmpegの標準出力を眺めてみても、44.1kHz/16bit/Stereoのpcm_s16be形式のM4Aから、同一サンプリングレート、量子化ビット数、チャネル数のpcm_s16le形式のWAVに変換されたことが判ります。pcm_s16beがpcm_s16leに変わっていますが、beとかleと言っているのはBig EndianとLittle Endianを指しており、SoXの場合と同様にデータの並び順が変わっているだけで、無劣化です。
なお、ffmpegの場合は特に何も指定しなければメタデータは出力ファイルに引き継がれません。
WAV --> M4A
入出力を逆に指定すればWAVからM4Aに変換できますが、M4AからWAVに変換した時と同様に何のオプションも指定しないと以下のようにAACで圧縮されてしまいます。
>ffmpeg -i INPUT.wav OUTPUT.m4a ffmpeg version N-75573-g1d0487f Copyright (c) 2000-2015 the FFmpeg developers built with gcc 4.9.3 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib libavutil 55. 2.100 / 55. 2.100 libavcodec 57. 3.100 / 57. 3.100 libavformat 57. 2.100 / 57. 2.100 libavdevice 57. 0.100 / 57. 0.100 libavfilter 6. 9.100 / 6. 9.100 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.100 / 2. 0.100 libpostproc 54. 0.100 / 54. 0.100 Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, wav, from 'INPUT.wav': Duration: 00:01:30.00, bitrate: 1411 kb/s Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s Output #0, ipod, to 'OUTPUT.m4a': Metadata: encoder : Lavf57.2.100 Stream #0:0: Audio: aac (libvo_aacenc) (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 128 kb/s Metadata: encoder : Lavc57.3.100 libvo_aacenc Stream mapping: Stream #0:0 -> #0:0 (pcm_s16le (native) -> aac (libvo_aacenc)) Press [q] to stop, [?] for help size= 1423kB time=00:01:30.01 bitrate= 129.5kbits/s video:0kB audio:1407kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.129480%
M4AはMP4やMOVといった映像ファイルのコンテナ形式と同様に、オーディオデータのコンテナ形式でしかありません。オーディオのコーデック指定をしなかったため、ffmpegがM4Aの場合のデフォルトコーデックのAACで圧縮されてしまったわけです。非圧縮のAIFFでM4Aに変換するには以下のように指定します。
>ffmpeg -i INPUT.wav -f aiff -acodec pcm_s16be OUTPUT.m4a ffmpeg version N-75573-g1d0487f Copyright (c) 2000-2015 the FFmpeg developers built with gcc 4.9.3 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib libavutil 55. 2.100 / 55. 2.100 libavcodec 57. 3.100 / 57. 3.100 libavformat 57. 2.100 / 57. 2.100 libavdevice 57. 0.100 / 57. 0.100 libavfilter 6. 9.100 / 6. 9.100 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.100 / 2. 0.100 libpostproc 54. 0.100 / 54. 0.100 Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, wav, from 'INPUT.wav': Duration: 00:01:30.00, bitrate: 1411 kb/s Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s Output #0, aiff, to 'OUTPUT.m4a': Metadata: encoder : Lavf57.2.100 Stream #0:0: Audio: pcm_s16be (NONE / 0x454E4F4E), 44100 Hz, stereo, s16, 1411 kb/s Metadata: encoder : Lavc57.3.100 pcm_s16be Stream mapping: Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s16be (native)) Press [q] to stop, [?] for help size= 15504kB time=00:01:30.00 bitrate=1411.2kbits/s video:0kB audio:15504kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000340%
上記例ではGarage Bandの出力ファイルと同様にビッグエンディアンの指定をしましたが、リトルエンディアンにしたければacodec指定のpcm_s16beをpcm_s16leに変更すればいいです。
以上。