-
-
Notifications
You must be signed in to change notification settings - Fork 309
How to use converter to play 8-bit wav files using AudioPlayer? #2153
-
Problem Description
I don't understand how to use the format converter to play 8-bit wav files over I2C.
I've found an old closed issue where converter streams were mentioned, and I looked at an example. But failed to understand how to inject such a converter in the AudioPlayer (I'm using play WAV file from SD_MMC card).
Device Description
ESP32S3 with ES8311 DAC
Sketch
AudioBoard board{AudioDriverES8311, NoPins}; AudioBoardStream out(board); AudioInfo info(16000,1,16); AudioSourceIdxSDMMC source("/Audio", "wav", true); MultiDecoder multi; WAVDecoder wav; AudioPlayer player(source, out, multi); bool play_file(char *filename, float volume) { if (!SD_MMC.exists(filename)) { Serial.println("play_file: '" + String(filename) + "' does not exist"); return false; } player.end(); // stop previous if any player.setAutoNext(false); player.setPath(filename); return player.begin(); } void setup() { Serial.begin(115200); // wait for Serial to be ready while (! Serial); Serial.println(); DriverPins pins; // no pin definition pins.addI2C(PinFunction::CODEC, Wire, true); pins.addPin(PinFunction::PA, PAPIN, PinLogic::Output); // Power Amplifier PinsI2S PinsI2S(PinFunction::CODEC, MCLKPIN, BCLKPIN, WSPIN, DOPIN, DIPIN); pins.addSPI(PinFunction::SD, SDMMC_CLK, SDMMC_CMD, SDMMC_DATA, -1, SPI); pins.addI2S(PinsI2S); board.setPins(pins); // start I2S & codec Serial.println("starting I2S..."); auto config = out.defaultConfig(); config.copyFrom(info); // define I2S pins if you dont want to use the default pins config.pin_bck = BCLKPIN; config.pin_ws = WSPIN; config.pin_data = DOPIN; config.pin_mck = MCLKPIN; config.rx_tx_mode = TX_MODE; config.input_device = ADC_INPUT_NONE; // no input config.output_device = DAC_OUTPUT_ALL; // use both channels of the internal dac config.sd_active = true; config.use_apll = true; // use APLL for better clock config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; // two channel if (!out.begin(config)) { Serial.println("I2S failed to start!"); return false; } // additinal settings out.setVolume(0.8); Serial.println("I2S started..."); play_file("/Audio/danger.wav",1.0); // play test sound } void loop() { player.copy(); }
Other Steps to Reproduce
My WAV files are 8K, mono, 8-bit and sound like noise when played.
Debug logging:
starting I2S...
[D] I2SCodecStream.h : 79 - virtual bool audio_tools::I2SCodecStream::begin(audio_tools::I2SCodecConfig)
[D] I2SCodecStream.h : 216 - bool audio_tools::I2SCodecStream::begin1()
[D] I2SCodecStream.h : 253 - void audio_tools::I2SCodecStream::setupI2SPins()
[D] I2SCodecStream.h : 278 - audio_driver_local::Optional<audio_driver::PinsI2S> audio_tools::I2SCodecStream::getI2SPins()
[D] I2SCodecStream.h : 285 - bool audio_tools::I2SCodecStream::beginCodec(audio_tools::I2SCodecConfig)
[D] I2SCodecStream.h : 301 - input: 0
[D] I2SCodecStream.h : 302 - output: 3
[D] I2SCodecStream.h : 318 - BIT_LENGTH_16BITS
[D] I2SCodecStream.h : 340 - RATE_16K
[D] I2SCodecStream.h : 367 - I2S_NORMAL
Debug: AudioBoard::begin
Info: AudioDriver::begin
Info: setupI2CAddress: 0x18
Info: ==> Updating address: 0x18
Info: sd_active: 1
Debug: DriverPins::begin
Debug: DriverPins::setupPinMode
Debug: pinMode for 46
Debug: PinsSPI::begin for 7
Info: setting up SPI miso:1,mosi:3, clk:2, cs:-1
Debug: PinsI2C::begin for function 8 on port 0
Info: i2c_bus_create
Info: setting up I2C w/o pins
[188689][W][Wire.cpp:301] begin(): Bus already started in Master Mode.
Info: AudioDriver::setConfig
Info: MCLK_SOURCE: 0
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x2
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x3
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x16
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x4
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x5
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xB
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xC
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x10
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x11
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x0
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x0
Info: ES8311 in Slave mode
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x0
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1
Info: ES8311 clock source: MCLK
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x2
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x2
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x5
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x5
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x3
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x3
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x4
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x4
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x7
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x7
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x8
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x8
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x6
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x6
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x6
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x6
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x13
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1B
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x1C
Debug: mode->CODEC_MODE_DECODE
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x9
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xA
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x9
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xA
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x17
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xE
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x12
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x14
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x14
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x14
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xD
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x15
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x37
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x45
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x9
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xA
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x9
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xA
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x9
Debug: i2c_bus_read_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xA
Debug: ES8311 in I2S Format
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x9
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0xA
Info: setPAPower pin 46 -> 1
Debug: es8311_codec_set_voice_volume:70
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x32
Debug: setVolume: 70
[D] I2SStream.h : 72 - bool audio_tools::I2SStream::begin(audio_tools::I2SConfig)
[D] BaseStream.h : 131 - virtual void audio_tools::AudioStream::setAudioInfo(audio_tools::AudioInfo)
[I] AudioTypes.h : 125 - in: sample_rate: 16000 / channels: 1 / bits_per_sample: 16
[I] AudioTypes.h : 125 - out: sample_rate: 16000 / channels: 1 / bits_per_sample: 16
[D] I2SESP32.h : 63 - bool audio_tools::I2SDriverESP32::begin(audio_tools::I2SConfigESP32)
[D] I2SESP32.h : 182 - bool audio_tools::I2SDriverESP32::begin(audio_tools::I2SConfigESP32, int, int)
[I] AudioTypes.h : 125 - sample_rate: 16000 / channels: 1 / bits_per_sample: 16
[I] I2SConfigESP32.h : 80 - rx/tx mode: TX_MODE
[I] I2SConfigESP32.h : 81 - port_no: 0
[I] I2SConfigESP32.h : 82 - is_master: Master
[I] I2SConfigESP32.h : 83 - sample rate: 16000
[I] I2SConfigESP32.h : 84 - bits per sample: 16
[I] I2SConfigESP32.h : 85 - number of channels: 1
[I] I2SConfigESP32.h : 86 - signal_type: Digital
[I] I2SConfigESP32.h : 88 - i2s_format: I2S_STD_FORMAT
[I] I2SConfigESP32.h : 90 - auto_clear: true
[I] I2SConfigESP32.h : 92 - use_apll: true
[I] I2SConfigESP32.h : 97 - buffer_count:6
[I] I2SConfigESP32.h : 98 - buffer_size:512
[I] I2SConfigESP32.h : 101 - pin_mck: 42
[I] I2SConfigESP32.h : 103 - pin_bck: 9
[I] I2SConfigESP32.h : 105 - pin_ws: 45
[I] I2SConfigESP32.h : 107 - pin_data: 8
[D] I2SESP32.h : 214 - i2s_driver_install
[D] I2SESP32.h : 230 - i2s_set_pin
[D] I2SESP32.h : 241 - i2s_zero_dma_buffer
[D] I2SESP32.h : 245 - begin - started
Debug: setVolume: 100
Debug: es8311_codec_set_voice_volume:100
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x32
Debug: setVolume: 80
Debug: es8311_codec_set_voice_volume:80
Debug: i2c_bus_write_bytes: addr=0x18 reglen=1 datalen=1 - reg=0x32
I2S started...
[D] Allocator.h : 76 - Allocated 4
[D] Allocator.h : 76 - Allocated 12
[D] AudioPlayer.h : 195 - void audio_tools::AudioPlayer::end()
[I] MetaDataID3.h : 592 - virtual void audio_tools::MetaDataID3::end()
[I] AudioPlayer.h : 201 - reset codec
[D] AudioPlayer.h : 303 - bool audio_tools::AudioPlayer::setPath(const char*)
[I] AudioPlayer.h : 559 - void audio_tools::AudioPlayer::writeEnd()
[D] StreamCopy.h : 108 - copy 1024 bytes
[I] AudioSourceIdxSDMMC.h : 79 - -> selectStream: /Audio/danger.wav
[D] AudioPlayer.h : 195 - void audio_tools::AudioPlayer::end()
[I] MetaDataID3.h : 592 - virtual void audio_tools::MetaDataID3::end()
[I] AudioPlayer.h : 201 - reset codec
[D] AudioEncoded.h : 150 - virtual bool audio_tools::EncodedAudioOutput::begin()
[D] AudioEncoded.h : 152 - virtual bool audio_tools::EncodedAudioOutput::begin()
[D] Allocator.h : 76 - Allocated 8
[D] AudioCodecsBase.h : 29 - virtual void audio_tools::AudioDecoder::setAudioInfo(audio_tools::AudioInfo)
[D] AudioPlayer.h : 325 - open selected stream
[I] MetaDataID3.h : 586 - virtual void audio_tools::MetaDataID3::begin()
[D] Allocator.h : 76 - Allocated 256
[D] StreamCopy.h : 51 - void audio_tools::StreamCopyT<T>::begin() [with T = unsigned char]
[I] StreamCopy.h : 57 - buffer_size=1024
[D] AudioPlayer.h : 150 - bool audio_tools::AudioPlayer::begin(int, bool)
[I] AudioPlayer.h : 363 - setVolume(1.000000)
[D] Allocator.h : 76 - Allocated 8
[D] Allocator.h : 76 - Allocated 8
[I] VolumeStream.h : 199 - setVolume: 1.000000 at 0
[I] VolumeStream.h : 199 - setVolume: 1.000000 at 1
[D] BaseStream.h : 131 - virtual void audio_tools::AudioStream::setAudioInfo(audio_tools::AudioInfo)
[I] AudioTypes.h : 125 - in: sample_rate: 16000 / channels: 1 / bits_per_sample: 16
[I] AudioTypes.h : 125 - out: sample_rate: 16000 / channels: 1 / bits_per_sample: 16
[D] Allocator.h : 76 - Allocated 2
[D] Allocator.h : 76 - Allocated 4
[D] Allocator.h : 76 - Allocated 4
[D] AudioEncoded.h : 150 - virtual bool audio_tools::EncodedAudioOutput::begin()
[D] AudioSourceIdxSDMMC.h : 43 - virtual void audio_tools::AudioSourceIdxSDMMC::begin()
[D] SDIndex.h : 25 - void audio_tools::SDIndex<SDT, FileT>::begin(const char*, const char*, const char*, bool) [with SDT = fs::SDMMCFS; FileT = fs::File]
[I] SDIndex.h : 32 - Index file size: 296
[I] MetaDataID3.h : 586 - virtual void audio_tools::MetaDataID3::begin()
[D] VolumeStream.h : 101 - bool audio_tools::VolumeStream::begin(audio_tools::VolumeStreamConfig)
[I] AudioSourceIdxSDMMC.h : 66 - selectStream: 0
[D] SDIndex.h : 84 - 0 -> /Audio/traffic.wav
[I] AudioSourceIdxSDMMC.h : 70 - Using file /Audio/traffic.wav
[D] AudioPlayer.h : 195 - void audio_tools::AudioPlayer::end()
[I] AudioEncoded.h : 178 - virtual void audio_tools::EncodedAudioOutput::end()
[I] MetaDataID3.h : 592 - virtual void audio_tools::MetaDataID3::end()
[I] AudioPlayer.h : 201 - reset codec
[D] AudioEncoded.h : 150 - virtual bool audio_tools::EncodedAudioOutput::begin()
[D] AudioEncoded.h : 152 - virtual bool audio_tools::EncodedAudioOutput::begin()
[D] AudioCodecsBase.h : 29 - virtual void audio_tools::AudioDecoder::setAudioInfo(audio_tools::AudioInfo)
[D] AudioPlayer.h : 325 - open selected stream
[I] MetaDataID3.h : 586 - virtual void audio_tools::MetaDataID3::begin()
[D] StreamCopy.h : 51 - void audio_tools::StreamCopyT<T>::begin() [with T = unsigned char]
[I] StreamCopy.h : 57 - buffer_size=1024
[D] StreamCopy.h : 51 - void audio_tools::StreamCopyT<T>::begin() [with T = unsigned char]
[I] StreamCopy.h : 57 - buffer_size=1024
[D] AudioPlayer.h : 405 - size_t audio_tools::AudioPlayer::copy(size_t)
[D] StreamCopy.h : 108 - copy 1024 bytes
[D] StreamCopy.h : 256 - available: 3554
[D] StreamCopy.h : 395 - write: 1024
[D] AudioEncoded.h : 191 - EncodedAudioOutput::write: 1024
[I] MultiDecoder.h : 253 - mime from mime_detector: audio/vnd.wave
[I] MultiDecoder.h : 199 - Using decoder for audio/vnd.wave (audio/vnd.wave)
[D] CodecWAV.h : 297 - virtual bool audio_tools::WAVDecoder::begin()
[I] MultiDecoder.h : 208 - Decoder audio/vnd.wave started
[D] CodecWAV.h : 319 - virtual size_t audio_tools::WAVDecoder::write(const uint8_t*, size_t)
[D] Buffers.h : 67 - writeArray 1024 -> 200
[I] CodecWAV.h : 57 - WAVHeader::begin: 200
[I] CodecWAV.h : 213 - WAVHeader sound_pos: 44
[I] CodecWAV.h : 214 - WAVHeader channels: 1
[I] CodecWAV.h : 215 - WAVHeader bits_per_sample: 8
[I] CodecWAV.h : 216 - WAVHeader sample_rate: 8000
[I] CodecWAV.h : 217 - WAVHeader format: 1
[I] CodecWAV.h : 422 - WAV sample_rate: 8000
[I] CodecWAV.h : 423 - WAV data_length: 3470
[I] CodecWAV.h : 424 - WAV is_streamed: 0
[I] CodecWAV.h : 426 - WAV is_valid: false
[D] AudioCodecsBase.h : 29 - virtual void audio_tools::AudioDecoder::setAudioInfo(audio_tools::AudioInfo)
[D] AudioPlayer.h : 230 - virtual void audio_tools::AudioPlayer::setAudioInfo(audio_tools::AudioInfo)
[I] AudioPlayer.h : 231 - sample_rate: 8000
[I] AudioPlayer.h : 232 - bits_per_sample: 8
[I] AudioPlayer.h : 233 - channels: 1
What is your development environment (incl. core version info)
No response
I have checked existing issues, discussions and online documentation
- I confirm I have checked existing issues, discussions and online documentation
Beta Was this translation helpful? Give feedback.
All reactions
I guess there are quite a few possibilities that might work: e.g.
a) use a CodecChain consisting of a WAVDecoder and a DecoderL8;
b) Instead of sending the output to I2SStream send it to a NumberFormatConverterStreamT<uint8_t, int16_t> nfc(out);
ps: this is not a bug in my code, so it shuld be a discussion and not an issue!
Replies: 2 comments 5 replies
-
I guess there are quite a few possibilities that might work: e.g.
a) use a CodecChain consisting of a WAVDecoder and a DecoderL8;
b) Instead of sending the output to I2SStream send it to a NumberFormatConverterStreamT<uint8_t, int16_t> nfc(out);
ps: this is not a bug in my code, so it shuld be a discussion and not an issue!
Beta Was this translation helpful? Give feedback.
All reactions
-
Agreed, my bad for not opening a discussion.
The I2SStream is currently embedded in AudioPlayer is it not? How would you "inject" such a CodecChain or that NumberFormatConverterStream?
I guess I need a code example.
Beta Was this translation helpful? Give feedback.
All reactions
-
I've tried switching to an MP3 file instead, and this looks OK in the logging, but sounds like noise on the output.
The file plays OK on my PC. I must admit there's a lot going on in the loop, not just the audio handling.
I haven't tried with a basic AudioPlayer only sketch.
Beta Was this translation helpful? Give feedback.
All reactions
-
No, there is no relationship between the player and I2S: you define the output object to the audio player and this can be anything!
In my proposal this would be the nfc!
AudioBoard board{AudioDriverES8311, NoPins}; AudioBoardStream out(board); NumberFormatConverterStreamT<uint8_t, int16_t> nfc(out); AudioPlayer player(source, nfc, multi);
Beta Was this translation helpful? Give feedback.
All reactions
-
The MP3 player worked OK, when I removed the debug logger, makes sense, all that Serial logging was eating too many CPU cycles.
Beta Was this translation helpful? Give feedback.
All reactions
-
FYI: I gave up on the number converter and converted my audio files to MP3 instead. Thanks for your support!
Beta Was this translation helpful? Give feedback.
All reactions
-
To make things a bit simpler, I extended the WAVDecoder to automatically convert 8 bit data to 16 bits and tested the functioniality today!
Beta Was this translation helpful? Give feedback.