LoginSignup
1
2

【CircuitPython】ValueError: fmtチャンクの後にdataチャンクが続かなければなりません

Posted at

0. はじめに

Raspberry Pi Pico で CircuitPython を使って、WAVファイルを再生するとき、『ValueError: fmtチャンクの後にdataチャンクが続かなければなりません』のエラーとなって再生できないWAVファイルが存在する。

このエラーの対応策を調べました。

WAVファイルの再生は、Adafruitのサイトで紹介されている、下記コードで確認。
(⭐️の箇所でエラーが起こる)

play.png

Adafruit CircuitPython 9.0.4 on 2024-04-16; Raspberry Pi Pico with rp2040

1. エラーの原因

一口に WAVファイルといっても、ファイルの中身(ファイルフォーマット)には、何パターンもあり、その一部のファイルフォーマットに対応していないことが原因のようです。

ネットに公開されているフリー音源や、オンラインのメディア変換(MP3→WAV)で作ったWAVファイルでも、このエラーになるファイルがあります。もちろん、普通に再生できるWAVファイルもあります。

これに関しては深追いはしていません。(コーデックの違い??)

2. 対応策

ffmpegコマンドでファイルを修復します(修復という表現が正しいのか分かりません)。

ffmpegコマンドに次のオプションを指定します。

ffmpeg -i "original.wav" -bitexact -acodec pcm_s16le -ac 2 -ar 16000 -map_metadata -1 "repaired.wav"

or

ffmpeg -i "original.mp3" -bitexact -acodec pcm_s16le -ac 2 -ar 16000 -map_metadata -1 "converted.wav"

モノラル音源の場合は、-ac 2-ac 1にする。

出典;

2.1 修復前後のファイルの違い

⓪大元の音源ファイル
$ ffmpeg -hide_banner -i hapyou2.mp3
[mp3 @ 0x11ce06400] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'hapyou2.mp3':
  Duration: 00:00:05.12, start: 0.000000, bitrate: 128 kb/s
  Stream #0:0: Audio: mp3 (mp3float), 44100 Hz, stereo, fltp, 128 kb/s
At least one output file must be specified
①オンラインオンバータで変換したWAVファイル(再生できない)
$ ffmpeg -hide_banner -i hapyou2.wav
[aist#0:0/pcm_s16le @ 0x122606120] Guessed Channel Layout: stereo
Input #0, wav, from 'hapyou2.wav':
  Metadata:
    encoder         : Lavf59.27.100
  Duration: 00:00:05.12, bitrate: 1411 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
At least one output file must be specified
②ffmpegで修復したWAVファイル(再生できる)
$ ffmpeg -hide_banner -i hapyou2.wav -bitexact -acodec pcm_s16le -ac 2 -ar 16000 -map_metadata -1 repaired.wav
[aist#0:0/pcm_s16le @ 0x12b6069d0] Guessed Channel Layout: stereo
Input #0, wav, from 'hapyou2.wav':
  Metadata:
    encoder         : Lavf59.27.100
  Duration: 00:00:05.12, bitrate: 1411 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to 'repaired.wav':
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, stereo, s16, 512 kb/s
      Metadata:
        encoder         : Lavc pcm_s16le
[out#0/wav @ 0x600003120540] video:0KiB audio:320KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.013428%
size=     320KiB time=00:00:05.12 bitrate= 512.1kbits/s speed= 826x    

$ ffmpeg -hide_banner -i repaired.wav
[aist#0:0/pcm_s16le @ 0x120e072c0] Guessed Channel Layout: stereo
Input #0, wav, from 'repaired.wav':
  Duration: 00:00:05.12, bitrate: 512 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, stereo, s16, 512 kb/s
At least one output file must be specified
③ffmpegで変換したWAVファイル(再生できる)
$ ffmpeg -hide_banner -i hapyou2.mp3 -bitexact -acodec pcm_s16le -ac 2 -ar 16000 -map_metadata -1 converted.wav
[mp3 @ 0x131e06d70] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'hapyou2.mp3':
  Duration: 00:00:05.12, start: 0.000000, bitrate: 128 kb/s
  Stream #0:0: Audio: mp3 (mp3float), 44100 Hz, stereo, fltp, 128 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mp3 (mp3float) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to 'converted.wav':
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, stereo, s16, 512 kb/s
      Metadata:
        encoder         : Lavc pcm_s16le
[out#0/wav @ 0x6000024f4600] video:0KiB audio:320KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.013428%
size=     320KiB time=00:00:05.12 bitrate= 512.1kbits/s speed= 678x    

$ ffmpeg -hide_banner -i converted.wav
[aist#0:0/pcm_s16le @ 0x13a607340] Guessed Channel Layout: stereo
Input #0, wav, from 'converted.wav':
  Duration: 00:00:05.12, bitrate: 512 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, stereo, s16, 512 kb/s
At least one output file must be specified

①の再生できないWAVファイルと、②③の再生できるWAVファイルのffmpeg情報から、サンプリング周波数(とビットレート)の違いが見て取れる。
では、サンプリング周波数44.1KHzのWAVファイルがエラーとなるのか確認したが、問題なく再生できた。サンプリング周波数がエラーの原因では無い。

④ffmpegで44.1KHzのWAVファイルに変換(再生できた)
$ ffmpeg -hide_banner -i hapyou2.mp3 -bitexact -acodec pcm_s16le -ac 2 -ar 44100 -map_metadata -1 converted441.wav
[mp3 @ 0x12cf054f0] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'hapyou2.mp3':
  Duration: 00:00:05.12, start: 0.000000, bitrate: 128 kb/s
  Stream #0:0: Audio: mp3 (mp3float), 44100 Hz, stereo, fltp, 128 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mp3 (mp3float) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to 'converted441.wav':
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
      Metadata:
        encoder         : Lavc pcm_s16le
[out#0/wav @ 0x600001d4c000] video:0KiB audio:882KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.004872%
size=     882KiB time=00:00:05.12 bitrate=1411.3kbits/s speed= 584x    

$ ffmpeg -hide_banner -i converted441.wav
[aist#0:0/pcm_s16le @ 0x147e072c0] Guessed Channel Layout: stereo
Input #0, wav, from 'converted441.wav':
  Duration: 00:00:05.12, bitrate: 1411 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
At least one output file must be specified
$ ffmpeg -version
ffmpeg version 7.0 Copyright (c) 2000-2024 the FFmpeg developers
built with Apple clang version 15.0.0 (clang-1500.3.9.4)

②③の再生できるWAVファイルの中身は同じかと想定したが、コンペアしてみたらそうではなかった。ファイルサイズは同じ。

$ cmp converted.wav repaired.wav
converted.wav repaired.wav differ: char 937, line 1

$ ls -ls converted.wav repaired.wav
648 -rw-r--r--  1 user_name  staff  327724  5 22 20:29 converted.wav
648 -rw-r--r--  1 user_name  staff  327724  5 22 20:38 repaired.wav

MicroPythonではエラーとならない

ちなみに、MicroPythonを使い、下記サイトのコードで再生すると、CircuitPythonではエラーとなるWAVファイルでも、エラーにならず再生できました。
CircuitPython(Adafruit)の実装の違いでしょうか。

MicroPython v1.22.2 on 2024-02-22; Raspberry Pi Pico W with RP2040

追伸

Raspberry Pi Pico のフラッシュメモリは2MBしか無いため、CircuitPython / MicroPythonのファームウェアを入れると、空き容量はわずかとなり、数秒のWAVファイルしか再生できない。
10秒で2MBぐらいになるため、大きいWAVファイルを再生するためには、外付けのSDカードから再生するしかない。
これについては、別の記事とする予定。

以上

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2