Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
earlephilhower committed Mar 26, 2018
2 parents b5faad6 + e3a3f2b commit 1e584d1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 11 deletions.
5 changes: 5 additions & 0 deletions src/AudioFileSourceBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ uint32_t AudioFileSourceBuffer::getPos()
return src->getPos();
}

uint32_t AudioFileSourceBuffer::getFillLevel()
{
return length;
}

uint32_t AudioFileSourceBuffer::read(void *data, uint32_t len)
{
if (!buffer) return src->read(data, len);
Expand Down
2 changes: 2 additions & 0 deletions src/AudioFileSourceBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class AudioFileSourceBuffer : public AudioFileSource
virtual uint32_t getPos() override;
virtual bool loop() override;

virtual uint32_t getFillLevel();

enum { STATUS_FILLING=2, STATUS_UNDERFLOW };

private:
Expand Down
37 changes: 28 additions & 9 deletions src/AudioOutputI2S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@
#endif
#include "AudioOutputI2S.h"

AudioOutputI2S::AudioOutputI2S(int port, bool builtInDAC, int use_apll)
AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int use_apll)
{
this->portNo = port;
this->i2sOn = false;
this->builtInDAC = builtInDAC;
if (output_mode != EXTERNAL_I2S && output_mode != INTERNAL_DAC && output_mode != INTERNAL_PDM) {
output_mode = EXTERNAL_I2S;
}
this->output_mode = output_mode;
#ifdef ESP32
if (!i2sOn) {
if (use_apll == APLL_AUTO) {
Expand All @@ -42,12 +45,25 @@ AudioOutputI2S::AudioOutputI2S(int port, bool builtInDAC, int use_apll)
use_apll = APLL_ENABLE;
}
}

i2s_mode_t mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
if (output_mode == INTERNAL_DAC) {
mode = (i2s_mode_t)(mode | I2S_MODE_DAC_BUILT_IN);
} else if (output_mode == INTERNAL_PDM) {
mode = (i2s_mode_t)(mode | I2S_MODE_PDM);
}

i2s_comm_format_t comm_fmt = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB);
if (output_mode == INTERNAL_DAC) {
comm_fmt = (i2s_comm_format_t)I2S_COMM_FORMAT_I2S_MSB;
}

i2s_config_t i2s_config_dac = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | (builtInDAC ? I2S_MODE_DAC_BUILT_IN : 0)),
.mode = mode,
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = (i2s_comm_format_t)((builtInDAC ? 0 : I2S_COMM_FORMAT_I2S) | I2S_COMM_FORMAT_I2S_MSB),
.communication_format = comm_fmt,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority
.dma_buf_count = 8,
.dma_buf_len = 64, //Interrupt level 1
Expand All @@ -57,7 +73,7 @@ AudioOutputI2S::AudioOutputI2S(int port, bool builtInDAC, int use_apll)
if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_dac, 0, NULL) != ESP_OK) {
Serial.println("ERROR: Unable to install I2S drives\n");
}
if (builtInDAC) {
if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) {
i2s_set_pin((i2s_port_t)portNo, NULL);
i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
} else {
Expand Down Expand Up @@ -85,7 +101,7 @@ AudioOutputI2S::~AudioOutputI2S()
if (i2sOn) {
Serial.printf("UNINSTALL I2S\n");
i2s_driver_uninstall((i2s_port_t)portNo); //stop & destroy i2s driver
}
}
#else
if (i2sOn) i2s_end();
#endif
Expand All @@ -95,7 +111,7 @@ AudioOutputI2S::~AudioOutputI2S()
bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout)
{
#ifdef ESP32
if (builtInDAC) return false; // Not allowed
if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) return false; // Not allowed

i2s_pin_config_t pins = {
.bck_io_num = bclk,
Expand Down Expand Up @@ -159,15 +175,18 @@ bool AudioOutputI2S::ConsumeSample(int16_t sample[2])
uint32_t ttl = sample[LEFTCHANNEL] + sample[RIGHTCHANNEL];
sample[LEFTCHANNEL] = sample[RIGHTCHANNEL] = (ttl>>1) & 0xffff;
}
uint32_t s32 = ((Amplify(sample[RIGHTCHANNEL]))<<16) | (Amplify(sample[LEFTCHANNEL]) & 0xffff);
#ifdef ESP32
if (builtInDAC) {
uint32_t s32;
if (output_mode == INTERNAL_DAC) {
int16_t l = Amplify(sample[LEFTCHANNEL]) + 0x8000;
int16_t r = Amplify(sample[RIGHTCHANNEL]) + 0x8000;
s32 = (r<<16) | (l&0xffff);
} else {
s32 = ((Amplify(sample[RIGHTCHANNEL]))<<16) | (Amplify(sample[LEFTCHANNEL]) & 0xffff);
}
return i2s_push_sample((i2s_port_t)portNo, (const char *)&s32, 0);
#else
uint32_t s32 = ((Amplify(sample[RIGHTCHANNEL]))<<16) | (Amplify(sample[LEFTCHANNEL]) & 0xffff);
return i2s_write_sample_nb(s32); // If we can't store it, return false. OTW true
#endif
}
Expand Down
5 changes: 3 additions & 2 deletions src/AudioOutputI2S.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
class AudioOutputI2S : public AudioOutput
{
public:
AudioOutputI2S(int port=0, bool builtInDAC=false, int use_apll=APLL_DISABLE);
AudioOutputI2S(int port=0, int output_mode=EXTERNAL_I2S, int use_apll=APLL_DISABLE);
virtual ~AudioOutputI2S() override;
bool SetPinout(int bclkPin, int wclkPin, int doutPin);
virtual bool SetRate(int hz) override;
Expand All @@ -39,11 +39,12 @@ class AudioOutputI2S : public AudioOutput
bool SetOutputModeMono(bool mono); // Force mono output no matter the input

enum : int { APLL_AUTO = -1, APLL_ENABLE = 1, APLL_DISABLE = 0 };
enum : int { EXTERNAL_I2S = 0, INTERNAL_DAC = 1, INTERNAL_PDM = 2 };

protected:
virtual int AdjustI2SRate(int hz) { return hz; }
uint8_t portNo;
bool builtInDAC;
int output_mode;
bool mono;
bool i2sOn;
};
Expand Down

0 comments on commit 1e584d1

Please sign in to comment.