-
-
Notifications
You must be signed in to change notification settings - Fork 22
How to Add a New Codec
Phil Schatzmann edited this page Jun 3, 2025
·
19 revisions
This guide explains the steps required to add support for a board and audio codec to the arduino-audio-driver library.
-
Create a new folder for your codec under Driver (e.g.,
src/Driver/mycodec/
). -
Add your codec implementation files (e.g.,
mycodec.c
,mycodec.h
) to this folder.- Use existing codecs (e.g.,
src/Driver/wm8960/
) as a reference for structure.
- Use existing codecs (e.g.,
- Header-only implementations are preferred for new codecs. Existing codecs are planned be migrated to header-only in the future.
- If your codec uses I2C or SPI, use the platform abstraction APIs provided in Platforms (e.g.,
API_I2C.h
). Do not use platform-specific or Arduino specific code directly in your codec implementation.
Add a new class in DriverAPI.h that calls the functionality provided in step 1. It might look as follows:
class AudioDriverYourDriverClass : public AudioDriver {
public:
AudioDriverYourDriverClass() { i2c_default_address = 0x1A; }
bool setMute(bool mute) { return xxx_set_voice_mute(mute); }
bool setVolume(int volume) {
this->volume = volume;
return xxxx_set_voice_volume(limitValue(volume, 0, 100));
};
/// Oprionally provide volume from driver scaled from 0 to 100
int getVolume() {
int vol;
xxxx_get_voice_volume(&vol);
return vol;
};
protected:
/// setup the codec
bool init(codec_config_t codec_cfg) {
return xxxx_init(&codec_cfg, getI2C(), getI2CAddress()) == RESULT_OK;
}
/// Shut down the codec
bool deinit() { return xxxx_deinit() == RESULT_OK; }
/// Use DAC, ADC or both
bool controlState(codec_mode_t mode) {
return xxxx_ctrl_state_active(mode, true) == RESULT_OK;
}
/// Setup i2s basied on sample rate, bits, channels, format, master/slave
bool configInterface(codec_mode_t mode, I2SDefinition iface) {
return xxxx_config_i2s(mode, &iface) == RESULT_OK;
}
};
Refer to the existing drivers in Driver.h for more detailed examples.
If your audio baord comes with hardocded pins, add a new DriverPins subclass to the DriverPins.h and a global static variable that can be used in your sketch.
/**
* @brief Pins for ....
* @author Phil Schatzmann
* @copyright GPLv3
*/
class PinsYourBoardClass : public DriverPins {
public:
PinsYourBoardClass() {
// sd pins
addSPI(ESP32PinsSD);
// add i2c codec pins: scl, sda, port, frequency
addI2C(PinFunction::CODEC, 23, 18);
// add i2s pins: mclk, bck, ws,data_out, data_in ,(port)
addI2S(PinFunction::CODEC, 0, 5, 25, 26, 35);
// add other pins
addPin(PinFunction::KEY, 36, PinLogic::InputActiveLow, 1);
addPin(PinFunction::KEY, 39, PinLogic::InputActiveLow, 2);
addPin(PinFunction::KEY, 33, PinLogic::InputActiveLow, 3);
addPin(PinFunction::KEY, 32, PinLogic::InputActiveLow, 4);
addPin(PinFunction::KEY, 13, PinLogic::InputActiveLow, 5);
addPin(PinFunction::KEY, 27, PinLogic::InputActiveLow, 6);
addPin(PinFunction::AUXIN_DETECT, 12, PinLogic::InputActiveLow);
addPin(PinFunction::PA, 21, PinLogic::Output);
addPin(PinFunction::LED, 22, PinLogic::Output, 1);
addPin(PinFunction::LED, 19, PinLogic::Output, 2);
}
};
/// Add this to the end of the file
static PinsYourBoardClass PinsYourBoardPins;
Add an entry at the end of AudioBoard.h to create a static varialbe for your generic driver or baord. E.g:
static AudioBoard GenericYourDriver{AudioDriverYourDriverClass, NoPins}; // Pins defined in your Sketch
static AudioBoard YourBoard{AudioDriverYourDriverClass, PinsYourBoardClass}; // if baord has defined pins
- Test your codec with supported hardware.
- You can use the example audiokit sketches from the AudioTools project: Just replace AudioKitEs8388V1 with the AudioBoard defined in step 4
For generic drivers w/o pin definitions you need to set up the pins in your sketch. e.g.
I2SCodecStream i2s(GenericYourDriver);
void setup() {
Wire.setPins(sda_pin, scl_pin);
Wire.begin();
auto config = i2s.defaultConfig(TX_MODE);
config.pin_bck = 14;
config.pin_ws = 15;
config.pin_data = 22;
// config.pin_mck = 0; // optional master clock pin
// config.i2s_format = I2S_STD_FORMAT; // default format
// config.is_master = true; // default esp32 is master
i2s.begin(config);
}
See this Wiki for further info.
- Ensure your code follows the style and conventions of the project.
- Submit a pull request with your changes and documentation.