Fix ESP32 regression of I2s_write_bytes (#12812)

This commit is contained in:
Theo Arends 2021-08-02 11:34:24 +02:00
parent 4f47fc8527
commit 1c5b1c0ee0
3 changed files with 95 additions and 5 deletions

View File

@ -1,7 +1,7 @@
/* /*
AudioOutputI2S AudioOutputI2S
Base class for I2S interface port Base class for I2S interface port
Copyright (C) 2017 Earle F. Philhower, III Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -269,7 +269,11 @@ bool AudioOutputI2S::ConsumeSample(int16_t sample[2])
{ {
s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff); s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff);
} }
return i2s_write_bytes((i2s_port_t)portNo, (const char *)&s32, sizeof(uint32_t), 0); // Deprecated. Use i2s_write
// return i2s_write_bytes((i2s_port_t)portNo, (const char *)&s32, sizeof(uint32_t), 0);
size_t bytes_written;
i2s_write((i2s_port_t)portNo, (const char*)&s32, sizeof(uint32_t), &bytes_written, 0);
return bytes_written;
#elif defined(ESP8266) #elif defined(ESP8266)
uint32_t s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff); uint32_t s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff);
return i2s_write_sample_nb(s32); // If we can't store it, return false. OTW true return i2s_write_sample_nb(s32); // If we can't store it, return false. OTW true

View File

@ -1,7 +1,7 @@
/* /*
AudioOutputI2SNoDAC AudioOutputI2SNoDAC
Audio player using SW delta-sigma to generate "analog" on I2S data Audio player using SW delta-sigma to generate "analog" on I2S data
Copyright (C) 2017 Earle F. Philhower, III Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -66,7 +66,7 @@ void AudioOutputI2SNoDAC::DeltaSigma(int16_t sample[2], uint32_t dsBuff[8])
for (int j = 0; j < oversample32; j++) { for (int j = 0; j < oversample32; j++) {
uint32_t bits = 0; // The bits we convert the sample into, MSB to go on the wire first uint32_t bits = 0; // The bits we convert the sample into, MSB to go on the wire first
for (int i = 32; i > 0; i--) { for (int i = 32; i > 0; i--) {
bits = bits << 1; bits = bits << 1;
if (cumErr < 0) { if (cumErr < 0) {
@ -95,7 +95,11 @@ bool AudioOutputI2SNoDAC::ConsumeSample(int16_t sample[2])
// Either send complete pulse stream or nothing // Either send complete pulse stream or nothing
#ifdef ESP32 #ifdef ESP32
if (!i2s_write_bytes((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample/32), 0)) // Deprecated. Use i2s_write
// if (!i2s_write_bytes((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample/32), 0))
size_t bytes_written;
i2s_write((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample/32), &bytes_written, 0);
if (!bytes_written)
return false; return false;
#elif defined(ESP8266) #elif defined(ESP8266)
if (!i2s_write_sample_nb(dsBuff[0])) return false; // No room at the inn if (!i2s_write_sample_nb(dsBuff[0])) return false; // No room at the inn

View File

@ -0,0 +1,82 @@
The current library needs two fixes solving the deprecated ``i2s_write_bytes`` function.
In file AudioOutputI2S.cpp:
bool AudioOutputI2S::ConsumeSample(int16_t sample[2])
{
//return if we haven't called ::begin yet
if (!i2sOn)
return false;
int16_t ms[2];
ms[0] = sample[0];
ms[1] = sample[1];
MakeSampleStereo16( ms );
if (this->mono) {
// Average the two samples and overwrite
int32_t ttl = ms[LEFTCHANNEL] + ms[RIGHTCHANNEL];
ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl>>1) & 0xffff;
}
#ifdef ESP32
uint32_t s32;
if (output_mode == INTERNAL_DAC)
{
int16_t l = Amplify(ms[LEFTCHANNEL]) + 0x8000;
int16_t r = Amplify(ms[RIGHTCHANNEL]) + 0x8000;
s32 = (r << 16) | (l & 0xffff);
}
else
{
s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff);
}
// Deprecated. Use i2s_write
// return i2s_write_bytes((i2s_port_t)portNo, (const char *)&s32, sizeof(uint32_t), 0);
size_t bytes_written;
i2s_write((i2s_port_t)portNo, (const char*)&s32, sizeof(uint32_t), &bytes_written, 0);
return bytes_written;
#elif defined(ESP8266)
uint32_t s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff);
return i2s_write_sample_nb(s32); // If we can't store it, return false. OTW true
#elif defined(ARDUINO_ARCH_RP2040)
return !!I2S.write((void*)ms, 4);
#endif
}
In file AudioOutputI2SNoDac.cpp:
bool AudioOutputI2SNoDAC::ConsumeSample(int16_t sample[2])
{
int16_t ms[2];
ms[0] = sample[0];
ms[1] = sample[1];
MakeSampleStereo16( ms );
// Make delta-sigma filled buffer
uint32_t dsBuff[8];
DeltaSigma(ms, dsBuff);
// Either send complete pulse stream or nothing
#ifdef ESP32
// Deprecated. Use i2s_write
// if (!i2s_write_bytes((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample/32), 0))
size_t bytes_written;
i2s_write((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample/32), &bytes_written, 0);
if (!bytes_written)
return false;
#elif defined(ESP8266)
if (!i2s_write_sample_nb(dsBuff[0])) return false; // No room at the inn
// At this point we've sent in first of possibly 8 32-bits, need to send
// remaining ones even if they block.
for (int i = 32; i < oversample; i+=32)
i2s_write_sample( dsBuff[i / 32]);
#elif defined(ARDUINO_ARCH_RP2040)
int16_t *p = (int16_t *) dsBuff;
for (int i = 0; i < oversample / 16; i++) {
I2S.write(*(p++));
}
#endif
return true;
}