adafruit / Adafruit_CircuitPython_CircuitPlayground

CircuitPython library for Circuit Playground Express
MIT License
91 stars 71 forks source link

Cannot play custom wav file #97

Closed ShreyaKhurana closed 4 years ago

ShreyaKhurana commented 4 years ago

Hi, I was trying to run a simple snippet using the cpx.play_file function:

from adafruit_circuitplayground.express import cpx

while True:
    if cpx.button_a:
        cpx.play_file("final.wav")
    if cpx.button_b:
        cpx.play_file("low_fade.wav")

I see the following error message because of final.wav which is my own file, in Mu:

Traceback (most recent call last):
  File "code.py", line 6, in <module>
  File "adafruit_circuitplayground/circuit_playground_base.py", line 741, in play_file
  File "adafruit_circuitplayground/circuit_playground_base.py", line 738, in play_file
ValueError: Data chunk must follow fmt chunk

But the image properties are as follows, the sample rate is < 22kHz and it's 16 bit file. i can play it fine in iTunes. Can someone please help with this?

Screen Shot 2020-08-01 at 5 44 35 PM
tannewt commented 4 years ago

Hi! How did you make the wavefile? I think we usually use Audacity.

We don't support all of the different versions of Wave because we are limited on code space.

ShreyaKhurana commented 4 years ago

I was using an online converter to get to the required sample rate and sample size. I'll try Audacity then!

evaherrada commented 4 years ago

Hey @ShreyaKhurana were you able to get this working?

ShreyaKhurana commented 4 years ago

Yup, got it working, just had to convert the file through Audacity, even iTunes didn't work for me though.

petewarden commented 1 year ago

As a note for anyone who wants a command line solution, I was able to successfully convert MP3s to CP-acceptable wavs using this ffmpeg command:

ffmpeg -i some.mp3 -f wav -flags +bitexact -acodec pcm_s16le -ac 1 -ar 22050 some.wav

This was using ffmpeg 3.4.11. The important part seems to be the -flags +bitexact, since that removes the additional chunk that the CircuitPlayground library can't handle. Some older versions of ffmpeg use -bitexact instead, apparently.

demc commented 1 year ago

As a note for anyone who wants a command line solution, I was able to successfully convert MP3s to CP-acceptable wavs using this ffmpeg command:

ffmpeg -i some.mp3 -f wav -flags +bitexact -acodec pcm_s16le -ac 1 -ar 22050 some.wav

This was using ffmpeg 3.4.11. The important part seems to be the -flags +bitexact, since that removes the additional chunk that the CircuitPlayground library can't handle. Some older versions of ffmpeg use -bitexact instead, apparently.

If anyone is having issues with ffmpeg 4 or 5, please use the following (notice the subtle change to the bitexact flag):

ffmpeg -i input_file.ogg -f wav -bitexact -acodec pcm_s16le -ac 1 -ar 22050 output_file.wav

As far as I could tell, -bitexact removes the ISFT metadata that was preventing the file from playing.

mperino commented 1 year ago

@demc 's ffmpeg solution worked on: ffmpeg 4.4.2-0ubuntu0.22.04.1 Much appreicated, and should be added to the docs..

s-light commented 5 months ago

just stumbled upon this - think also that is a important note for these docks:

additionally i head to remove the meta data from my files:

ffmpeg -i input.mp3 -bitexact -acodec pcm_s16le -ac 1 -ar 16000 -map_metadata -1 -bitexact output__16kHz_16bit_mono.wav

and just copied together a bash script for easier usage:

#!/bin/bash

input_file=( \
    -i "$1"
) 

fullfile="$1"
echo "${fullfile}"
filename=$(basename -- "$fullfile")
# echo "${filename}"
extension="${filename##*.}"
# echo "${filename}"
extension=$([[ "$filename" = *.* ]] && echo ".${filename##*.}" || echo '')
echo "${extension}"

# filename="${fullfile##*/}"
filename="${filename%.*}"
echo "${filename}"

echo "."
output_final="${filename}__16kHz_16bit_mono.wav"
echo "output_final: ${output_final}"
echo "."

# copy
codec=( \
    # no video
    # -vn
    -bitexact \
    # extract first 10sec
    # -t 10 \
    # audio 16bit
    -acodec pcm_s16le \
    -ac 1 \
    # rate 16kHz
    -ar 16000 \
    # remove metadata
    -map_metadata -1 \
    -bitexact
)
# -fflags +bitexact -flags:v +bitexact -flags:a +bitexact

echo "\nt1"

cmd_part1=(ffmpeg "${input_file[@]}" "${codec[@]}" "$output_final")
echo "part1:" "${cmd_part1[@]}"

"${cmd_part1[@]}"

echo "done"

exit