-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
supporting of different bits per sample #5244
Comments
Not supported now, with no expectation of adding them in. Never seen an 8-bit-only I2S DAC (thankfully!). All the API and calls now are assuming packed 16-bits, as well as assumptions about clocking setup (reverse-engineered by multiple people) and other parts (DMA clocking/etc). What's the use case? Never had a request from the folks using my I2S decoder library, so I'm curious... |
Thanks for replying. There are hifi audio with 96k, 192k and 384k sampling rate and 24bis or 32 bits per sample. |
@earlephilhower is this request valid? Is it something you'd consider as an enhancement for your audio lib? |
It's definitely possible, but would require a significant change to the userspace API. The actual DMA/etc. doesn't care as long as you set the I2S config appropriately. Given that the I2S clocking is also only approximate (check the code that tries to figure out the closest divisor combination for the clock), hifi DACs and the 8266 seem like a waste. 24- and 32-bit samples would be handled the same, as 4-bytes per sample, left-aligned signed fractional. Fine for leaving it open as a 3.0 or something, but probably not 2.6.x. |
I'll leave it without a milestone for now. |
Hi if you got time, I can send you the modified code for your review. The modified i2s.h is as following: #define I2S_DUAL_CHANNELS (0) #define I2STX_16BITS_FULL (0) #ifdef __cplusplus void i2s_begin(); // Enable TX only, for compatibility /* bool i2s_is_full();//returns true if DMA is full and can not take more bytes (overflow) #ifdef __cplusplus |
Hi @earlephilhower I am very interested to this too, I developed an ESP8266 and ESP32 audio library like your good ESP8266Audio library, but simpler and a bit different, ESP32 have this by filling i2s configuration structures but I cannot figure how to set highter bit rates on ESP8266, without these ESP8266 cannot be used as Hi Fidelity audio player, I only can play with 16Bit audio and not with professional 24Bit and 32Bit audio for studio recording. Please, tell me if there are plains to add it or maybe point me on the right direction. Hi @tedhsieh1966 do you you tried your modified code? Many thanks to both |
Add basic 24 bit mode to the I2S API with a i2s_set_bits() call. By default 16b mode is still used, but if i2s_set_bits(24) is run before i2s_begin() then the HW will drive 24-bits of data. This data must be left-aligned (i.e. bits 31..8) in 4-byte samples. Fixes #5244 (the HW doesn't support 8 or 32 bits, only 16 or 24).
Many thanks for this great feature I've awaited for a long time 😉 So now I can play 96Khz 24 bit audio on ESP8266. Many thanks for your great work !!! |
Thanks a million. Can't wait to try it. |
The math used shouldn't care whether it's 8khz or 96klhz (it does floating point math to avoid overflow/etc, see the core_esp8266_i2s.c file). However the 8266 itself does not have an audio PLL and therefore the generated bit clock is simply a divided version of the 80mhz core clock. It is most likely the case that at 48 bits/L+R sample at 96khz the actual closest clock is too far from 96khz to work properly w/the DAC. DACs often have separate filter banks depending on the bitrate, and if you fall outside its window may not do anything at all. :( Back of the envelope gives ~4.6MHz clock for 96K x 24b x 2, which is also very high for the GPIOs on-chip and any kind of breadboarding, so be careful with signal integrity, too. |
Many thanks for your reply earlephilhower, I had the similar issue using the PCM1808 I2S 24 bit Stereo line in with ESP32 that need an external clock (quartz or PLL chip like PLL17xx), but I've tried to use ESP32 itself to generate the clock with LEDC pwm (teorically by set the divider to 1 the resolution decrease to 1 bit and the max speed is 80 Mhz. It worked well at 36Khz samplerate but won't work with 44100, 48000, 96000 samplerate due to clock dividers aproximation, I know that the clock cannot be precise. I use it at 256FS so i.e. at 48Khz it need 48000 x 256 x 2 = 24.576.000 Hz, using same calculation at 44100 it must be 22.579.200 and at 96Khz must be exact the double of 48Khz, so 49.512.000 Hz. For PCM1808 specific case the clock must be max 6 frames +- outgoing the real clock needed, after this it won't work. But the problem is that I'm sure that on old cores the same external DAC I will use now worked well up 192 Khz on breadboard too with short wires, so this is software related too, not only hardware, maybe I can search i2s.h and core_esp8266_i2s.c from old cores and test again. Many thanks for your great support |
The sample rate 192k/96k doesn't matter, really, just the bitclock. The sample rate is the period of the LRCLOCK and triggered off the bitclock mod (16,24). Remember you're sending more bits at 24b per sample.
There is a fcn which reports the real I2S rate. I'd recommend dumping it on your 96K setup and see how far off it is. |
Yes I already used it, the i2s_get_real_rate() function. Note that I only used 16bit with ESP8266, never used the new 24bit API, I will try it these days when I've some time, for 24bit I refer to ESP32. I've used 24bit on ESP8266 only for input (PCM1808 Dual I2S line in and INMP441 I2S microphone), but to send it's signal to external DAC I downsampled to 16bit. Anyway, next days I will test and see the real rate if is out the PCM5102 threshold by reading the datasheet and eventually I report it here. Many thanks |
Hi earlephilhower , uint16_t i2s_write_buffer(int16_t *frames, uint16_t frame_count); |
The core unfortunately exported the I2S functions as plain C so we couldn't add overloads for 32b quantities. Easiest thing is to use |
I'm trying to use this with an INMP441 mic. I'm a bit confused how 24-bit read is supposed to work given that i2s_read_sample defines a 16-bit interface? |
Can we have the 8 bit -mono support? I write this question because the i2s port of this MCU is used not only for using sound DAC's, and i think that using 8bit shift registers with this hardware would be awesome! |
Maybe you can use 2 shift registers to get 16 bits, or just use one and then use 8 bit values masking the value with 8 bit. (value & 0xFF). |
@dirtmover Have you succeded? Here is a screenshot of raw data decoded as 32kHz sample rate and 8bit per sample. Those noise parts are around 200bytes in length, so it is 50 samples@4bytes per sample. (I'm using i2s_read_sample(left, right) and left-right variables are put in buffer unmodified): |
IM trying to solve this also. |
In https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/i2s.h , there are different type of bit width per sample supported as following.
/**
/
typedef enum {
I2S_BITS_PER_SAMPLE_8BIT = 8, /!< I2S bits per sample: 8-bits*/
I2S_BITS_PER_SAMPLE_16BIT = 16, /!< I2S bits per sample: 16-bits/
I2S_BITS_PER_SAMPLE_24BIT = 24, /!< I2S bits per sample: 24-bits/
I2S_BITS_PER_SAMPLE_32BIT = 32, /!< I2S bits per sample: 32-bits/
} i2s_bits_per_sample_t;
However, in Arduino/cores/esp8266/i2s.h there is no description on how to use these.
Is there supporting of these bits_per_sample from cores for esp8266?
If yes, where can I find the usage documentation or examples?
If no, will there be a schedule to support them?
Thanks for any replying.
The text was updated successfully, but these errors were encountered: