├── gui ├── favicon.ico ├── img │ ├── pwm.png │ ├── tdm.jpg │ ├── adat.jpg │ ├── delay.png │ ├── grip.png │ ├── adcpins1.jpg │ ├── adcpins2.jpg │ ├── biquad.png │ ├── cs42448.jpg │ ├── dacpin.jpg │ ├── dacpins.png │ ├── dahdsr.png │ ├── multiply.png │ ├── node-red.png │ ├── pdmmic.jpg │ ├── pt8211.jpg │ ├── adccircuit.png │ ├── fir_filter.png │ ├── w25q128fv.jpg │ ├── waveforms.png │ ├── waveshaper.png │ ├── whitenoise.png │ ├── adccircuit2.png │ ├── adccircuitmic.jpg │ ├── ampschematics.png │ ├── dac_speaker.jpg │ ├── memoryboard.jpg │ ├── pw_maze_white.png │ ├── shelf_filter.png │ ├── spdif_proto.jpg │ ├── touchguitar.jpg │ ├── usbtype_audio.png │ ├── waveformsmod.png │ ├── pwmdualcircuit.jpg │ ├── sgtl5000closeup.jpg │ ├── wavetablevideo.jpg │ ├── audioshield_inputs.jpg │ ├── usbtype_audio_in.png │ ├── usbtype_audio_out.png │ ├── audioshield_backside.jpg │ ├── audioshield_outputs.jpg │ ├── audioshield_quad_in.jpg │ ├── audioshield_quad_out.jpg │ └── spin.svg ├── icons │ ├── db.png │ ├── rpi.png │ ├── alert.png │ ├── bridge.png │ ├── debug.png │ ├── feed.png │ ├── file.png │ ├── hash.png │ ├── inject.png │ ├── light.png │ ├── range.png │ ├── redis.png │ ├── serial.png │ ├── swap.png │ ├── switch.png │ ├── timer.png │ ├── watch.png │ ├── arduino.png │ ├── arrow-in.png │ ├── comment.png │ ├── envelope.png │ ├── function.png │ ├── leveldb.png │ ├── mongodb.png │ ├── template.png │ ├── trigger.png │ ├── twitter.png │ ├── bluetooth.png │ ├── bridge-dash.png │ ├── node-error.png │ ├── white-globe.png │ └── node-changed.png ├── font-awesome │ └── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff ├── bootstrap │ └── img │ │ ├── glyphicons-halflings.png │ │ └── glyphicons-halflings-white.png ├── jquery │ ├── css │ │ └── smoothness │ │ │ └── images │ │ │ ├── animated-overlay.gif │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ ├── ui-icons_454545_256x240.png │ │ │ ├── ui-icons_888888_256x240.png │ │ │ ├── ui-icons_cd0a0a_256x240.png │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ └── js │ │ └── jquery.ui.touch-punch.min.js └── red │ ├── ui │ ├── state.js │ ├── notifications.js │ ├── keyboard.js │ ├── tab-config.js │ ├── tabs.js │ ├── tab-info.js │ ├── touch │ │ └── radialMenu.js │ ├── sidebar.js │ └── palette.js │ ├── storage.js │ ├── history.js │ └── main.js ├── component.mk ├── .gitignore ├── README.md ├── lib └── sndfilter │ ├── mem.c │ ├── wav.h │ ├── mem.h │ ├── snd.h │ ├── snd.c │ ├── biquad.h │ ├── compressor.h │ ├── adaptive-release-curve.html │ ├── wav.c │ ├── compressor-curve.html │ └── biquad.c ├── src ├── synth_dc.cpp ├── effect_compressor.cpp ├── record_psram.cpp ├── effect_multiply.cpp ├── effect_calibration.cpp ├── data_waveforms.c ├── input_i2s.cpp ├── record_flash.cpp ├── output_i2s.cpp ├── mixer.cpp ├── control_i2s.cpp ├── synth_sine.cpp ├── effect_delay.cpp ├── effect_envelope.cpp ├── play_sdmmc_wav.cpp └── AudioStream.cpp ├── include ├── Audio.h ├── output_i2s.h ├── synth_dc.h ├── control_i2s.h ├── record_flash.h ├── record_psram.h ├── input_i2s.h ├── effect_calibration.h ├── play_sdmmc_wav.h ├── effect_multiply.h ├── CpuStats.h ├── effect_compressor.h ├── CpuDisplay.h ├── mixer.h ├── synth_sine.h ├── effect_envelope.h ├── effect_delay.h └── AudioStream.h └── CMakeLists.txt /gui/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/favicon.ico -------------------------------------------------------------------------------- /gui/img/pwm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/pwm.png -------------------------------------------------------------------------------- /gui/img/tdm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/tdm.jpg -------------------------------------------------------------------------------- /gui/icons/db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/db.png -------------------------------------------------------------------------------- /gui/icons/rpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/rpi.png -------------------------------------------------------------------------------- /gui/img/adat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/adat.jpg -------------------------------------------------------------------------------- /gui/img/delay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/delay.png -------------------------------------------------------------------------------- /gui/img/grip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/grip.png -------------------------------------------------------------------------------- /gui/icons/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/alert.png -------------------------------------------------------------------------------- /gui/icons/bridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/bridge.png -------------------------------------------------------------------------------- /gui/icons/debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/debug.png -------------------------------------------------------------------------------- /gui/icons/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/feed.png -------------------------------------------------------------------------------- /gui/icons/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/file.png -------------------------------------------------------------------------------- /gui/icons/hash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/hash.png -------------------------------------------------------------------------------- /gui/icons/inject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/inject.png -------------------------------------------------------------------------------- /gui/icons/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/light.png -------------------------------------------------------------------------------- /gui/icons/range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/range.png -------------------------------------------------------------------------------- /gui/icons/redis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/redis.png -------------------------------------------------------------------------------- /gui/icons/serial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/serial.png -------------------------------------------------------------------------------- /gui/icons/swap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/swap.png -------------------------------------------------------------------------------- /gui/icons/switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/switch.png -------------------------------------------------------------------------------- /gui/icons/timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/timer.png -------------------------------------------------------------------------------- /gui/icons/watch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/watch.png -------------------------------------------------------------------------------- /gui/img/adcpins1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/adcpins1.jpg -------------------------------------------------------------------------------- /gui/img/adcpins2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/adcpins2.jpg -------------------------------------------------------------------------------- /gui/img/biquad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/biquad.png -------------------------------------------------------------------------------- /gui/img/cs42448.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/cs42448.jpg -------------------------------------------------------------------------------- /gui/img/dacpin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/dacpin.jpg -------------------------------------------------------------------------------- /gui/img/dacpins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/dacpins.png -------------------------------------------------------------------------------- /gui/img/dahdsr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/dahdsr.png -------------------------------------------------------------------------------- /gui/img/multiply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/multiply.png -------------------------------------------------------------------------------- /gui/img/node-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/node-red.png -------------------------------------------------------------------------------- /gui/img/pdmmic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/pdmmic.jpg -------------------------------------------------------------------------------- /gui/img/pt8211.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/pt8211.jpg -------------------------------------------------------------------------------- /gui/icons/arduino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/arduino.png -------------------------------------------------------------------------------- /gui/icons/arrow-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/arrow-in.png -------------------------------------------------------------------------------- /gui/icons/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/comment.png -------------------------------------------------------------------------------- /gui/icons/envelope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/envelope.png -------------------------------------------------------------------------------- /gui/icons/function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/function.png -------------------------------------------------------------------------------- /gui/icons/leveldb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/leveldb.png -------------------------------------------------------------------------------- /gui/icons/mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/mongodb.png -------------------------------------------------------------------------------- /gui/icons/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/template.png -------------------------------------------------------------------------------- /gui/icons/trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/trigger.png -------------------------------------------------------------------------------- /gui/icons/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/twitter.png -------------------------------------------------------------------------------- /gui/img/adccircuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/adccircuit.png -------------------------------------------------------------------------------- /gui/img/fir_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/fir_filter.png -------------------------------------------------------------------------------- /gui/img/w25q128fv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/w25q128fv.jpg -------------------------------------------------------------------------------- /gui/img/waveforms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/waveforms.png -------------------------------------------------------------------------------- /gui/img/waveshaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/waveshaper.png -------------------------------------------------------------------------------- /gui/img/whitenoise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/whitenoise.png -------------------------------------------------------------------------------- /gui/icons/bluetooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/bluetooth.png -------------------------------------------------------------------------------- /gui/icons/bridge-dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/bridge-dash.png -------------------------------------------------------------------------------- /gui/icons/node-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/node-error.png -------------------------------------------------------------------------------- /gui/icons/white-globe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/white-globe.png -------------------------------------------------------------------------------- /gui/img/adccircuit2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/adccircuit2.png -------------------------------------------------------------------------------- /gui/img/adccircuitmic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/adccircuitmic.jpg -------------------------------------------------------------------------------- /gui/img/ampschematics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/ampschematics.png -------------------------------------------------------------------------------- /gui/img/dac_speaker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/dac_speaker.jpg -------------------------------------------------------------------------------- /gui/img/memoryboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/memoryboard.jpg -------------------------------------------------------------------------------- /gui/img/pw_maze_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/pw_maze_white.png -------------------------------------------------------------------------------- /gui/img/shelf_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/shelf_filter.png -------------------------------------------------------------------------------- /gui/img/spdif_proto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/spdif_proto.jpg -------------------------------------------------------------------------------- /gui/img/touchguitar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/touchguitar.jpg -------------------------------------------------------------------------------- /gui/img/usbtype_audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/usbtype_audio.png -------------------------------------------------------------------------------- /gui/img/waveformsmod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/waveformsmod.png -------------------------------------------------------------------------------- /gui/icons/node-changed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/icons/node-changed.png -------------------------------------------------------------------------------- /gui/img/pwmdualcircuit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/pwmdualcircuit.jpg -------------------------------------------------------------------------------- /gui/img/sgtl5000closeup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/sgtl5000closeup.jpg -------------------------------------------------------------------------------- /gui/img/wavetablevideo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/wavetablevideo.jpg -------------------------------------------------------------------------------- /gui/img/audioshield_inputs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/audioshield_inputs.jpg -------------------------------------------------------------------------------- /gui/img/usbtype_audio_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/usbtype_audio_in.png -------------------------------------------------------------------------------- /gui/img/usbtype_audio_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/usbtype_audio_out.png -------------------------------------------------------------------------------- /gui/img/audioshield_backside.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/audioshield_backside.jpg -------------------------------------------------------------------------------- /gui/img/audioshield_outputs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/audioshield_outputs.jpg -------------------------------------------------------------------------------- /gui/img/audioshield_quad_in.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/audioshield_quad_in.jpg -------------------------------------------------------------------------------- /gui/img/audioshield_quad_out.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/img/audioshield_quad_out.jpg -------------------------------------------------------------------------------- /gui/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /gui/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /gui/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /gui/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /gui/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /gui/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_ADD_INCLUDEDIRS := include 2 | COMPONENT_PRIV_INCLUDEDIRS+ := lib/dr_wav 3 | COMPONENT_SRCDIRS := src 4 | COMPONENT_SRCDIRS += lib/dr_wav -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/animated-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/animated-overlay.gif -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /gui/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macaba/ESP32Audio/HEAD/gui/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .config 2 | *.o 3 | *.pyc 4 | 5 | # Example project files 6 | examples/**/sdkconfig 7 | examples/**/sdkconfig.old 8 | examples/**/build 9 | 10 | # VS Code Settings 11 | .vscode/ 12 | build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32 Audio 2 | 3 | Based on the Teensy Audio Library with heavy modification (floats for samples, no ARM DSP instructions, and extensions to support CPU profiling). 4 | 5 | Using ESP-IDF v4.0-beta2 6 | 7 | ## Examples 8 | 9 | https://github.com/macaba/ESP32AudioLibraryExamples 10 | -------------------------------------------------------------------------------- /lib/sndfilter/mem.c: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc 2 | // MIT License 3 | // Project Home: https://github.com/voidqk/sndfilter 4 | 5 | #include "mem.h" 6 | #include 7 | 8 | // initialize sf_malloc/sf_free with the standard malloc/free 9 | sf_malloc_func sf_malloc = malloc; 10 | sf_free_func sf_free = free; 11 | -------------------------------------------------------------------------------- /src/synth_dc.cpp: -------------------------------------------------------------------------------- 1 | #include "synth_dc.h" 2 | 3 | void IRAM_ATTR AudioSynthWaveformDC::update(void) 4 | { 5 | audio_block_t *block; 6 | 7 | block = allocate(); 8 | if (block) { 9 | for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) { 10 | block->data[i] = dcValue; 11 | } 12 | 13 | AudioStream::transmit(block); 14 | AudioStream::release(block); 15 | } 16 | } -------------------------------------------------------------------------------- /lib/sndfilter/wav.h: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc 2 | // MIT License 3 | // Project Home: https://github.com/voidqk/sndfilter 4 | 5 | // simple .wav file loading and saving 6 | // only handles loading 1 or 2 channel WAVs with 16-bit samples 7 | // only saves 2 channel WAVs with 16-bit samples 8 | 9 | #ifndef SNDFILTER_WAV__H 10 | #define SNDFILTER_WAV__H 11 | 12 | #include "snd.h" 13 | 14 | sf_snd sf_wavload(const char *file); 15 | bool sf_wavsave(sf_snd snd, const char *file); 16 | 17 | #endif // SNDFILTER_WAV__H 18 | -------------------------------------------------------------------------------- /lib/sndfilter/mem.h: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc 2 | // MIT License 3 | // Project Home: https://github.com/voidqk/sndfilter 4 | 5 | // memory management 6 | 7 | #ifndef SNDFILTER_MEM__H 8 | #define SNDFILTER_MEM__H 9 | 10 | #include 11 | 12 | typedef void *(*sf_malloc_func)(size_t size); 13 | typedef void (*sf_free_func)(void *ptr); 14 | 15 | // overwrite these globals to change the malloc/free functions of the library 16 | extern sf_malloc_func sf_malloc; 17 | extern sf_free_func sf_free; 18 | 19 | #endif // SNDFILTER_MEM__H 20 | -------------------------------------------------------------------------------- /include/Audio.h: -------------------------------------------------------------------------------- 1 | #ifndef Audio_h_ 2 | #define Audio_h_ 3 | 4 | // include all the library headers, so a sketch can use a single 5 | // #include to get the whole library 6 | 7 | #include "control_i2s.h" 8 | #include "effect_calibration.h" 9 | #include "effect_compressor.h" 10 | #include "effect_delay.h" 11 | #include "effect_envelope.h" 12 | #include "effect_multiply.h" 13 | #include "input_i2s.h" 14 | #include "mixer.h" 15 | #include "output_i2s.h" 16 | #include "play_sdmmc_wav.h" 17 | #include "record_psram.h" 18 | #include "synth_dc.h" 19 | #include "synth_sine.h" 20 | 21 | #endif -------------------------------------------------------------------------------- /include/output_i2s.h: -------------------------------------------------------------------------------- 1 | #ifndef output_i2s_h_ 2 | #define output_i2s_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "freertos/FreeRTOS.h" 6 | #include "driver/i2s.h" 7 | #include "control_i2s.h" 8 | 9 | class AudioOutputI2S : public AudioStream 10 | { 11 | public: 12 | AudioOutputI2S(void) : AudioStream(2, inputQueueArray, "AudioOutputI2S") { blockingObjectRunning = true; blocking = true; initialised = true; } //blockingObjectRunning - let's the audiostream loop know that something will throttle the loop 13 | virtual void update(void); 14 | private: 15 | //void init(void); 16 | audio_block_t *inputQueueArray[2]; 17 | int32_t outputSampleBuffer[AUDIO_BLOCK_SAMPLES * 2]; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /include/synth_dc.h: -------------------------------------------------------------------------------- 1 | #ifndef synth_dc_h_ 2 | #define synth_dc_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "freertos/FreeRTOS.h" 6 | 7 | class AudioSynthWaveformDC : public AudioStream 8 | { 9 | //GUI: inputs:0, outputs:1 //this line used for automatic generation of GUI node 10 | //GUI: shortName:dc //this line used for automatic generation of GUI node 11 | public: 12 | AudioSynthWaveformDC() : AudioStream(0, NULL, "AudioSynthWaveformDC"), dcValue(0.0) { initialised = true; } 13 | virtual void update(void); 14 | void value(float n) { 15 | if (n < -1.0f) n = -1.0f; 16 | else if (n > 1.0f) n = 1.0f; 17 | dcValue = n; 18 | } 19 | private: 20 | float dcValue; 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /lib/sndfilter/snd.h: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc 2 | // MIT License 3 | // Project Home: https://github.com/voidqk/sndfilter 4 | 5 | // data structure for a 2-channel 32-bit floating point sound in memory 6 | 7 | #ifndef SNDFILTER_SND__H 8 | #define SNDFILTER_SND__H 9 | 10 | #include 11 | 12 | typedef struct { 13 | float L; // left channel sample 14 | float R; // right channel sample 15 | } sf_sample_st; 16 | 17 | typedef struct { 18 | sf_sample_st *samples; 19 | int size; // number of samples 20 | int rate; // samples per second 21 | } sf_snd_st, *sf_snd; 22 | 23 | sf_snd sf_snd_new(int size, int rate, bool clear); 24 | void sf_snd_free(sf_snd snd); 25 | 26 | #endif // SNDFILTER_SND__H 27 | -------------------------------------------------------------------------------- /include/control_i2s.h: -------------------------------------------------------------------------------- 1 | #ifndef control_i2s_h_ 2 | #define control_i2s_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "freertos/FreeRTOS.h" 6 | #include "driver/i2s.h" 7 | #include "output_i2s.h" 8 | #include "input_i2s.h" 9 | #include "esp_log.h" 10 | 11 | #define MCLK (AUDIO_SAMPLE_RATE_EXACT * 384) 12 | 13 | class AudioControlI2S 14 | { 15 | public: 16 | AudioControlI2S(void){} 17 | virtual ~AudioControlI2S(); 18 | void init(i2s_port_t i2s_port, i2s_config_t* i2s_config, i2s_pin_config_t* i2s_pin_config, bool outputMCLK); 19 | void init_default_codec_rx_tx_24bit(); 20 | void init_default_adc_dac(); 21 | friend class AudioInputI2S; 22 | friend class AudioOutputI2S; 23 | protected: 24 | static bool initialised; 25 | static uint8_t bits; 26 | }; 27 | 28 | #endif -------------------------------------------------------------------------------- /lib/sndfilter/snd.c: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc 2 | // MIT License 3 | // Project Home: https://github.com/voidqk/sndfilter 4 | 5 | #include "snd.h" 6 | #include "mem.h" 7 | #include 8 | 9 | sf_snd sf_snd_new(int size, int rate, bool clear){ 10 | sf_snd snd = sf_malloc(sizeof(sf_snd_st)); 11 | if (snd == NULL) 12 | return NULL; 13 | snd->size = size; 14 | snd->rate = rate; 15 | snd->samples = sf_malloc(sizeof(sf_sample_st) * size); 16 | if (snd->samples == NULL){ 17 | sf_free(snd); 18 | return NULL; 19 | } 20 | if (clear && size > 0) 21 | memset(snd->samples, 0, sizeof(sf_sample_st) * size); 22 | return snd; 23 | } 24 | 25 | void sf_snd_free(sf_snd snd){ 26 | sf_free(snd->samples); 27 | sf_free(snd); 28 | } 29 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | SRCS 3 | src/AudioStream.cpp 4 | src/control_i2s.cpp 5 | src/data_waveforms.c 6 | src/effect_calibration.cpp 7 | src/effect_compressor.cpp 8 | lib/dr_wav/dr_wav.h 9 | src/effect_delay.cpp 10 | src/effect_envelope.cpp 11 | src/effect_multiply.cpp 12 | src/input_i2s.cpp 13 | src/mixer.cpp 14 | src/output_i2s.cpp 15 | #src/play_sdmmc_wav.cpp 16 | #src/record_flash.cpp 17 | src/record_psram.cpp 18 | src/synth_dc.cpp 19 | src/synth_sine.cpp 20 | INCLUDE_DIRS include 21 | PRIV_INCLUDE_DIRS "lib/dr_wav") 22 | 23 | # Edit following two lines to set component requirements (see docs) 24 | #set(COMPONENT_REQUIRES ) 25 | #set(COMPONENT_PRIV_REQUIRES ) 26 | 27 | #set(COMPONENT_SRCS "src" "lib/dr_wav") 28 | #set(COMPONENT_ADD_INCLUDEDIRS "include") 29 | #set(COMPONENT_PRIV_INCLUDEDIRS "lib/dr_wav") 30 | 31 | #register_component() -------------------------------------------------------------------------------- /gui/red/ui/state.js: -------------------------------------------------------------------------------- 1 | /** Modified from original Node-Red source, for audio system visualization 2 | * vim: set ts=4: 3 | * Copyright 2013 IBM Corp. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | **/ 17 | RED.state = { 18 | DEFAULT: 0, 19 | MOVING: 1, 20 | JOINING: 2, 21 | MOVING_ACTIVE: 3, 22 | ADDING: 4, 23 | EDITING: 5, 24 | EXPORT: 6, 25 | IMPORT: 7, 26 | IMPORT_DRAGGING: 8 27 | } 28 | -------------------------------------------------------------------------------- /gui/red/storage.js: -------------------------------------------------------------------------------- 1 | /* public domain 2 | * vim: set ts=4: 3 | */ 4 | 5 | RED.storage = (function() { 6 | function update() { 7 | // TOOD: use setTimeout to limit the rate of changes? 8 | if (localStorage) { 9 | var nns = RED.nodes.createCompleteNodeSet(); 10 | localStorage.setItem("audio_library_guitool", JSON.stringify(nns)); 11 | //console.log("localStorage write"); 12 | } 13 | } 14 | function load() { 15 | if (localStorage) { 16 | var data = localStorage.getItem("audio_library_guitool"); 17 | //console.log("localStorage read: " + data); 18 | if (data) RED.nodes.import(data, false); 19 | } 20 | } 21 | function clear() { 22 | // TOOD: use setTimeout to limit the rate of changes? 23 | if (localStorage) { 24 | localStorage.removeItem("audio_library_guitool"); 25 | //console.log("localStorage write"); 26 | } 27 | } 28 | return { 29 | update: update, 30 | load: load, 31 | clear: clear 32 | } 33 | })(); 34 | -------------------------------------------------------------------------------- /include/record_flash.h: -------------------------------------------------------------------------------- 1 | #ifndef record_flash_h_ 2 | #define record_flash_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "freertos/FreeRTOS.h" 6 | #include "esp_log.h" 7 | #include "esp_partition.h" 8 | 9 | class AudioRecordFlash : public AudioStream 10 | { 11 | public: 12 | AudioRecordFlash(void) : AudioStream(1, inputQueueArray, "AudioRecordFlash") { } 13 | virtual void update(void); 14 | void startRecord() { playing = false; recordPointer = 0; record = true; printf("Start Record\n"); } 15 | void stopRecord() { record = false; printf("Stop Record\n"); } 16 | void play() { record = false; playPointer = 0; playing = true; printf("Play\n");} 17 | void stop() { playing = false; } 18 | private: 19 | void init(); 20 | audio_block_t *inputQueueArray[1]; 21 | bool initialised = false; 22 | const esp_partition_t *data_partition = NULL; 23 | bool record = false; 24 | bool playing = false; 25 | int recordPointer = 0; 26 | int playPointer = 0; 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /include/record_psram.h: -------------------------------------------------------------------------------- 1 | #ifndef record_psram_h_ 2 | #define record_psram_h_ 3 | 4 | #include "AudioStream.h" 5 | //#include "esp_spiram.h" 6 | #include "freertos/FreeRTOS.h" 7 | 8 | #define RECORD_PSRAM_BLOCK_MAX (AUDIO_SAMPLE_RATE_EXACT / AUDIO_BLOCK_SAMPLES) * 10 9 | 10 | class AudioRecordPSRAM : public AudioStream 11 | { 12 | public: 13 | AudioRecordPSRAM(void) : AudioStream(1, inputQueueArray, "AudioRecordPSRAM") { } 14 | virtual void update(void); 15 | void startRecord() { playing = false; recordPointer = 0; record = true; printf("Start Record\n"); } 16 | void stopRecord() { record = false; printf("Stop Record\n"); } 17 | void play() { record = false; playPointer = 0; playing = true; printf("Play\n");} 18 | void stop() { playing = false; } 19 | private: 20 | void init(int num); 21 | audio_block_t *inputQueueArray[1]; 22 | audio_block_t *buffer; 23 | bool record = false; 24 | bool playing = false; 25 | int recordPointer = 0; 26 | int playPointer = 0; 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /include/input_i2s.h: -------------------------------------------------------------------------------- 1 | #ifndef input_i2s_h_ 2 | #define input_i2s_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "freertos/FreeRTOS.h" 6 | #include "driver/i2s.h" 7 | #include "control_i2s.h" 8 | 9 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 10 | 11 | class AudioInputI2S : public AudioStream 12 | { 13 | public: 14 | AudioInputI2S() : AudioStream(0, NULL, "AudioInputI2S") { blockingObjectRunning = true; blocking = true; initialised = true; } //blockingObjectRunning - let's the audiostream loop know that something will throttle the loop 15 | virtual void update(void); 16 | private: 17 | int32_t inputSampleBuffer[AUDIO_BLOCK_SAMPLES * 2]; 18 | unsigned char reverse(unsigned char b) { 19 | b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; 20 | b = (b & 0xCC) >> 2 | (b & 0x33) << 2; 21 | b = (b & 0xAA) >> 1 | (b & 0x55) << 1; 22 | return b; 23 | } 24 | union foo 25 | { 26 | int32_t integer; 27 | uint8_t byte[4]; 28 | }; 29 | }; 30 | 31 | 32 | 33 | #endif -------------------------------------------------------------------------------- /include/effect_calibration.h: -------------------------------------------------------------------------------- 1 | #ifndef effect_calibration_h_ 2 | #define effect_calibration_h_ 3 | #include "AudioStream.h" 4 | #include "esp_log.h" 5 | 6 | class AudioEffectCalibration : public AudioStream 7 | { 8 | public: 9 | AudioEffectCalibration() : AudioStream(1, inputQueueArray, "AudioEffectCalibration"), m(1), c(0) { initialised = true; } 10 | 11 | void calibrate(float zeroValue, float measuredZero, float fullScaleValue, float measuredFullScaleValue); 12 | 13 | void enableAverage() { inputAverage = 0; outputAverage = 0; averagingEnable = true; } 14 | void disableAverage() { averagingEnable = false; inputAverage = 0; outputAverage = 0; } 15 | float getInputAverage() { return inputAverage; } 16 | float getOutputAverage() { return outputAverage; } 17 | 18 | void inputDC(float value) { inputOverrideValue = value; inputOverrideEnable = true; } 19 | void inputNormal() { inputOverrideEnable = false; } 20 | 21 | virtual void update(void); 22 | private: 23 | bool averagingEnable = false; 24 | float inputAverage, outputAverage; 25 | bool inputOverrideEnable = false; 26 | float inputOverrideValue; 27 | audio_block_t *inputQueueArray[1]; 28 | float m, c; 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /include/play_sdmmc_wav.h: -------------------------------------------------------------------------------- 1 | #ifndef play_sdmmc_wav_h_ 2 | #define play_sdmmc_wav_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "../lib/dr_wav/dr_wav.h" 6 | #include "esp_vfs_fat.h" 7 | #include "driver/sdmmc_host.h" 8 | #include "driver/sdspi_host.h" 9 | #include "sdmmc_cmd.h" 10 | #include 11 | 12 | class AudioPlaySdMmcWav : public AudioStream 13 | { 14 | public: 15 | AudioPlaySdMmcWav(void) : AudioStream(0, NULL, "AudioPlaySdMmcWav") { initialised = true; } 16 | //bool play(const char *filename); 17 | //void stop(void); 18 | //bool isPlaying(void); 19 | //uint32_t positionMillis(void); 20 | //uint32_t lengthMillis(void); 21 | void playFile(const char *filename); 22 | virtual void update(void); 23 | private: 24 | void configure(void); 25 | drwav* pWav; 26 | float* pSampleData = NULL; 27 | bool fileLoaded; 28 | bool playback; 29 | int samplePointer; //Current sample pointer 30 | int sampleBufferSize; //Maximum buffer block size 31 | int fileBlockPointer; //Current buffer block 32 | int fileBlockPointerMax; //Maximum buffer block 33 | static bool configured; //This is used to stop multiple instances instantiating the SD card driver 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/effect_compressor.cpp: -------------------------------------------------------------------------------- 1 | #include "effect_compressor.h" 2 | 3 | void AudioEffectCompressor::defaultSetup(){ 4 | sf_defaultcomp(&compState, AUDIO_SAMPLE_RATE_EXACT); 5 | } 6 | 7 | void AudioEffectCompressor::setupSimple(float pregain, float threshold, float knee, float ratio, float attack, float release) 8 | { 9 | sf_simplecomp(&compState, AUDIO_SAMPLE_RATE_EXACT, pregain, threshold, knee, ratio, attack, release); 10 | } 11 | 12 | void AudioEffectCompressor::setupAdvanced(float pregain, float threshold, float knee, float ratio, float attack, float release, 13 | float predelay, float releasezone1, float releasezone2, float releasezone3, float releasezone4, float postgain, float wet) 14 | { 15 | sf_advancecomp(&compState, AUDIO_SAMPLE_RATE_EXACT, pregain, threshold, knee, ratio, attack, release, 16 | predelay, releasezone1, releasezone2, releasezone3, releasezone4, postgain, wet); 17 | } 18 | 19 | void AudioEffectCompressor::update(void) 20 | { 21 | audio_block_t *blocka; 22 | 23 | blocka = receiveWritable(0); 24 | if (!blocka) { 25 | return; 26 | } 27 | 28 | //sf_compressor_process(&compState, AUDIO_BLOCK_SAMPLES, input, output); 29 | transmit(blocka); 30 | release(blocka); 31 | } 32 | -------------------------------------------------------------------------------- /gui/jquery/js/jquery.ui.touch-punch.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Touch Punch 0.2.3 3 | * 4 | * Copyright 2011–2014, Dave Furfero 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * 7 | * Depends: 8 | * jquery.ui.widget.js 9 | * jquery.ui.mouse.js 10 | */ 11 | !function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); -------------------------------------------------------------------------------- /src/record_psram.cpp: -------------------------------------------------------------------------------- 1 | #include "record_psram.h" 2 | 3 | void AudioRecordPSRAM::init(int num) 4 | { 5 | if(num > RECORD_PSRAM_BLOCK_MAX) 6 | num = RECORD_PSRAM_BLOCK_MAX; 7 | //buffer = (audio_block_t*)ps_calloc(num, sizeof(audio_block_t)); 8 | buffer = (audio_block_t*)heap_caps_malloc(num * sizeof(audio_block_t), MALLOC_CAP_SPIRAM); 9 | printf("AudioRecordPSRAM: %i blocks allocated.\n", num); 10 | } 11 | 12 | void IRAM_ATTR AudioRecordPSRAM::update(void) 13 | { 14 | audio_block_t *block; 15 | 16 | if(!initialised) 17 | { 18 | init(RECORD_PSRAM_BLOCK_MAX); 19 | initialised = true; 20 | } 21 | 22 | if(record) 23 | { 24 | block = receiveReadOnly(); 25 | if (!block) return; 26 | 27 | //printf("Storing audio in buffer %i\n", recordPointer); 28 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 29 | { 30 | buffer[recordPointer].data[i] = block->data[i]; 31 | } 32 | recordPointer++; 33 | 34 | if(recordPointer >= RECORD_PSRAM_BLOCK_MAX) 35 | { 36 | record = false; //Stop recording 37 | recordPointer = RECORD_PSRAM_BLOCK_MAX; 38 | } 39 | 40 | release(block); 41 | } 42 | 43 | if(playing) 44 | { 45 | block = allocate(); 46 | if(!block) return; 47 | 48 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 49 | { 50 | block->data[i] = buffer[playPointer].data[i]; 51 | } 52 | playPointer++; 53 | 54 | if(playPointer >= recordPointer) 55 | { 56 | playing = false; //Stop playing 57 | } 58 | 59 | transmit(block); 60 | release(block); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /include/effect_multiply.h: -------------------------------------------------------------------------------- 1 | /* Audio Library for Teensy 3.X 2 | * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com 3 | * 4 | * Development of this audio library was funded by PJRC.COM, LLC by sales of 5 | * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop 6 | * open source software by purchasing Teensy or other PJRC products. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice, development funding notice, and this permission 16 | * notice shall be included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | #ifndef effect_multiply_h_ 28 | #define effect_multiply_h_ 29 | 30 | #include "AudioStream.h" 31 | 32 | class AudioEffectMultiply : public AudioStream 33 | { 34 | public: 35 | AudioEffectMultiply() : AudioStream(2, inputQueueArray, "AudioEffectMultiply") { initialised = true; } 36 | virtual void update(void); 37 | private: 38 | audio_block_t *inputQueueArray[2]; 39 | }; 40 | 41 | #endif -------------------------------------------------------------------------------- /include/CpuStats.h: -------------------------------------------------------------------------------- 1 | #ifndef cpustats_h_ 2 | #define cpustats_h_ 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | volatile uint32_t idlectrl0 = 0; 11 | float cpu0Load; 12 | float cpu0LoadMax; 13 | void cpu0( void * parameter ) //Gets a new CPU load approx. every 1 second 14 | { 15 | const uint32_t cycleCount = 21818182; //240MHz / 11 16 | uint32_t t00, t01; 17 | 18 | t00 = xthal_get_ccount(); 19 | for(uint32_t i = 0; i < cycleCount; i++) { 20 | idlectrl0++; 21 | } 22 | t01 = xthal_get_ccount(); 23 | 24 | uint32_t cycles_expected = 11 * cycleCount; 25 | uint32_t cycles_used = t01 - t00; 26 | 27 | cpu0Load = 100.0f * (cycles_used - cycles_expected) / cycles_used; 28 | if(cpu0Load > cpu0LoadMax) 29 | cpu0LoadMax = cpu0Load; 30 | } 31 | 32 | volatile uint32_t idlectrl1 = 0; 33 | float cpu1Load; 34 | float cpu1LoadMax; 35 | void cpu1( void * parameter ) //Gets a new CPU load approx. every 1 second 36 | { 37 | const uint32_t cycleCount = 21818182; //240MHz / 11 38 | uint32_t t00, t01; 39 | 40 | t00 = xthal_get_ccount(); 41 | for(uint32_t i = 0; i < cycleCount; i++) { 42 | idlectrl1++; 43 | } 44 | t01 = xthal_get_ccount(); 45 | 46 | uint32_t cycles_expected = 11 * cycleCount; 47 | uint32_t cycles_used = t01 - t00; 48 | 49 | cpu1Load = 100.0f * (cycles_used - cycles_expected) / cycles_used; 50 | if(cpu1Load > cpu1LoadMax) 51 | cpu1LoadMax = cpu1Load; 52 | } 53 | 54 | void StartMonitoringCPU0() 55 | { 56 | esp_register_freertos_idle_hook_for_cpu((esp_freertos_idle_cb_t)cpu0, 0); 57 | } 58 | 59 | void StartMonitoringCPU1() 60 | { 61 | esp_register_freertos_idle_hook_for_cpu((esp_freertos_idle_cb_t)cpu1, 1); 62 | } 63 | 64 | //uint32_t inline IRAM_ATTR cycles() 65 | //{ 66 | // uint32_t ccount; 67 | // __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); 68 | // return ccount; 69 | //} 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif -------------------------------------------------------------------------------- /include/effect_compressor.h: -------------------------------------------------------------------------------- 1 | #ifndef effect_compressor_h_ 2 | #define effect_compressor_h_ 3 | 4 | #include "AudioStream.h" 5 | #include "../lib/sndfilter/compressor.h" 6 | 7 | class AudioEffectCompressor : public AudioStream 8 | { 9 | public: 10 | AudioEffectCompressor() : AudioStream(1, inputQueueArray, "AudioEffectCompressor") { defaultSetup(); initialised = true; } 11 | void setupSimple( 12 | float pregain, // dB, amount to boost the signal before applying compression [0 to 100] 13 | float threshold, // dB, level where compression kicks in [-100 to 0] 14 | float knee, // dB, width of the knee [0 to 40] 15 | float ratio, // unitless, amount to inversely scale the output when applying comp [1 to 20] 16 | float attack, // seconds, length of the attack phase [0 to 1] 17 | float release // seconds, length of the release phase [0 to 1] 18 | ); 19 | void setupAdvanced( 20 | // these parameters are the same as the simple version above: 21 | float pregain, float threshold, float knee, float ratio, float attack, float release, 22 | // these are the advanced parameters: 23 | float predelay, // seconds, length of the predelay buffer [0 to 1] 24 | float releasezone1, // release zones should be increasing between 0 and 1, and are a fraction 25 | float releasezone2, // of the release time depending on the input dB -- these parameters define 26 | float releasezone3, // the adaptive release curve, which is discussed in further detail in the 27 | float releasezone4, // demo: adaptive-release-curve.html 28 | float postgain, // dB, amount of gain to apply after compression [0 to 100] 29 | float wet // amount to apply the effect [0 completely dry to 1 completely wet] 30 | ); 31 | virtual void update(void); 32 | private: 33 | void defaultSetup(); 34 | audio_block_t *inputQueueArray[1]; 35 | sf_compressor_state_st compState; 36 | }; 37 | 38 | #endif -------------------------------------------------------------------------------- /gui/red/ui/notifications.js: -------------------------------------------------------------------------------- 1 | /** Modified from original Node-Red source, for audio system visualization 2 | * vim: set ts=4: 3 | * Copyright 2013 IBM Corp. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | **/ 17 | RED.notify = (function() { 18 | var currentNotifications = []; 19 | var c = 0; 20 | return function(msg,type,fixed,timeout) { 21 | if (currentNotifications.length > 4) { 22 | var ll = currentNotifications.length; 23 | for (var i = 0;ll > 4 && idata[i] *= blockb->data[i]; 47 | } 48 | transmit(blocka); 49 | release(blocka); 50 | release(blockb); 51 | } 52 | -------------------------------------------------------------------------------- /src/effect_calibration.cpp: -------------------------------------------------------------------------------- 1 | #include "effect_calibration.h" 2 | 3 | static const char *TAG = "AudioEffectCalibration"; 4 | 5 | void AudioEffectCalibration::update(void) 6 | { 7 | audio_block_t *blocka; 8 | 9 | blocka = receiveWritable(0); 10 | if(blocka) 11 | { 12 | if(averagingEnable) 13 | { 14 | float sum = 0; 15 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 16 | { 17 | sum += blocka->data[i]; 18 | } 19 | inputAverage = sum/AUDIO_BLOCK_SAMPLES; 20 | } 21 | float temp; 22 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 23 | { 24 | if(inputOverrideEnable) 25 | { 26 | temp = inputOverrideValue; 27 | } 28 | else 29 | { 30 | temp = blocka->data[i]; 31 | } 32 | temp *= m; 33 | temp += c; 34 | blocka->data[i] = temp; 35 | } 36 | if(averagingEnable) 37 | { 38 | float sum = 0; 39 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 40 | { 41 | sum += blocka->data[i]; 42 | } 43 | outputAverage = sum/AUDIO_BLOCK_SAMPLES; 44 | } 45 | transmit(blocka); 46 | release(blocka); 47 | } 48 | } 49 | 50 | void AudioEffectCalibration::calibrate(float zeroValue, float measuredZero, float fullScaleValue, float measuredFullScaleValue) 51 | { 52 | //To do: use zeroValue https://racelogic.support/02VBOX_Motorsport/Video_Data_Loggers/Video_VBOX_Range/Video_VBOX_-_User_manual/24_-_Calculating_Scale_and_Offset 53 | //float scale = fullScaleValue/(measuredFullScaleValue-measuredZero); 54 | //float offset = (scale * measuredZero) / fullScaleValue; 55 | float scale = (fullScaleValue-zeroValue)/(measuredFullScaleValue-measuredZero); 56 | float offset = zeroValue-(measuredZero*scale); 57 | //offset *= -1; 58 | ESP_LOGI(TAG, "M: %f, C: %f.", scale, offset); 59 | m = scale; 60 | c = offset; 61 | } 62 | -------------------------------------------------------------------------------- /gui/red/ui/keyboard.js: -------------------------------------------------------------------------------- 1 | /** Modified from original Node-Red source, for audio system visualization 2 | * vim: set ts=4: 3 | * Copyright 2013 IBM Corp. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | **/ 17 | RED.keyboard = (function() { 18 | 19 | var active = true; 20 | var handlers = {}; 21 | 22 | d3.select(window).on("keydown",function() { 23 | if (!active) { return; } 24 | var handler = handlers[d3.event.keyCode]; 25 | if (handler && handler.ondown) { 26 | if (!handler.modifiers || 27 | ((!handler.modifiers.shift || d3.event.shiftKey) && 28 | (!handler.modifiers.ctrl || d3.event.ctrlKey ) && 29 | (!handler.modifiers.alt || d3.event.altKey ) )) { 30 | handler.ondown(); 31 | } 32 | } 33 | }); 34 | d3.select(window).on("keyup",function() { 35 | if (!active) { return; } 36 | var handler = handlers[d3.event.keyCode]; 37 | if (handler && handler.onup) { 38 | if (!handler.modifiers || 39 | ((!handler.modifiers.shift || d3.event.shiftKey) && 40 | (!handler.modifiers.ctrl || d3.event.ctrlKey ) && 41 | (!handler.modifiers.alt || d3.event.altKey ) )) { 42 | handler.onup(); 43 | } 44 | } 45 | }); 46 | function addHandler(key,modifiers,ondown,onup) { 47 | var mod = modifiers; 48 | var cbdown = ondown; 49 | var cbup = onup; 50 | 51 | if (typeof modifiers == "function") { 52 | mod = {}; 53 | cbdown = modifiers; 54 | cbup = ondown; 55 | } 56 | handlers[key] = {modifiers:mod, ondown:cbdown, onup:cbup}; 57 | } 58 | function removeHandler(key) { 59 | delete handlers[key]; 60 | } 61 | 62 | return { 63 | add: addHandler, 64 | remove: removeHandler, 65 | disable: function(){ active = false;}, 66 | enable: function(){ active = true; } 67 | } 68 | 69 | })(); 70 | -------------------------------------------------------------------------------- /include/CpuDisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef cpudisplay_h_ 2 | #define cpudisplay_h_ 3 | 4 | #include "AudioStream.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #ifndef F_CPU 11 | #define F_CPU (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000U) 12 | #endif 13 | 14 | unsigned long IRAM_ATTR millis() 15 | { 16 | return (unsigned long) (esp_timer_get_time() / 1000); 17 | } 18 | 19 | void cpuDisplay() 20 | { 21 | const float maxTicksPerUpdate = (((float)F_CPU) / 44100.0f) * 128.0f; 22 | AudioStream *p; 23 | printf("%lu ms uptime\r\n\r\n", millis()); 24 | printf("CPU 0 %5.2f%% [%5.2f%% max] \r\n", cpu0Load, cpu0LoadMax); 25 | printf("CPU 1 %5.2f%% [%5.2f%% max] \r\n\r\n", cpu1Load, cpu1LoadMax); 26 | int clocks, clocksMax, clocksSec; 27 | float load, loadMax, loadSec; 28 | int totalClocks = 0, totalClocksMax = 0; 29 | printf(" | Per Update | Per Second |\r\n"); 30 | printf("%-31s %6s %7s %6s %6s %9s\r\n", "Audio Object", "Min %", "Clocks", "Max %", "%", "Clocks"); 31 | printf("----------------------------------------------------------------------\r\n"); 32 | for (p = AudioStream::first_update; p; p = p->next_update) { 33 | if (p->active) { 34 | if(!p->blocking){ 35 | clocks = p->clocksPerUpdateMin; 36 | clocksMax = p->clocksPerUpdateMax; 37 | clocksSec = p->clocksPerSecond; 38 | load = 100.0f * ((float)clocks / maxTicksPerUpdate); 39 | loadMax = 100.0f * ((float)clocksMax / maxTicksPerUpdate); 40 | loadSec = 100.0f * ((float)clocksSec/((float)F_CPU)); 41 | printf("%-31s %6.2f %7i %6.2f %6.2f %9i\r\n", p->name, load, clocks, loadMax, loadSec, clocksSec); 42 | totalClocks += clocks; 43 | totalClocksMax += clocksMax; 44 | } 45 | else{ 46 | printf("%-31s %6s %7s %6s %6s %9s\r\n", p->name, "-", "-", "-", "-", "-"); 47 | } 48 | } 49 | } 50 | printf(" ---------------------\r\n"); 51 | printf("%31s %6.2f %7i %6.2f\r\n", "", 100.0f * ((float)totalClocks / maxTicksPerUpdate), totalClocks, 100.0f * ((float)totalClocksMax / maxTicksPerUpdate)); 52 | } 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif -------------------------------------------------------------------------------- /lib/sndfilter/biquad.h: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc 2 | // MIT License 3 | // Project Home: https://github.com/voidqk/sndfilter 4 | 5 | // biquad filtering based on WebAudio specification: 6 | // https://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface 7 | 8 | #ifndef SNDFILTER_BIQUAD__H 9 | #define SNDFILTER_BIQUAD__H 10 | 11 | #include "snd.h" 12 | 13 | // biquad filtering is a technique used to perform a variety of sound filters 14 | // 15 | // this API works by first initializing an sf_biquad_state_st structure, and then using it to 16 | // process a sample in chunks 17 | // 18 | // for example, for a lowpass filter over a stream with 128 samples per chunk, you would do: 19 | // 20 | // sf_biquad_state_st lowpass; 21 | // sf_lowpass(&lowpass, 44100, 440, 1); 22 | // 23 | // for each 128 length sample: 24 | // sf_biquad_process(&lowpass, 128, input, output); 25 | // 26 | // notice that sf_biquad_process will change the xn1,xn2,yn1,yn2 values inside of the state 27 | // structure, since these values must be carried over across chunk boundaries 28 | // 29 | // also notice that the choice to divide the sound into chunks of 128 samples is completely 30 | // arbitrary from the filter's perspective 31 | 32 | typedef struct { 33 | float b0; 34 | float b1; 35 | float b2; 36 | float a1; 37 | float a2; 38 | sf_sample_st xn1; 39 | sf_sample_st xn2; 40 | sf_sample_st yn1; 41 | sf_sample_st yn2; 42 | } sf_biquad_state_st; 43 | 44 | // these functions will initialize an sf_biquad_state_st structure based on the desired filter 45 | void sf_lowpass (sf_biquad_state_st *state, int rate, float cutoff, float resonance); 46 | void sf_highpass (sf_biquad_state_st *state, int rate, float cutoff, float resonance); 47 | void sf_bandpass (sf_biquad_state_st *state, int rate, float freq, float Q); 48 | void sf_notch (sf_biquad_state_st *state, int rate, float freq, float Q); 49 | void sf_peaking (sf_biquad_state_st *state, int rate, float freq, float Q, float gain); 50 | void sf_allpass (sf_biquad_state_st *state, int rate, float freq, float Q); 51 | void sf_lowshelf (sf_biquad_state_st *state, int rate, float freq, float Q, float gain); 52 | void sf_highshelf(sf_biquad_state_st *state, int rate, float freq, float Q, float gain); 53 | 54 | // this function will process the input sound based on the state passed 55 | // the input and output buffers should be the same size 56 | void sf_biquad_process(sf_biquad_state_st *state, int size, sf_sample_st *input, 57 | sf_sample_st *output); 58 | 59 | #endif // SNDFILTER_BIQUAD__H 60 | -------------------------------------------------------------------------------- /src/data_waveforms.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // These audio waveforms have a period of 256 points, plus a 257th 4 | // point that is a duplicate of the first point. This duplicate 5 | // is needed because the waveform generator uses linear interpolation 6 | // between each point and the next point in the waveform. 7 | 8 | const float AudioWaveformSine[257] = { 9 | 0.00000,0.02454,0.04907,0.07356,0.09802,0.12241,0.14673,0.17096,0.19509,0.21910, 10 | 0.24298,0.26671,0.29028,0.31368,0.33689,0.35990,0.38268,0.40524,0.42756,0.44961, 11 | 0.47140,0.49290,0.51410,0.53500,0.55557,0.57581,0.59570,0.61523,0.63439,0.65317, 12 | 0.67156,0.68954,0.70711,0.72425,0.74095,0.75721,0.77301,0.78835,0.80321,0.81758, 13 | 0.83147,0.84485,0.85773,0.87009,0.88192,0.89322,0.90399,0.91421,0.92388,0.93299, 14 | 0.94154,0.94953,0.95694,0.96378,0.97003,0.97570,0.98079,0.98528,0.98918,0.99248, 15 | 0.99518,0.99729,0.99880,0.99970,1.00000,0.99970,0.99880,0.99729,0.99518,0.99248, 16 | 0.98918,0.98528,0.98079,0.97570,0.97003,0.96378,0.95694,0.94953,0.94154,0.93299, 17 | 0.92388,0.91421,0.90399,0.89322,0.88192,0.87009,0.85773,0.84485,0.83147,0.81758, 18 | 0.80321,0.78835,0.77301,0.75721,0.74095,0.72425,0.70711,0.68954,0.67156,0.65317, 19 | 0.63439,0.61523,0.59570,0.57581,0.55557,0.53500,0.51410,0.49290,0.47140,0.44961, 20 | 0.42756,0.40524,0.38268,0.35990,0.33689,0.31368,0.29028,0.26671,0.24298,0.21910, 21 | 0.19509,0.17096,0.14673,0.12241,0.09802,0.07356,0.04907,0.02454,0.00000,-0.02454, 22 | -0.04907,-0.07356,-0.09802,-0.12241,-0.14673,-0.17096,-0.19509,-0.21910,-0.24298,-0.26671, 23 | -0.29028,-0.31368,-0.33689,-0.35990,-0.38268,-0.40524,-0.42756,-0.44961,-0.47140,-0.49290, 24 | -0.51410,-0.53500,-0.55557,-0.57581,-0.59570,-0.61523,-0.63439,-0.65317,-0.67156,-0.68954, 25 | -0.70711,-0.72425,-0.74095,-0.75721,-0.77301,-0.78835,-0.80321,-0.81758,-0.83147,-0.84485, 26 | -0.85773,-0.87009,-0.88192,-0.89322,-0.90399,-0.91421,-0.92388,-0.93299,-0.94154,-0.94953, 27 | -0.95694,-0.96378,-0.97003,-0.97570,-0.98079,-0.98528,-0.98918,-0.99248,-0.99518,-0.99729, 28 | -0.99880,-0.99970,-1.00000,-0.99970,-0.99880,-0.99729,-0.99518,-0.99248,-0.98918,-0.98528, 29 | -0.98079,-0.97570,-0.97003,-0.96378,-0.95694,-0.94953,-0.94154,-0.93299,-0.92388,-0.91421, 30 | -0.90399,-0.89322,-0.88192,-0.87009,-0.85773,-0.84485,-0.83147,-0.81758,-0.80321,-0.78835, 31 | -0.77301,-0.75721,-0.74095,-0.72425,-0.70711,-0.68954,-0.67156,-0.65317,-0.63439,-0.61523, 32 | -0.59570,-0.57581,-0.55557,-0.53500,-0.51410,-0.49290,-0.47140,-0.44961,-0.42756,-0.40524, 33 | -0.38268,-0.35990,-0.33689,-0.31368,-0.29028,-0.26671,-0.24298,-0.21910,-0.19509,-0.17096, 34 | -0.14673,-0.12241,-0.09802,-0.07356,-0.04907,-0.02454,0.00000 35 | }; 36 | -------------------------------------------------------------------------------- /src/input_i2s.cpp: -------------------------------------------------------------------------------- 1 | #include "input_i2s.h" 2 | 3 | void IRAM_ATTR AudioInputI2S::update(void) 4 | { 5 | audio_block_t *new_left=NULL, *new_right=NULL; 6 | 7 | if(AudioControlI2S::initialised) 8 | { 9 | new_left = allocate(); 10 | if (new_left != NULL) { 11 | new_right = allocate(); 12 | if (new_right == NULL) { 13 | release(new_left); 14 | new_left = NULL; 15 | } 16 | } 17 | 18 | //Serial.println("update"); 19 | 20 | size_t bytesRead = 0; 21 | //i2s_adc_enable(I2S_NUM_0); 22 | switch(AudioControlI2S::bits) 23 | { 24 | case 16: 25 | i2s_read(I2S_NUM_0, (char*)&inputSampleBuffer, (AUDIO_BLOCK_SAMPLES * sizeof(uint32_t)), &bytesRead, portMAX_DELAY); //Block but yield to other tasks 26 | break; 27 | case 24: 28 | case 32: 29 | i2s_read(I2S_NUM_0, (char*)&inputSampleBuffer, (AUDIO_BLOCK_SAMPLES * sizeof(uint32_t)) * 2, &bytesRead, portMAX_DELAY); //Block but yield to other tasks 30 | break; 31 | default: 32 | printf("Unknown bit depth\n"); 33 | break; 34 | } 35 | //i2s_adc_disable(I2S_NUM_0); 36 | 37 | switch(AudioControlI2S::bits) 38 | { 39 | case 16: 40 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 41 | { 42 | if(new_left != NULL) 43 | { 44 | new_left->data[i] = ((float)(inputSampleBuffer[i] & 0xfff)/2048.0f) - 1.0f; 45 | } 46 | } 47 | break; 48 | case 24: 49 | union foo input; 50 | union foo output; 51 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 52 | { 53 | if(new_left != NULL) 54 | { 55 | input.integer = inputSampleBuffer[i*2]; 56 | output.byte[0] = input.byte[1]; 57 | output.byte[1] = input.byte[2]; 58 | output.byte[2] = input.byte[3]; 59 | if(CHECK_BIT(output.byte[2], 7)) 60 | { 61 | output.byte[3] = 0xFF; 62 | } 63 | else 64 | output.byte[3] = 0x00; 65 | new_left->data[i] = ((float)output.integer)/8388608.0f; 66 | } 67 | if(new_right != NULL) 68 | { 69 | input.integer = inputSampleBuffer[i*2 + 1]; 70 | output.byte[0] = input.byte[1]; 71 | output.byte[1] = input.byte[2]; 72 | output.byte[2] = input.byte[3]; 73 | if(CHECK_BIT(output.byte[2], 7)) 74 | { 75 | output.byte[3] = 0xFF; 76 | } 77 | else 78 | output.byte[3] = 0x00; 79 | new_right->data[i] = ((float)output.integer)/8388608.0f; 80 | } 81 | //printf("%f\n", new_out->data[i]); 82 | } 83 | //printf("0x%08x %d\n", output.integer, output.integer); 84 | //printf("%f\n", new_left->data[0]); 85 | break; 86 | } 87 | transmit(new_left, 0); 88 | release(new_left); 89 | transmit(new_right, 1); 90 | release(new_right); 91 | } 92 | } -------------------------------------------------------------------------------- /src/record_flash.cpp: -------------------------------------------------------------------------------- 1 | #include "record_flash.h" 2 | 3 | #define PARTITION_NAME "storage" 4 | 5 | //flash record size, for recording 5 seconds' data 6 | #define I2S_CHANNEL_NUM 1 7 | #define FLASH_RECORD_SIZE (I2S_CHANNEL_NUM * AUDIO_SAMPLE_RATE_EXACT * 32 / 8 * 1) 8 | #define FLASH_SECTOR_SIZE (0x1000) 9 | #define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE) 10 | #define MAX_RECORD 4194304 11 | #define AUDIO_BYTES AUDIO_BLOCK_SAMPLES * sizeof(float) 12 | 13 | static const char *TAG = "record_flash"; 14 | 15 | void AudioRecordFlash::init() 16 | { 17 | printf("Erasing flash \n"); 18 | data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, PARTITION_NAME); 19 | if (data_partition != NULL) 20 | { 21 | printf("partiton addr: 0x%08x; size: %d; label: %s\n", data_partition->address, data_partition->size, data_partition->label); 22 | } 23 | else 24 | { 25 | ESP_LOGE(TAG, "Partition error: can't find partition name: %s\n", PARTITION_NAME); 26 | return; 27 | } 28 | printf("Erase size: %d Bytes\n", FLASH_ERASE_SIZE); 29 | //ESP_ERROR_CHECK(esp_partition_erase_range(data_partition, 0, FLASH_ERASE_SIZE)); 30 | } 31 | 32 | void IRAM_ATTR AudioRecordFlash::update(void) 33 | { 34 | audio_block_t *block; 35 | 36 | if(!initialised) 37 | { 38 | init(); 39 | initialised = true; 40 | } 41 | 42 | if(record) 43 | { 44 | block = receiveReadOnly(); 45 | if (!block) return; 46 | 47 | if (data_partition != NULL) 48 | { 49 | printf("Writing to partition\n"); 50 | esp_partition_write(data_partition, recordPointer, (char *)block->data, AUDIO_BYTES); 51 | printf("Finished writing to partition\n"); 52 | recordPointer += AUDIO_BYTES; 53 | if(recordPointer >= MAX_RECORD) 54 | { 55 | record = false; 56 | } 57 | } 58 | 59 | release(block); 60 | } 61 | 62 | if(playing) 63 | { 64 | block = allocate(); 65 | if(!block) return; 66 | 67 | if (data_partition != NULL) 68 | { 69 | printf("Reading from partition\n"); 70 | esp_partition_read(data_partition, playPointer, (char *)block->data, AUDIO_BYTES); 71 | playPointer += AUDIO_BYTES; 72 | if(playPointer >= recordPointer) 73 | { 74 | playing = false; 75 | printf("Ran out of things to play.\n"); 76 | } 77 | } 78 | 79 | transmit(block); 80 | release(block); 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /src/output_i2s.cpp: -------------------------------------------------------------------------------- 1 | #include "output_i2s.h" 2 | 3 | void IRAM_ATTR AudioOutputI2S::update(void) 4 | { 5 | audio_block_t *block_left, *block_right; 6 | 7 | if(AudioControlI2S::initialised) 8 | { 9 | block_left = receiveReadOnly(0); // input 0 10 | block_right = receiveReadOnly(1); // input 1 11 | 12 | switch(AudioControlI2S::bits) 13 | { 14 | case 16: 15 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 16 | { 17 | int16_t sample[2]; 18 | if(block_left) 19 | sample[0] = (int16_t)(block_left->data[i] * 32767.0f); 20 | else 21 | sample[0] = 0; 22 | if(block_right) 23 | sample[1] = (int16_t)(block_right->data[i] * 32767.0f); 24 | else 25 | sample[1] = 0; 26 | 27 | outputSampleBuffer[i] = (((sample[1]+ 0x8000)<<16) | ((sample[0]+ 0x8000) & 0xffff)); 28 | } 29 | break; 30 | case 24: 31 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 32 | { 33 | if(block_left) 34 | outputSampleBuffer[i*2] = (-((int32_t)(block_left->data[i] * 8388608.0f))) << 8; 35 | else 36 | outputSampleBuffer[i*2] = 0; 37 | 38 | if(block_right) 39 | outputSampleBuffer[i*2 + 1] = (-((int32_t)(block_right->data[i] * 8388608.0f))) << 8; 40 | else 41 | outputSampleBuffer[i*2 + 1] = 0; 42 | } 43 | break; 44 | case 32: 45 | for(int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) 46 | { 47 | if(block_left) 48 | outputSampleBuffer[i*2] = ((int32_t)(block_left->data[i] * 1073741823.0f)); 49 | else 50 | outputSampleBuffer[i*2] = 0; 51 | 52 | if(block_right) 53 | outputSampleBuffer[i*2 + 1] = ((int32_t)(block_right->data[i] * 1073741823.0f)); 54 | else 55 | outputSampleBuffer[i*2 + 1] = 0; 56 | } 57 | break; 58 | default: 59 | printf("Unknown bit depth\n"); 60 | break; 61 | } 62 | 63 | size_t totalBytesWritten = 0; 64 | size_t bytesWritten = 0; 65 | for(;;) 66 | { 67 | switch(AudioControlI2S::bits) 68 | { 69 | case 16: 70 | i2s_write(I2S_NUM_0, (const char*)&outputSampleBuffer, (AUDIO_BLOCK_SAMPLES * sizeof(uint32_t)), &bytesWritten, portMAX_DELAY); //Block but yield to other tasks 71 | break; 72 | case 24: 73 | case 32: 74 | i2s_write(I2S_NUM_0, (const char*)&outputSampleBuffer, (AUDIO_BLOCK_SAMPLES * sizeof(uint32_t)) * 2, &bytesWritten, portMAX_DELAY); //Block but yield to other tasks 75 | break; 76 | default: 77 | printf("Unknown bit depth\n"); 78 | break; 79 | } 80 | totalBytesWritten += bytesWritten; 81 | if(totalBytesWritten >= (AUDIO_BLOCK_SAMPLES * sizeof(uint32_t))) 82 | break; 83 | vPortYield(); 84 | } 85 | 86 | if (block_left) release(block_left); 87 | if (block_right) release(block_right); 88 | 89 | //if (update_responsibility) AudioStream::update_all(); 90 | //AudioStream::update_all(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /gui/red/ui/tab-config.js: -------------------------------------------------------------------------------- 1 | /** Modified from original Node-Red source, for audio system visualization 2 | * vim: set ts=4: 3 | * Copyright 2013 IBM Corp. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | **/ 17 | RED.sidebar.config = (function() { 18 | 19 | var content = document.createElement("div"); 20 | content.id = "tab-config"; 21 | content.style.paddingTop = "4px"; 22 | content.style.paddingLeft = "4px"; 23 | content.style.paddingRight = "4px"; 24 | 25 | var list = $("