M4AをWAVに変換する(その逆も)

 最近大型Updateのあった*1AppleのGarage Bandをポチポチ触っていたのですが、エクスポートしたオーディオファイルは非圧縮AIFFを選択してもM4Aファイルとして書き出されることを知りました。同様にiOSプラットフォームで動作するYAMAHA Mobile Sequencerや、KORG GadgetなどはWAVで書き出せるのに、Appleらしいというかなんというか。
 で、書き出されたファイルをPCのアプリケーションで取り扱おうとしても、M4Aには対応していないことも多く取り扱いが不便なのです。というわけで標準的なWAVファイル形式に変換することにしました。

 以下、SoXを使う例と、ffmpegを使う例を記載します。
 

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に変更すればいいです。
 



以上。

*1:Logic由来のソフトウェアシンセサイザーのAlchemyが搭載されたものの、iPhone6/iPadAir2以降でなければ動作しないため、私にとっての恩恵は実はなかった

*2:"-V3"オプションは標準出力のメッセージレベル指定なので省略可能