├── src ├── data │ ├── FC_def_snd.txt │ ├── 0.mp3 │ ├── 1.mp3 │ ├── 2.mp3 │ ├── 3.mp3 │ ├── 4.mp3 │ ├── 5.mp3 │ ├── 6.mp3 │ ├── 7.mp3 │ ├── 8.mp3 │ ├── 9.mp3 │ ├── dot.mp3 │ ├── alarm.mp3 │ ├── flux.mp3 │ ├── fluxing.mp3 │ ├── renaming.mp3 │ ├── startup.mp3 │ ├── installing.mp3 │ ├── timetravel.mp3 │ └── travelstart.mp3 ├── src │ └── ESP8266Audio │ │ ├── AudioLogger.cpp │ │ ├── libmad │ │ ├── VERSION │ │ ├── COPYRIGHT │ │ ├── mad.h.sed │ │ ├── layer3.h │ │ ├── bit.h │ │ ├── version.h │ │ ├── global.h │ │ ├── README.ESP8266 │ │ ├── TODO │ │ ├── huffman.h │ │ ├── fixed.c │ │ ├── synth.h │ │ ├── version.c │ │ ├── imdct_s.dat.h │ │ ├── decoder.h │ │ ├── timer.h │ │ ├── qc_table.dat.h │ │ ├── frame.h │ │ ├── stream.h │ │ ├── CREDITS │ │ ├── config.h │ │ ├── stream.c │ │ ├── sf_table.dat.h │ │ ├── bit.c │ │ ├── README │ │ ├── CHANGES │ │ └── timer.c │ │ ├── AudioLogger.h │ │ ├── AudioFileSourceSPIFFS.h │ │ ├── AudioFileSourceLittleFS.h │ │ ├── AudioFileSourceSD.h │ │ ├── AudioFileSourceFS.h │ │ ├── AudioFileSourcePROGMEM.h │ │ ├── AudioFileSourceFS.cpp │ │ ├── AudioGenerator.h │ │ ├── AudioFileSource.h │ │ ├── AudioFileSourceSD.cpp │ │ ├── AudioStatus.h │ │ ├── AudioGeneratorWAV.h │ │ ├── AudioOutputI2S.h │ │ ├── AudioFileSourcePROGMEM.cpp │ │ ├── AudioOutput.h │ │ ├── AudioGeneratorMP3.h │ │ ├── AudioGeneratorWAV.cpp │ │ └── AudioOutputI2S.cpp ├── fluxcapacitor-A10001986.ino.nodemcu-32s.bin ├── AudioFileSourceLoop.h ├── fc_wifi.h ├── fc_audio.h ├── fc_main.h ├── AudioFileSourceLoop.cpp ├── fcdisplay.h ├── input.h ├── fc_global.h ├── fc_settings.h ├── mqtt.h └── input.cpp ├── CheatSheet.pdf ├── Flux-Capacitor.code-workspace ├── .gitignore ├── install ├── sound-pack-20230621.zip └── fluxcapacitor-A10001986.ino.nodemcu-32s.bin ├── Hardware ├── flux_capacitor_body.3mf ├── flux_capacitor_door.3mf ├── flux_capacitor_right_dimensions.pdf ├── flux_capacitor_window_dimensions.pdf └── flux_capacitor_top-bottom_dimensions.pdf ├── .vscode └── extensions.json ├── fcirkeys.txt ├── LICENSE └── platformio.ini /src/data/FC_def_snd.txt: -------------------------------------------------------------------------------- 1 | TCD -------------------------------------------------------------------------------- /CheatSheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/CheatSheet.pdf -------------------------------------------------------------------------------- /src/data/0.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/0.mp3 -------------------------------------------------------------------------------- /src/data/1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/1.mp3 -------------------------------------------------------------------------------- /src/data/2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/2.mp3 -------------------------------------------------------------------------------- /src/data/3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/3.mp3 -------------------------------------------------------------------------------- /src/data/4.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/4.mp3 -------------------------------------------------------------------------------- /src/data/5.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/5.mp3 -------------------------------------------------------------------------------- /src/data/6.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/6.mp3 -------------------------------------------------------------------------------- /src/data/7.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/7.mp3 -------------------------------------------------------------------------------- /src/data/8.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/8.mp3 -------------------------------------------------------------------------------- /src/data/9.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/9.mp3 -------------------------------------------------------------------------------- /src/data/dot.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/dot.mp3 -------------------------------------------------------------------------------- /src/data/alarm.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/alarm.mp3 -------------------------------------------------------------------------------- /src/data/flux.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/flux.mp3 -------------------------------------------------------------------------------- /src/data/fluxing.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/fluxing.mp3 -------------------------------------------------------------------------------- /src/data/renaming.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/renaming.mp3 -------------------------------------------------------------------------------- /src/data/startup.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/startup.mp3 -------------------------------------------------------------------------------- /Flux-Capacitor.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /src/data/installing.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/installing.mp3 -------------------------------------------------------------------------------- /src/data/timetravel.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/timetravel.mp3 -------------------------------------------------------------------------------- /src/data/travelstart.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/data/travelstart.mp3 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /install/sound-pack-20230621.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/install/sound-pack-20230621.zip -------------------------------------------------------------------------------- /Hardware/flux_capacitor_body.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/Hardware/flux_capacitor_body.3mf -------------------------------------------------------------------------------- /Hardware/flux_capacitor_door.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/Hardware/flux_capacitor_door.3mf -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioLogger.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "AudioLogger.h" 3 | 4 | DevNullOut silencedLogger; 5 | Print* audioLogger = &silencedLogger; 6 | -------------------------------------------------------------------------------- /Hardware/flux_capacitor_right_dimensions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/Hardware/flux_capacitor_right_dimensions.pdf -------------------------------------------------------------------------------- /Hardware/flux_capacitor_window_dimensions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/Hardware/flux_capacitor_window_dimensions.pdf -------------------------------------------------------------------------------- /Hardware/flux_capacitor_top-bottom_dimensions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/Hardware/flux_capacitor_top-bottom_dimensions.pdf -------------------------------------------------------------------------------- /src/fluxcapacitor-A10001986.ino.nodemcu-32s.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/src/fluxcapacitor-A10001986.ino.nodemcu-32s.bin -------------------------------------------------------------------------------- /install/fluxcapacitor-A10001986.ino.nodemcu-32s.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitSetup/Flux-Capacitor_backup/main/install/fluxcapacitor-A10001986.ino.nodemcu-32s.bin -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/VERSION: -------------------------------------------------------------------------------- 1 | 0.15.1b 2 | configure.ac:24 3 | version.h:25-28 4 | msvc++/config.h:99,105,120 5 | msvc++/mad.h:41-44 6 | 7 | Makefile.am:98-100 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /fcirkeys.txt: -------------------------------------------------------------------------------- 1 | { 2 | "key0":"0x7d168bcf", 3 | "key1":"0xf7283c77", 4 | "key2":"0x757fb4df", 5 | "key3":"0xb33b4597", 6 | "key4":"0x3c03e507", 7 | "key5":"0xe705551f", 8 | "key6":"0xa4a58ec7", 9 | "key7":"0xe2e45f7f", 10 | "key8":"0x6bacfeef", 11 | "key9":"0x0e88e91f", 12 | "keySTAR":"0x86337a52", 13 | "keyHASH":"0xabbe1086", 14 | "keyUP":"0xc20370a1", 15 | "keyDOWN":"0x81930a09", 16 | "keyLEFT":"0x983ab4c1", 17 | "keyRIGHT":"0x21035431", 18 | "keyOK":"0xbb0ed9e1" 19 | } 20 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioLogger.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifndef _AUDIOLOGGER_H 5 | #define _AUDIOLOGGER_H 6 | 7 | class DevNullOut: public Print 8 | { 9 | public: 10 | virtual size_t write(uint8_t) { return 1; } 11 | }; 12 | 13 | extern DevNullOut silencedLogger; 14 | 15 | // Global `audioLogger` is initialized to &silencedLogger 16 | // It can be initialized anytime to &Serial or any other Print:: derivative instance. 17 | extern Print* audioLogger; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/COPYRIGHT: -------------------------------------------------------------------------------- 1 | 2 | libmad - MPEG audio decoder library 3 | Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | If you would like to negotiate alternate licensing terms, you may do 20 | so by contacting: Underbit Technologies, Inc. 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 A10001986 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/mad.h.sed: -------------------------------------------------------------------------------- 1 | # 2 | # libmad - MPEG audio decoder library 3 | # Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | # 19 | # $Id: mad.h.sed,v 1.9 2004/01/23 09:41:32 rob Exp $ 20 | # 21 | 22 | /^\/\*$/{ 23 | N 24 | s/ \* libmad - /&/ 25 | t copy 26 | b next 27 | : copy 28 | g 29 | n 30 | s|^ \* \$\(Id: .*\) \$$|/* \1 */|p 31 | /^ \*\/$/d 32 | b copy 33 | } 34 | /^# *include "/d 35 | : next 36 | p 37 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/layer3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: layer3.h,v 1.10 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_LAYER3_H 23 | # define LIBMAD_LAYER3_H 24 | 25 | # include "stream.h" 26 | # include "frame.h" 27 | 28 | int mad_layer_III(struct mad_stream *, struct mad_frame *); 29 | 30 | # endif 31 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourceSPIFFS.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourceFS 3 | Input Arduion "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOFILESOURCESPIFFS_H 22 | #define _AUDIOFILESOURCESPIFFS_H 23 | 24 | #include 25 | #include 26 | 27 | #include "AudioFileSource.h" 28 | #include "AudioFileSourceFS.h" 29 | 30 | class AudioFileSourceSPIFFS : public AudioFileSourceFS 31 | { 32 | public: 33 | AudioFileSourceSPIFFS() : AudioFileSourceFS(SPIFFS) { }; 34 | AudioFileSourceSPIFFS(const char *filename) : AudioFileSourceFS(SPIFFS, filename) {}; 35 | // Others are inherited from base 36 | }; 37 | 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourceLittleFS.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourceFS 3 | Input Arduion "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOFILESOURCESPIFFS_H 22 | #define _AUDIOFILESOURCESPIFFS_H 23 | 24 | #include 25 | #include 26 | 27 | #include "AudioFileSource.h" 28 | #include "AudioFileSourceFS.h" 29 | 30 | class AudioFileSourceLittleFS : public AudioFileSourceFS 31 | { 32 | public: 33 | AudioFileSourceLittleFS() : AudioFileSourceFS(LittleFS) { }; 34 | AudioFileSourceLittleFS(const char *filename) : AudioFileSourceFS(LittleFS, filename) {}; 35 | // Others are inherited from base 36 | }; 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = esp32dev 13 | data_dir = src/data 14 | 15 | [env:esp32dev] 16 | platform = espressif32 ;@ 6.3.2 17 | framework = arduino 18 | board = nodemcu-32s 19 | platform_packages = 20 | framework-arduinoespressif32 ;@ 2.0.6 21 | board_build.f_cpu = 240000000L 22 | board_build.flash_mode = qio 23 | lib_deps = 24 | ;earlephilhower/ESP8266Audio @ ^1.9.7 25 | gianbacchio/ESP8266Spiram @ ^1.0 26 | https://github.com/tzapu/WiFiManager.git 27 | ArduinoJson @ ^6.19.4 28 | upload_speed = 921600 29 | monitor_speed = 115200 30 | build_flags = 31 | -std=gnu++11 32 | -mtarget-align 33 | ;see tc_global.h for full explanations of these options 34 | -DFC_DBG ;enables serial debug 35 | #-DUSE_SPIFFS ;use SPIFFS for arduinoespressif32 < 2.0, otherwise use LittleFS - If LittleFS uncomment board_build.filesystem below 36 | 37 | board_build.filesystem = LittleFS ;uncomment if using LittleFS - make sure USE_SPIFFS IS commented above 38 | build_src_flags = 39 | -DDEBUG_PORT=Serial 40 | -ggdb 41 | ;uncomment the following to use the esp32 exception decoder 42 | #monitor_filters = esp32_exception_decoder 43 | #build_type = debug -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourceSD.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourceSPIFFS 3 | Input SD card "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOFILESOURCESD_H 22 | #define _AUDIOFILESOURCESD_H 23 | 24 | #include "AudioFileSource.h" 25 | #include 26 | 27 | 28 | class AudioFileSourceSD : public AudioFileSource 29 | { 30 | public: 31 | AudioFileSourceSD(); 32 | AudioFileSourceSD(const char *filename); 33 | virtual ~AudioFileSourceSD() override; 34 | 35 | virtual bool open(const char *filename) override; 36 | virtual uint32_t read(void *data, uint32_t len) override; 37 | virtual bool seek(int32_t pos, int dir) override; 38 | virtual bool close() override; 39 | virtual bool isOpen() override; 40 | virtual uint32_t getSize() override; 41 | virtual uint32_t getPos() override; 42 | 43 | private: 44 | File f; 45 | }; 46 | 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /src/AudioFileSourceLoop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AudioFileSourceLoop 3 | * Read SD/SPIFFS/LittleFS file to be used by AudioGenerator 4 | * Reads file in a loop (for looped playback) 5 | * 6 | * Thomas Winischhofer (A10001986), 2023 7 | * 8 | * Based on AudioFileSourceSD by Earle F. Philhower, III 9 | * 10 | */ 11 | 12 | #ifndef _AudioFileSourceLoop_H 13 | #define _AudioFileSourceLoop_H 14 | 15 | #include "src/ESP8266Audio/AudioFileSource.h" 16 | #include 17 | #ifdef USE_SPIFFS 18 | #include 19 | #else 20 | #include 21 | #endif 22 | 23 | class AudioFileSourceLoop : public AudioFileSource 24 | { 25 | public: 26 | AudioFileSourceLoop(); 27 | virtual ~AudioFileSourceLoop() override; 28 | 29 | //virtual bool open(const char *filename) override; 30 | virtual uint32_t read(void *data, uint32_t len) override; 31 | virtual bool seek(int32_t pos, int dir) override; 32 | virtual bool close() override; 33 | virtual bool isOpen() override; 34 | virtual uint32_t getSize() override; 35 | virtual uint32_t getPos() override; 36 | void setStartPos(int32_t newStartPos); 37 | void setPlayLoop(bool playLoop); 38 | 39 | protected: 40 | File f; 41 | int32_t startPos = 0; 42 | bool doPlayLoop = false; 43 | }; 44 | 45 | class AudioFileSourceSDLoop : public AudioFileSourceLoop 46 | { 47 | public: 48 | AudioFileSourceSDLoop(); 49 | AudioFileSourceSDLoop(const char *filename); 50 | 51 | virtual bool open(const char *filename) override; 52 | }; 53 | 54 | class AudioFileSourceFSLoop : public AudioFileSourceLoop 55 | { 56 | public: 57 | AudioFileSourceFSLoop(); 58 | AudioFileSourceFSLoop(const char *filename); 59 | 60 | virtual bool open(const char *filename) override; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourceFS.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourceFS 3 | Input Arduion "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOFILESOURCEFS_H 22 | #define _AUDIOFILESOURCEFS_H 23 | 24 | #include 25 | #include 26 | 27 | #include "AudioFileSource.h" 28 | 29 | class AudioFileSourceFS : public AudioFileSource 30 | { 31 | public: 32 | AudioFileSourceFS(fs::FS &fs) { filesystem = &fs; } 33 | AudioFileSourceFS(fs::FS &fs, const char *filename); 34 | virtual ~AudioFileSourceFS() override; 35 | 36 | virtual bool open(const char *filename) override; 37 | virtual uint32_t read(void *data, uint32_t len) override; 38 | virtual bool seek(int32_t pos, int dir) override; 39 | virtual bool close() override; 40 | virtual bool isOpen() override; 41 | virtual uint32_t getSize() override; 42 | virtual uint32_t getPos() override { if (!f) return 0; else return f.position(); }; 43 | 44 | private: 45 | fs::FS *filesystem; 46 | fs::File f; 47 | }; 48 | 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourcePROGMEM.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourcePROGMEM 3 | Store a "file" as a PROGMEM array and use it as audio source data 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOFILESOURCEPROGMEM_H 22 | #define _AUDIOFILESOURCEPROGMEM_H 23 | 24 | #include "AudioFileSource.h" 25 | 26 | class AudioFileSourcePROGMEM : public AudioFileSource 27 | { 28 | public: 29 | AudioFileSourcePROGMEM(); 30 | AudioFileSourcePROGMEM(const void *data, uint32_t len); 31 | virtual ~AudioFileSourcePROGMEM() override; 32 | virtual uint32_t read(void *data, uint32_t len) override; 33 | virtual bool seek(int32_t pos, int dir) override; 34 | virtual bool close() override; 35 | virtual bool isOpen() override; 36 | virtual uint32_t getSize() override; 37 | virtual uint32_t getPos() override { if (!opened) return 0; else return filePointer; }; 38 | 39 | bool open(const void *data, uint32_t len); 40 | 41 | private: 42 | bool opened; 43 | const void *progmemData; 44 | uint32_t progmemLen; 45 | uint32_t filePointer; 46 | }; 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/bit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_BIT_H 23 | # define LIBMAD_BIT_H 24 | 25 | struct mad_bitptr { 26 | unsigned char const *byte; 27 | unsigned short cache; 28 | unsigned short left; 29 | }; 30 | 31 | void mad_bit_init(struct mad_bitptr *, unsigned char const *); 32 | 33 | # define mad_bit_finish(bitptr) /* nothing */ 34 | 35 | unsigned int mad_bit_length(struct mad_bitptr const *, 36 | struct mad_bitptr const *); 37 | 38 | # define mad_bit_bitsleft(bitptr) ((bitptr)->left) 39 | unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); 40 | 41 | void mad_bit_skip(struct mad_bitptr *, unsigned int); 42 | unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); 43 | void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); 44 | 45 | unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); 46 | 47 | # endif 48 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_VERSION_H 23 | # define LIBMAD_VERSION_H 24 | 25 | # define MAD_VERSION_MAJOR 0 26 | # define MAD_VERSION_MINOR 15 27 | # define MAD_VERSION_PATCH 1 28 | # define MAD_VERSION_EXTRA " (beta)" 29 | 30 | # define MAD_VERSION_STRINGIZE(str) #str 31 | # define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) 32 | 33 | # define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ 34 | MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ 35 | MAD_VERSION_STRING(MAD_VERSION_PATCH) \ 36 | MAD_VERSION_EXTRA 37 | 38 | # define MAD_PUBLISHYEAR "2000-2004" 39 | # define MAD_AUTHOR "Underbit Technologies, Inc." 40 | # define MAD_EMAIL "info@underbit.com" 41 | 42 | extern char const mad_version[]; 43 | extern char const mad_copyright[]; 44 | extern char const mad_author[]; 45 | extern char const mad_build[]; 46 | 47 | # endif 48 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: global.h,v 1.11 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_GLOBAL_H 23 | # define LIBMAD_GLOBAL_H 24 | 25 | /* conditional debugging */ 26 | 27 | # if defined(DEBUG) && defined(NDEBUG) 28 | # error "cannot define both DEBUG and NDEBUG" 29 | # endif 30 | 31 | # if defined(DEBUG) 32 | # include 33 | # endif 34 | 35 | /* conditional features */ 36 | 37 | # if defined(OPT_SPEED) && defined(OPT_ACCURACY) 38 | # error "cannot optimize for both speed and accuracy" 39 | # endif 40 | 41 | # if defined(OPT_SPEED) && !defined(OPT_SSO) 42 | # define OPT_SSO 43 | # endif 44 | 45 | # if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) && \ 46 | defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK) 47 | # define USE_ASYNC 48 | # endif 49 | 50 | # if !defined(HAVE_ASSERT_H) 51 | # undef assert 52 | # if defined(NDEBUG) 53 | # define assert(x) /* nothing */ 54 | # else 55 | # define assert(x) do { if (!(x)) abort(); } while (0) 56 | # endif 57 | # endif 58 | 59 | # endif 60 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourceFS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourceFS 3 | Input "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include "AudioFileSourceFS.h" 22 | #ifdef ESP32 23 | #include "SPIFFS.h" 24 | #endif 25 | 26 | AudioFileSourceFS::AudioFileSourceFS(FS &fs, const char *filename) 27 | { 28 | filesystem = &fs; 29 | open(filename); 30 | } 31 | 32 | bool AudioFileSourceFS::open(const char *filename) 33 | { 34 | #ifndef ESP32 35 | filesystem->begin(); 36 | #endif 37 | f = filesystem->open(filename, "r"); 38 | return f; 39 | } 40 | 41 | AudioFileSourceFS::~AudioFileSourceFS() 42 | { 43 | if (f) f.close(); 44 | } 45 | 46 | uint32_t AudioFileSourceFS::read(void *data, uint32_t len) 47 | { 48 | return f.read(reinterpret_cast(data), len); 49 | } 50 | 51 | bool AudioFileSourceFS::seek(int32_t pos, int dir) 52 | { 53 | return f.seek(pos, (dir==SEEK_SET)?SeekSet:(dir==SEEK_CUR)?SeekCur:SeekEnd); 54 | } 55 | 56 | bool AudioFileSourceFS::close() 57 | { 58 | f.close(); 59 | return true; 60 | } 61 | 62 | bool AudioFileSourceFS::isOpen() 63 | { 64 | return f?true:false; 65 | } 66 | 67 | uint32_t AudioFileSourceFS::getSize() 68 | { 69 | if (!f) return 0; 70 | return f.size(); 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioGenerator 3 | Base class of an audio output generator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOGENERATOR_H 22 | #define _AUDIOGENERATOR_H 23 | 24 | #include 25 | #include "AudioStatus.h" 26 | #include "AudioFileSource.h" 27 | #include "AudioOutput.h" 28 | 29 | class AudioGenerator 30 | { 31 | public: 32 | AudioGenerator() { lastSample[0] = 0; lastSample[1] = 0; }; 33 | virtual ~AudioGenerator() {}; 34 | virtual bool begin(AudioFileSource *source, AudioOutput *output) { (void)source; (void)output; return false; }; 35 | virtual bool loop() { return false; }; 36 | virtual bool stop() { return false; }; 37 | virtual bool isRunning() { return false;}; 38 | virtual void desync () { }; 39 | 40 | public: 41 | virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { return cb.RegisterMetadataCB(fn, data); } 42 | virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { return cb.RegisterStatusCB(fn, data); } 43 | 44 | protected: 45 | bool running; 46 | AudioFileSource *file; 47 | AudioOutput *output; 48 | int16_t lastSample[2]; 49 | 50 | protected: 51 | AudioStatus cb; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/README.ESP8266: -------------------------------------------------------------------------------- 1 | This is the LIBMAD library, ported and optimized for the ESP8266 by 2 | Earle F. Philhower, III . The entire GIT 3 | history is preserved in GitHub at: 4 | https://github.com/earlephilhower/libmad-8266 5 | 6 | Unlike the "port" in NONOS-SDK from Espressif, this works in STEREO 7 | with an external I2S, or a full dynamic 32x oversampled mono using 8 | the AudioOutputI2SNoDAC which sounds poretty good @ 44.1KHz. 9 | 10 | The only functional changes made were in the synth section, where the 11 | amount of data synthesized in one pass was reduces from 1156 to 32 bytes 12 | and pre-scaled to minimize memory usage. Most other work involved 13 | shrinking the HEAP footprint by moving any constants to PROGMEM and 14 | adjusting the code to work. Often shorts could just be made to ints 15 | and then pointer/array access "just worked." In other cases accessor 16 | functions or macros were required to make the mad_fixed_t accesses 17 | use a 32-bit read before operating on a local register/RAM copy of 18 | a value. 19 | 20 | Massive stack variables were moved to the heap and dynamically 21 | allocated/deallocated on function entrance/exit. The xr[] array 22 | and the tmp[] array in layer3.c took around 8KB stack space, whereas 23 | the standard Arduino only has 4K total stack. That lead to some very 24 | interesting crashes, believe you me. 25 | 26 | Present memory needs to decode 128kb/sec MP3s are around 34KB heap 27 | and 1KB stack. Of this, about 24KB are required at all times once 28 | the MP3 object is instantiated, while the additional 10KB are for the 29 | stack-to-heap variables mentioned above. 30 | 31 | Any bugs in the port are most likely my fault, not Underbit's. I'd 32 | like to thank them for producing such a readable MP3 decoder and 33 | releasing it under the GPL. Their web page is: 34 | http://www.underbit.com/products/mad/ 35 | 36 | -Earle F. Philhower, III 37 | earlephilhower@yahoo.com 38 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSource 3 | Base class of an input "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOFILESOURCE_H 22 | #define _AUDIOFILESOURCE_H 23 | 24 | #include 25 | #include "AudioStatus.h" 26 | 27 | class AudioFileSource 28 | { 29 | public: 30 | AudioFileSource() {}; 31 | virtual ~AudioFileSource() {}; 32 | virtual bool open(const char *filename) { (void)filename; return false; }; 33 | virtual uint32_t read(void *data, uint32_t len) { (void)data; (void)len; return 0; }; 34 | virtual uint32_t readNonBlock(void *data, uint32_t len) { return read(data, len); }; 35 | virtual bool seek(int32_t pos, int dir) { (void)pos; (void)dir; return false; }; 36 | virtual bool close() { return false; }; 37 | virtual bool isOpen() { return false; }; 38 | virtual uint32_t getSize() { return 0; }; 39 | virtual uint32_t getPos() { return 0; }; 40 | virtual bool loop() { return true; }; 41 | 42 | public: 43 | virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { return cb.RegisterMetadataCB(fn, data); } 44 | virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { return cb.RegisterStatusCB(fn, data); } 45 | 46 | protected: 47 | AudioStatus cb; 48 | }; 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourceSD.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourceSPIFFS 3 | Input SD card "file" to be used by AudioGenerator 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include "AudioFileSourceSD.h" 22 | 23 | AudioFileSourceSD::AudioFileSourceSD() 24 | { 25 | } 26 | 27 | AudioFileSourceSD::AudioFileSourceSD(const char *filename) 28 | { 29 | open(filename); 30 | } 31 | 32 | bool AudioFileSourceSD::open(const char *filename) 33 | { 34 | f = SD.open(filename, FILE_READ); 35 | return f; 36 | } 37 | 38 | AudioFileSourceSD::~AudioFileSourceSD() 39 | { 40 | if (f) f.close(); 41 | } 42 | 43 | uint32_t AudioFileSourceSD::read(void *data, uint32_t len) 44 | { 45 | return f.read(reinterpret_cast(data), len); 46 | } 47 | 48 | bool AudioFileSourceSD::seek(int32_t pos, int dir) 49 | { 50 | if (!f) return false; 51 | if (dir==SEEK_SET) return f.seek(pos); 52 | else if (dir==SEEK_CUR) return f.seek(f.position() + pos); 53 | else if (dir==SEEK_END) return f.seek(f.size() + pos); 54 | return false; 55 | } 56 | 57 | bool AudioFileSourceSD::close() 58 | { 59 | f.close(); 60 | return true; 61 | } 62 | 63 | bool AudioFileSourceSD::isOpen() 64 | { 65 | return f?true:false; 66 | } 67 | 68 | uint32_t AudioFileSourceSD::getSize() 69 | { 70 | if (!f) return 0; 71 | return f.size(); 72 | } 73 | 74 | uint32_t AudioFileSourceSD::getPos() 75 | { 76 | if (!f) return 0; 77 | return f.position(); 78 | } 79 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/TODO: -------------------------------------------------------------------------------- 1 | 2 | libmad - MPEG audio decoder library 3 | Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | 5 | $Id: TODO,v 1.3 2004/02/05 09:02:39 rob Exp $ 6 | 7 | =============================================================================== 8 | 9 | libmad: 10 | - more API layers (buffering, PCM samples, dithering, etc.) 11 | - x86 performance optimization compiler flags 12 | - function documentation, general docs 13 | - finish async API 14 | - parse system streams? 15 | - MPEG-2 MC, AAC? 16 | - logarithmic multiplication? 17 | - multiple frame decoding for better locality of reference? 18 | - frame serial numbers, Layer III frame continuity checks 19 | 20 | fixed.h: 21 | - experiment with FPM_INTEL: 22 | 23 | # if 1 24 | # define mad_f_scale64(hi, lo) \ 25 | ({ mad_fixed_t __result; \ 26 | asm ("shrl %3,%1\n\t" \ 27 | "shll %4,%2\n\t" \ 28 | "orl %2,%1" \ 29 | : "=rm" (__result) \ 30 | : "0" (lo), "r" (hi), \ 31 | "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \ 32 | : "cc"); \ 33 | __result; \ 34 | }) 35 | # else 36 | # define mad_f_scale64(hi, lo) \ 37 | ({ mad_fixed64hi_t __hi_; \ 38 | mad_fixed64lo_t __lo_; \ 39 | mad_fixed_t __result; \ 40 | asm ("sall %2,%1" \ 41 | : "=r" (__hi_) \ 42 | : "0" (hi), "I" (32 - MAD_F_SCALEBITS) \ 43 | : "cc"); \ 44 | asm ("shrl %2,%1" \ 45 | : "=r" (__lo_) \ 46 | : "0" (lo), "I" (MAD_F_SCALEBITS) \ 47 | : "cc"); \ 48 | asm ("orl %1,%2" \ 49 | : "=rm" (__result) \ 50 | : "r" (__hi_), "0" (__lo_) \ 51 | : "cc"); \ 52 | __result; \ 53 | }) 54 | # endif 55 | 56 | libmad Layer I: 57 | - check frame length sanity 58 | 59 | libmad Layer II: 60 | - check frame length sanity 61 | 62 | libmad Layer III: 63 | - circular buffer 64 | - optimize zero_part from Huffman decoding throughout 65 | - MPEG 2.5 8000 Hz sf bands? mixed blocks? 66 | - stereo->mono conversion optimization? 67 | - enable frame-at-a-time decoding 68 | - improve portability of huffman.c 69 | 70 | -------------------------------------------------------------------------------- /src/fc_wifi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * WiFi and Config Portal handling 9 | * 10 | * ------------------------------------------------------------------- 11 | * License: MIT 12 | * 13 | * Permission is hereby granted, free of charge, to any person 14 | * obtaining a copy of this software and associated documentation 15 | * files (the "Software"), to deal in the Software without restriction, 16 | * including without limitation the rights to use, copy, modify, 17 | * merge, publish, distribute, sublicense, and/or sell copies of the 18 | * Software, and to permit persons to whom the Software is furnished to 19 | * do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be 22 | * included in all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 29 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef _FC_WIFI_H 34 | #define _FC_WIFI_H 35 | 36 | extern bool wifiSetupDone; 37 | extern bool wifiIsOff; 38 | extern bool wifiAPIsOff; 39 | extern bool wifiInAPMode; 40 | 41 | void wifi_setup(); 42 | void wifi_setup2(); 43 | void wifi_loop(); 44 | void wifiOff(); 45 | void wifiOn(unsigned long newDelay = 0, bool alsoInAPMode = false, bool deferConfigPortal = false); 46 | bool wifiIsOn(); 47 | void wifiStartCP(); 48 | 49 | void updateConfigPortalValues(); 50 | 51 | bool wifi_getIP(uint8_t& a, uint8_t& b, uint8_t& c, uint8_t& d); 52 | bool isIp(char *str); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioStatus.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioStatus 3 | Base class for Audio* status/metadata reporting 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOSTATUS_H 22 | #define _AUDIOSTATUS_H 23 | 24 | #include 25 | 26 | #include "AudioLogger.h" 27 | 28 | class AudioStatus 29 | { 30 | public: 31 | AudioStatus() { ClearCBs(); }; 32 | virtual ~AudioStatus() {}; 33 | 34 | void ClearCBs() { mdFn = NULL; stFn = NULL; }; 35 | 36 | typedef void (*metadataCBFn)(void *cbData, const char *type, bool isUnicode, const char *str); 37 | bool RegisterMetadataCB(metadataCBFn f, void *cbData) { mdFn = f; mdData = cbData; return true; } 38 | 39 | // Returns a unique warning/error code, varying by the object. The string may be a PSTR, use _P functions! 40 | typedef void (*statusCBFn)(void *cbData, int code, const char *string); 41 | bool RegisterStatusCB(statusCBFn f, void *cbData) { stFn = f; stData = cbData; return true; } 42 | 43 | // Safely call the md function, if defined 44 | inline void md(const char *type, bool isUnicode, const char *string) { if (mdFn) mdFn(mdData, type, isUnicode, string); } 45 | 46 | // Safely call the st function, if defined 47 | inline void st(int code, const char *string) { if (stFn) stFn(stData, code, string); } 48 | 49 | private: 50 | metadataCBFn mdFn; 51 | void *mdData; 52 | statusCBFn stFn; 53 | void *stData; 54 | }; 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/huffman.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: huffman.h,v 1.11 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_HUFFMAN_H 23 | # define LIBMAD_HUFFMAN_H 24 | 25 | // Use ints instead of bitfields. This'll make the structure way larger, but allow 26 | // for easy direct access w/o any helper functions when placed in PROGMEM 27 | 28 | union huffquad { 29 | struct { 30 | unsigned int final; 31 | unsigned int bits; 32 | unsigned int offset; 33 | } ptr; 34 | struct { 35 | unsigned int final; 36 | unsigned int hlen; 37 | unsigned int v; 38 | unsigned int w; 39 | unsigned int x; 40 | unsigned int y; 41 | } value; 42 | unsigned int final ; 43 | }; 44 | 45 | union huffpair { 46 | struct { 47 | unsigned int final; 48 | unsigned int bits; 49 | unsigned int offset; 50 | } ptr; 51 | struct { 52 | unsigned int final; 53 | unsigned int hlen; 54 | unsigned int x; 55 | unsigned int y; 56 | } value; 57 | unsigned int final; 58 | }; 59 | 60 | struct hufftable { 61 | union huffpair const *table; 62 | unsigned int linbits; 63 | unsigned int startbits; 64 | }; 65 | 66 | extern union huffquad const *const mad_huff_quad_table[2]; 67 | extern struct hufftable const mad_huff_pair_table[32]; 68 | 69 | # endif 70 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/fixed.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | #pragma GCC optimize ("O3") 23 | 24 | # include "config.h" 25 | 26 | # include "global.h" 27 | 28 | # include "fixed.h" 29 | 30 | /* 31 | * NAME: fixed->abs() 32 | * DESCRIPTION: return absolute value of a fixed-point number 33 | */ 34 | mad_fixed_t mad_f_abs(mad_fixed_t x) 35 | { 36 | return x < 0 ? -x : x; 37 | } 38 | 39 | /* 40 | * NAME: fixed->div() 41 | * DESCRIPTION: perform division using fixed-point math 42 | */ 43 | mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y) 44 | { 45 | mad_fixed_t q, r; 46 | unsigned int bits; 47 | 48 | q = mad_f_abs(x / y); 49 | 50 | if (x < 0) { 51 | x = -x; 52 | y = -y; 53 | } 54 | 55 | r = x % y; 56 | 57 | if (y < 0) { 58 | x = -x; 59 | y = -y; 60 | } 61 | 62 | if (q > mad_f_intpart(MAD_F_MAX) && 63 | !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0))) 64 | return 0; 65 | 66 | for (bits = MAD_F_FRACBITS; bits && r; --bits) { 67 | q <<= 1, r <<= 1; 68 | if (r >= y) 69 | r -= y, ++q; 70 | } 71 | 72 | /* round */ 73 | if (2 * r >= y) 74 | ++q; 75 | 76 | /* fix sign */ 77 | if ((x < 0) != (y < 0)) 78 | q = -q; 79 | 80 | return q << bits; 81 | } 82 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioGeneratorWAV.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioGeneratorWAV 3 | Audio output generator that reads 8 and 16-bit WAV files 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOGENERATORWAV_H 22 | #define _AUDIOGENERATORWAV_H 23 | 24 | #include "AudioGenerator.h" 25 | 26 | class AudioGeneratorWAV : public AudioGenerator 27 | { 28 | public: 29 | AudioGeneratorWAV(); 30 | virtual ~AudioGeneratorWAV() override; 31 | virtual bool begin(AudioFileSource *source, AudioOutput *output) override; 32 | virtual bool loop() override; 33 | virtual bool stop() override; 34 | virtual bool isRunning() override; 35 | void SetBufferSize(int sz) { buffSize = sz; } 36 | 37 | private: 38 | bool ReadU32(uint32_t *dest) { return file->read(reinterpret_cast(dest), 4); } 39 | bool ReadU16(uint16_t *dest) { return file->read(reinterpret_cast(dest), 2); } 40 | bool ReadU8(uint8_t *dest) { return file->read(reinterpret_cast(dest), 1); } 41 | bool GetBufferedData(int bytes, void *dest); 42 | bool ReadWAVInfo(); 43 | 44 | 45 | protected: 46 | // WAV info 47 | uint16_t channels; 48 | uint32_t sampleRate; 49 | uint16_t bitsPerSample; 50 | 51 | uint32_t availBytes; 52 | 53 | // We need to buffer some data in-RAM to avoid doing 1000s of small reads 54 | uint32_t buffSize; 55 | uint8_t *buff; 56 | uint16_t buffPtr; 57 | uint16_t buffLen; 58 | }; 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/synth.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_SYNTH_H 23 | # define LIBMAD_SYNTH_H 24 | 25 | # include "fixed.h" 26 | # include "frame.h" 27 | #include 28 | 29 | struct mad_pcm { 30 | unsigned int samplerate; /* sampling frequency (Hz) */ 31 | unsigned short channels; /* number of channels */ 32 | unsigned short length; /* number of samples per channel */ 33 | int16_t samples[2][32]; //1152]; /* PCM output samples [ch][sample] */ 34 | }; 35 | 36 | struct mad_synth { 37 | mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ 38 | /* [ch][eo][peo][s][v] */ 39 | 40 | unsigned int phase; /* current processing phase */ 41 | 42 | struct mad_pcm pcm; /* PCM output */ 43 | }; 44 | 45 | /* single channel PCM selector */ 46 | enum { 47 | MAD_PCM_CHANNEL_SINGLE = 0 48 | }; 49 | 50 | /* dual channel PCM selector */ 51 | enum { 52 | MAD_PCM_CHANNEL_DUAL_1 = 0, 53 | MAD_PCM_CHANNEL_DUAL_2 = 1 54 | }; 55 | 56 | /* stereo PCM selector */ 57 | enum { 58 | MAD_PCM_CHANNEL_STEREO_LEFT = 0, 59 | MAD_PCM_CHANNEL_STEREO_RIGHT = 1 60 | }; 61 | 62 | void mad_synth_init(struct mad_synth *); 63 | 64 | # define mad_synth_finish(synth) /* nothing */ 65 | 66 | void mad_synth_mute(struct mad_synth *); 67 | 68 | enum mad_flow mad_synth_frame(struct mad_synth *, struct mad_frame const *, enum mad_flow (*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata ); 69 | enum mad_flow mad_synth_frame_onens(struct mad_synth *synth, struct mad_frame const *frame, unsigned int ns); 70 | 71 | # endif 72 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: version.c,v 1.15 2004/01/23 09:41:33 rob Exp $ 20 | */ 21 | 22 | #pragma GCC optimize ("O3") 23 | 24 | # include "config.h" 25 | 26 | # include "global.h" 27 | 28 | # include "version.h" 29 | 30 | char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION; 31 | char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR; 32 | char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; 33 | 34 | char const mad_build[] = "" 35 | # if defined(DEBUG) 36 | "DEBUG " 37 | # elif defined(NDEBUG) 38 | "NDEBUG " 39 | # endif 40 | 41 | # if defined(EXPERIMENTAL) 42 | "EXPERIMENTAL " 43 | # endif 44 | 45 | # if defined(FPM_64BIT) 46 | "FPM_64BIT " 47 | # elif defined(FPM_INTEL) 48 | "FPM_INTEL " 49 | # elif defined(FPM_ARM) 50 | "FPM_ARM " 51 | # elif defined(FPM_MIPS) 52 | "FPM_MIPS " 53 | # elif defined(FPM_SPARC) 54 | "FPM_SPARC " 55 | # elif defined(FPM_PPC) 56 | "FPM_PPC " 57 | # elif defined(FPM_DEFAULT) 58 | "FPM_DEFAULT " 59 | # endif 60 | 61 | # if defined(ASO_IMDCT) 62 | "ASO_IMDCT " 63 | # endif 64 | # if defined(ASO_INTERLEAVE1) 65 | "ASO_INTERLEAVE1 " 66 | # endif 67 | # if defined(ASO_INTERLEAVE2) 68 | "ASO_INTERLEAVE2 " 69 | # endif 70 | # if defined(ASO_ZEROCHECK) 71 | "ASO_ZEROCHECK " 72 | # endif 73 | 74 | # if defined(OPT_SPEED) 75 | "OPT_SPEED " 76 | # elif defined(OPT_ACCURACY) 77 | "OPT_ACCURACY " 78 | # endif 79 | 80 | # if defined(OPT_SSO) 81 | "OPT_SSO " 82 | # endif 83 | 84 | # if defined(OPT_DCTO) /* never defined here */ 85 | "OPT_DCTO " 86 | # endif 87 | 88 | # if defined(OPT_STRICT) 89 | "OPT_STRICT " 90 | # endif 91 | ; 92 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioOutputI2S.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioOutputI2S 3 | Base class for an I2S output port 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "AudioOutput.h" 24 | 25 | class AudioOutputI2S : public AudioOutput 26 | { 27 | public: 28 | #if defined(ESP32) || defined(ESP8266) 29 | AudioOutputI2S(int port=0, int output_mode=EXTERNAL_I2S, int dma_buf_count = 8, int use_apll=APLL_DISABLE); 30 | bool SetPinout(int bclkPin, int wclkPin, int doutPin); 31 | enum : int { APLL_AUTO = -1, APLL_ENABLE = 1, APLL_DISABLE = 0 }; 32 | enum : int { EXTERNAL_I2S = 0, INTERNAL_DAC = 1, INTERNAL_PDM = 2 }; 33 | #elif defined(ARDUINO_ARCH_RP2040) 34 | AudioOutputI2S(long sampleRate = 44100, pin_size_t sck = 26, pin_size_t data = 28); 35 | #endif 36 | virtual ~AudioOutputI2S() override; 37 | virtual bool SetRate(int hz) override; 38 | virtual bool SetBitsPerSample(int bits) override; 39 | virtual bool SetChannels(int channels) override; 40 | virtual bool begin() override { return begin(true); } 41 | virtual bool ConsumeSample(int16_t sample[2]) override; 42 | virtual void flush() override; 43 | virtual bool stop() override; 44 | 45 | bool begin(bool txDAC); 46 | bool SetOutputModeMono(bool mono); // Force mono output no matter the input 47 | bool SetLsbJustified(bool lsbJustified); // Allow supporting non-I2S chips, e.g. PT8211 48 | 49 | protected: 50 | bool SetPinout(); 51 | virtual int AdjustI2SRate(int hz) { return hz; } 52 | uint8_t portNo; 53 | int output_mode; 54 | bool mono; 55 | int lsb_justified; 56 | bool i2sOn; 57 | int dma_buf_count; 58 | int use_apll; 59 | // We can restore the old values and free up these pins when in NoDAC mode 60 | uint32_t orig_bck; 61 | uint32_t orig_ws; 62 | 63 | uint8_t bclkPin; 64 | uint8_t wclkPin; 65 | uint8_t doutPin; 66 | }; 67 | -------------------------------------------------------------------------------- /src/fc_audio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * Sound handling 9 | * 10 | * ------------------------------------------------------------------- 11 | * License: MIT 12 | * 13 | * Permission is hereby granted, free of charge, to any person 14 | * obtaining a copy of this software and associated documentation 15 | * files (the "Software"), to deal in the Software without restriction, 16 | * including without limitation the rights to use, copy, modify, 17 | * merge, publish, distribute, sublicense, and/or sell copies of the 18 | * Software, and to permit persons to whom the Software is furnished to 19 | * do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be 22 | * included in all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 29 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef _FC_AUDIO_H 34 | #define _FC_AUDIO_H 35 | 36 | extern bool audioInitDone; 37 | extern bool audioMute; 38 | 39 | extern bool playingFlux; 40 | 41 | extern uint8_t curSoftVol; 42 | extern bool useVKnob; 43 | 44 | extern bool haveMusic; 45 | extern bool mpActive; 46 | 47 | void audio_setup(); 48 | void audio_loop(); 49 | void play_file(const char *audio_file, uint16_t flags, float volumeFactor = 1.0); 50 | void append_file(const char *audio_file, uint16_t flags, float volumeFactor = 1.0); 51 | bool checkAudioDone(); 52 | void stopAudio(); 53 | bool append_pending(); 54 | 55 | void play_flux(); 56 | void append_flux(); 57 | 58 | void inc_vol(); 59 | void dec_vol(); 60 | 61 | void mp_init(bool isSetup); 62 | void mp_play(bool forcePlay = true); 63 | bool mp_stop(); 64 | void mp_next(bool forcePlay = false); 65 | void mp_prev(bool forcePlay = false); 66 | int mp_gotonum(int num, bool force = false); 67 | void mp_makeShuffle(bool enable); 68 | int mp_checkForFolder(int num); 69 | 70 | // Default volume (index) 71 | #define DEFAULT_VOLUME 6 72 | 73 | #define PA_LOOP 0x0001 74 | #define PA_INTRMUS 0x0002 75 | #define PA_ALLOWSD 0x0004 76 | #define PA_DYNVOL 0x0008 77 | #define PA_ISFLUX 0x0010 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/fc_main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * Main controller 9 | * 10 | * ------------------------------------------------------------------- 11 | * License: MIT 12 | * 13 | * Permission is hereby granted, free of charge, to any person 14 | * obtaining a copy of this software and associated documentation 15 | * files (the "Software"), to deal in the Software without restriction, 16 | * including without limitation the rights to use, copy, modify, 17 | * merge, publish, distribute, sublicense, and/or sell copies of the 18 | * Software, and to permit persons to whom the Software is furnished to 19 | * do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be 22 | * included in all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 29 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef _FC_MAIN_H 34 | #define _FC_MAIN_H 35 | 36 | // Number of IR keys 37 | #define NUM_IR_KEYS 17 38 | 39 | // FC LEDs 40 | #define FC_SPD_MAX 1 // 10ms 41 | #define FC_SPD_MIN 500 // 5000ms 42 | #define FC_SPD_IDLE 20 43 | 44 | extern unsigned long powerupMillis; 45 | 46 | extern uint16_t minBLL; 47 | extern uint16_t lastIRspeed; 48 | extern bool irLocked; 49 | 50 | extern bool TCDconnected; 51 | 52 | extern bool FPBUnitIsOn; 53 | extern bool fluxNM; 54 | 55 | extern uint8_t fluxPat; 56 | 57 | extern bool TTrunning; 58 | extern int playFLUX; 59 | extern bool IRLearning; 60 | 61 | extern bool networkTimeTravel; 62 | extern bool networkTCDTT; 63 | extern bool networkReentry; 64 | extern bool networkAbort; 65 | extern bool networkAlarm; 66 | extern uint16_t networkLead; 67 | 68 | void main_boot(); 69 | void main_setup(); 70 | void main_loop(); 71 | 72 | void showWaitSequence(); 73 | void endWaitSequence(); 74 | void showCopyError(); 75 | void allOff(); 76 | 77 | void populateIRarray(uint32_t *irkeys, int index); 78 | void copyIRarray(uint32_t *irkeys, int index); 79 | 80 | void setFluxMode(int mode); 81 | void startFluxTimer(); 82 | 83 | void mydelay(unsigned long mydel, bool withIR); 84 | 85 | void prepareTT(); 86 | 87 | void bttfn_loop(); 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/imdct_s.dat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: imdct_s.dat,v 1.8 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, 23 | -MAD_F(0x0ec835e8) /* -0.923879533 */, 24 | -MAD_F(0x0216a2a2) /* -0.130526192 */, 25 | MAD_F(0x0fdcf549) /* 0.991444861 */, 26 | -MAD_F(0x061f78aa) /* -0.382683432 */, 27 | -MAD_F(0x0cb19346) /* -0.793353340 */ }, 28 | 29 | /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, 30 | MAD_F(0x061f78aa) /* 0.382683432 */, 31 | MAD_F(0x0fdcf549) /* 0.991444861 */, 32 | MAD_F(0x0216a2a2) /* 0.130526192 */, 33 | -MAD_F(0x0ec835e8) /* -0.923879533 */, 34 | -MAD_F(0x09bd7ca0) /* -0.608761429 */ }, 35 | 36 | /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, 37 | -MAD_F(0x0ec835e8) /* -0.923879533 */, 38 | MAD_F(0x0ec835e8) /* 0.923879533 */, 39 | -MAD_F(0x061f78aa) /* -0.382683432 */, 40 | -MAD_F(0x061f78aa) /* -0.382683432 */, 41 | MAD_F(0x0ec835e8) /* 0.923879533 */ }, 42 | 43 | /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, 44 | -MAD_F(0x061f78aa) /* -0.382683432 */, 45 | MAD_F(0x061f78aa) /* 0.382683432 */, 46 | MAD_F(0x0ec835e8) /* 0.923879533 */, 47 | MAD_F(0x0ec835e8) /* 0.923879533 */, 48 | MAD_F(0x061f78aa) /* 0.382683432 */ }, 49 | 50 | /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, 51 | -MAD_F(0x061f78aa) /* -0.382683432 */, 52 | MAD_F(0x09bd7ca0) /* 0.608761429 */, 53 | -MAD_F(0x0cb19346) /* -0.793353340 */, 54 | MAD_F(0x0ec835e8) /* 0.923879533 */, 55 | -MAD_F(0x0fdcf549) /* -0.991444861 */ }, 56 | 57 | /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */, 58 | -MAD_F(0x0ec835e8) /* -0.923879533 */, 59 | -MAD_F(0x0cb19346) /* -0.793353340 */, 60 | -MAD_F(0x09bd7ca0) /* -0.608761429 */, 61 | -MAD_F(0x061f78aa) /* -0.382683432 */, 62 | -MAD_F(0x0216a2a2) /* -0.130526192 */ } 63 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioFileSourcePROGMEM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | AudioFileSourcePROGMEM 3 | Store a "file" as a PROGMEM array and use it as audio source data 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include "AudioFileSourcePROGMEM.h" 22 | 23 | AudioFileSourcePROGMEM::AudioFileSourcePROGMEM() 24 | { 25 | opened = false; 26 | progmemData = NULL; 27 | progmemLen = 0; 28 | filePointer = 0; 29 | } 30 | 31 | AudioFileSourcePROGMEM::AudioFileSourcePROGMEM(const void *data, uint32_t len) 32 | { 33 | open(data, len); 34 | } 35 | 36 | AudioFileSourcePROGMEM::~AudioFileSourcePROGMEM() 37 | { 38 | } 39 | 40 | bool AudioFileSourcePROGMEM::open(const void *data, uint32_t len) 41 | { 42 | if (!data || !len) return false; 43 | 44 | opened = true; 45 | progmemData = data; 46 | progmemLen = len; 47 | filePointer = 0; 48 | return true; 49 | } 50 | 51 | uint32_t AudioFileSourcePROGMEM::getSize() 52 | { 53 | if (!opened) return 0; 54 | return progmemLen; 55 | } 56 | 57 | bool AudioFileSourcePROGMEM::isOpen() 58 | { 59 | return opened; 60 | } 61 | 62 | bool AudioFileSourcePROGMEM::close() 63 | { 64 | opened = false; 65 | progmemData = NULL; 66 | progmemLen = 0; 67 | filePointer = 0; 68 | return true; 69 | } 70 | 71 | bool AudioFileSourcePROGMEM::seek(int32_t pos, int dir) 72 | { 73 | if (!opened) return false; 74 | uint32_t newPtr; 75 | switch (dir) { 76 | case SEEK_SET: newPtr = pos; break; 77 | case SEEK_CUR: newPtr = filePointer + pos; break; 78 | case SEEK_END: newPtr = progmemLen - pos; break; 79 | default: return false; 80 | } 81 | if (newPtr > progmemLen) return false; 82 | filePointer = newPtr; 83 | return true; 84 | } 85 | 86 | uint32_t AudioFileSourcePROGMEM::read(void *data, uint32_t len) 87 | { 88 | if (!opened) return 0; 89 | if (filePointer >= progmemLen) return 0; 90 | 91 | uint32_t toRead = progmemLen - filePointer; 92 | if (toRead > len) toRead = len; 93 | 94 | memcpy_P(data, reinterpret_cast(progmemData)+filePointer, toRead); 95 | filePointer += toRead; 96 | return toRead; 97 | } 98 | 99 | 100 | -------------------------------------------------------------------------------- /src/AudioFileSourceLoop.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * AudioFileSourceLoop 3 | * Read SD/SPIFFS/LittleFS file to be used by AudioGenerator 4 | * Reads file in a loop (for looped playback) 5 | * 6 | * Thomas Winischhofer (A10001986), 2023 7 | * 8 | * Based on AudioFileSourceSD by Earle F. Philhower, III 9 | * 10 | */ 11 | 12 | #include "fc_global.h" 13 | #include "AudioFileSourceLoop.h" 14 | 15 | AudioFileSourceLoop::AudioFileSourceLoop() 16 | { 17 | } 18 | 19 | AudioFileSourceLoop::~AudioFileSourceLoop() 20 | { 21 | if(f) f.close(); 22 | } 23 | 24 | uint32_t AudioFileSourceLoop::read(void *data, uint32_t len) 25 | { 26 | uint32_t glen = f.read(reinterpret_cast(data), len); 27 | if(!doPlayLoop || glen == len) return glen; 28 | seek(startPos, SEEK_SET); 29 | return glen + f.read(reinterpret_cast(data) + glen, len - glen); 30 | } 31 | 32 | bool AudioFileSourceLoop::seek(int32_t pos, int dir) 33 | { 34 | if(!f) return false; 35 | if(dir == SEEK_SET) return f.seek(pos); 36 | else if(dir == SEEK_CUR) return f.seek(f.position() + pos); 37 | else if(dir == SEEK_END) return f.seek(f.size() + pos); 38 | return false; 39 | } 40 | 41 | bool AudioFileSourceLoop::close() 42 | { 43 | f.close(); 44 | return true; 45 | } 46 | 47 | bool AudioFileSourceLoop::isOpen() 48 | { 49 | return f ? true : false; 50 | } 51 | 52 | uint32_t AudioFileSourceLoop::getSize() 53 | { 54 | if(!f) return 0; 55 | return f.size(); 56 | } 57 | 58 | uint32_t AudioFileSourceLoop::getPos() 59 | { 60 | if(!f) return 0; 61 | return f.position(); 62 | } 63 | 64 | void AudioFileSourceLoop::setStartPos(int32_t newStartPos) 65 | { 66 | startPos = newStartPos; 67 | } 68 | 69 | void AudioFileSourceLoop::setPlayLoop(bool playLoop) 70 | { 71 | doPlayLoop = playLoop; 72 | } 73 | 74 | 75 | // SD ----------------------------------------------- 76 | 77 | AudioFileSourceSDLoop::AudioFileSourceSDLoop() 78 | { 79 | } 80 | 81 | AudioFileSourceSDLoop::AudioFileSourceSDLoop(const char *filename) 82 | { 83 | open(filename); 84 | } 85 | 86 | bool AudioFileSourceSDLoop::open(const char *filename) 87 | { 88 | f = SD.open(filename, FILE_READ); 89 | return f; 90 | } 91 | 92 | // FlashFS ------------------------------------------- 93 | 94 | AudioFileSourceFSLoop::AudioFileSourceFSLoop() 95 | { 96 | } 97 | 98 | AudioFileSourceFSLoop::AudioFileSourceFSLoop(const char *filename) 99 | { 100 | open(filename); 101 | } 102 | 103 | #ifdef USE_SPIFFS // ------------------------------ 104 | 105 | bool AudioFileSourceFSLoop::open(const char *filename) 106 | { 107 | f = SPIFFS.open(filename, FILE_READ); 108 | return f; 109 | } 110 | 111 | #else // ----------------------------------------- 112 | 113 | bool AudioFileSourceFSLoop::open(const char *filename) 114 | { 115 | f = LittleFS.open(filename, FILE_READ); 116 | return f; 117 | } 118 | 119 | #endif // ----------------------------------------- 120 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioOutput.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioOutput 3 | Base class of an audio output player 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOOUTPUT_H 22 | #define _AUDIOOUTPUT_H 23 | 24 | #include 25 | #include "AudioStatus.h" 26 | 27 | class AudioOutput 28 | { 29 | public: 30 | AudioOutput() { }; 31 | virtual ~AudioOutput() {}; 32 | virtual bool SetRate(int hz) { hertz = hz; return true; } 33 | virtual bool SetBitsPerSample(int bits) { bps = bits; return true; } 34 | virtual bool SetChannels(int chan) { channels = chan; return true; } 35 | virtual bool SetGain(float f) { if (f>4.0) f = 4.0; if (f<0.0) f=0.0; gainF2P6 = (uint8_t)(f*(1<<6)); return true; } 36 | virtual bool begin() { return false; }; 37 | typedef enum { LEFTCHANNEL=0, RIGHTCHANNEL=1 } SampleIndex; 38 | virtual bool ConsumeSample(int16_t sample[2]) { (void)sample; return false; } 39 | virtual uint16_t ConsumeSamples(int16_t *samples, uint16_t count) 40 | { 41 | for (uint16_t i=0; i>6; 69 | if (v < -32767) return -32767; 70 | else if (v > 32767) return 32767; 71 | else return (int16_t)(v&0xffff); 72 | } 73 | 74 | protected: 75 | uint16_t hertz; 76 | uint8_t bps; 77 | uint8_t channels; 78 | uint8_t gainF2P6; // Fixed point 2.6 79 | 80 | protected: 81 | AudioStatus cb; 82 | }; 83 | 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioGeneratorMP3.h: -------------------------------------------------------------------------------- 1 | /* 2 | AudioGeneratorMP3 3 | Wrap libmad MP3 library to play audio 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _AUDIOGENERATORMP3_H 22 | #define _AUDIOGENERATORMP3_H 23 | 24 | #include "AudioGenerator.h" 25 | #include "libmad/config.h" 26 | #include "libmad/mad.h" 27 | 28 | class AudioGeneratorMP3 : public AudioGenerator 29 | { 30 | public: 31 | AudioGeneratorMP3(); 32 | AudioGeneratorMP3(void *preallocateSpace, int preallocateSize); 33 | AudioGeneratorMP3(void *buff, int buffSize, void *stream, int streamSize, void *frame, int frameSize, void *synth, int synthSize); 34 | virtual ~AudioGeneratorMP3() override; 35 | virtual bool begin(AudioFileSource *source, AudioOutput *output) override; 36 | virtual bool loop() override; 37 | virtual bool stop() override; 38 | virtual bool isRunning() override; 39 | virtual void desync () override; 40 | 41 | static constexpr int preAllocSize () { return preAllocBuffSize() + preAllocStreamSize() + preAllocFrameSize() + preAllocSynthSize(); } 42 | static constexpr int preAllocBuffSize () { return ((buffLen + 7) & ~7); } 43 | static constexpr int preAllocStreamSize () { return ((sizeof(struct mad_stream) + 7) & ~7); } 44 | static constexpr int preAllocFrameSize () { return (sizeof(struct mad_frame) + 7) & ~7; } 45 | static constexpr int preAllocSynthSize () { return (sizeof(struct mad_synth) + 7) & ~7; } 46 | 47 | protected: 48 | void *preallocateSpace = nullptr; 49 | int preallocateSize = 0; 50 | void *preallocateStreamSpace = nullptr; 51 | int preallocateStreamSize = 0; 52 | void *preallocateFrameSpace = nullptr; 53 | int preallocateFrameSize = 0; 54 | void *preallocateSynthSpace = nullptr; 55 | int preallocateSynthSize = 0; 56 | 57 | static constexpr int buffLen = 0x600; // Slightly larger than largest MP3 frame 58 | unsigned char *buff; 59 | int lastReadPos; 60 | int lastBuffLen; 61 | unsigned int lastRate; 62 | int lastChannels; 63 | 64 | // Decoding bits 65 | bool madInitted; 66 | struct mad_stream *stream; 67 | struct mad_frame *frame; 68 | struct mad_synth *synth; 69 | int samplePtr; 70 | int nsCount; 71 | int nsCountMax; 72 | 73 | // The internal helpers 74 | enum mad_flow ErrorToFlow(); 75 | enum mad_flow Input(); 76 | bool DecodeNextFrame(); 77 | bool GetOneSample(int16_t sample[2]); 78 | 79 | private: 80 | int unrecoverable = 0; 81 | }; 82 | 83 | #endif 84 | 85 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_DECODER_H 23 | # define LIBMAD_DECODER_H 24 | 25 | # include "stream.h" 26 | # include "frame.h" 27 | # include "synth.h" 28 | 29 | enum mad_decoder_mode { 30 | MAD_DECODER_MODE_SYNC = 0, 31 | MAD_DECODER_MODE_ASYNC 32 | }; 33 | 34 | enum mad_flow { 35 | MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ 36 | MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ 37 | MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ 38 | MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ 39 | }; 40 | 41 | struct mad_decoder { 42 | enum mad_decoder_mode mode; 43 | 44 | int options; 45 | 46 | struct { 47 | long pid; 48 | int in; 49 | int out; 50 | } async; 51 | 52 | struct { 53 | struct mad_stream stream; 54 | struct mad_frame frame; 55 | struct mad_synth synth; 56 | } *sync; 57 | 58 | void *cb_data; 59 | 60 | enum mad_flow (*input_func)(void *, struct mad_stream *); 61 | enum mad_flow (*header_func)(void *, struct mad_header const *); 62 | enum mad_flow (*filter_func)(void *, 63 | struct mad_stream const *, struct mad_frame *); 64 | enum mad_flow (*output_func)(void *, 65 | struct mad_header const *, struct mad_pcm *); 66 | enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); 67 | enum mad_flow (*message_func)(void *, void *, unsigned int *); 68 | }; 69 | 70 | void mad_decoder_init(struct mad_decoder *, void *, 71 | enum mad_flow (*)(void *, struct mad_stream *), 72 | enum mad_flow (*)(void *, struct mad_header const *), 73 | enum mad_flow (*)(void *, 74 | struct mad_stream const *, 75 | struct mad_frame *), 76 | enum mad_flow (*)(void *, 77 | struct mad_header const *, 78 | struct mad_pcm *), 79 | enum mad_flow (*)(void *, 80 | struct mad_stream *, 81 | struct mad_frame *), 82 | enum mad_flow (*)(void *, void *, unsigned int *)); 83 | int mad_decoder_finish(struct mad_decoder *); 84 | 85 | # define mad_decoder_options(decoder, opts) \ 86 | ((void) ((decoder)->options = (opts))) 87 | 88 | int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); 89 | int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); 90 | 91 | # endif 92 | -------------------------------------------------------------------------------- /src/fcdisplay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * FCDisplay: Handles the FC LEDs 9 | * 10 | * ------------------------------------------------------------------- 11 | * License: MIT 12 | * 13 | * Permission is hereby granted, free of charge, to any person 14 | * obtaining a copy of this software and associated documentation 15 | * files (the "Software"), to deal in the Software without restriction, 16 | * including without limitation the rights to use, copy, modify, 17 | * merge, publish, distribute, sublicense, and/or sell copies of the 18 | * Software, and to permit persons to whom the Software is furnished to 19 | * do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be 22 | * included in all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 29 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef _FCDISPLAY_H 34 | #define _FCDISPLAY_H 35 | 36 | /* 37 | * PWM LED class for Center and Box LEDs 38 | */ 39 | 40 | class PWMLED { 41 | 42 | public: 43 | 44 | PWMLED(uint8_t pwm_pin); 45 | void begin(uint8_t ledChannel, uint32_t freq, uint8_t resolution, uint8_t pwm_pin = 255); 46 | 47 | void setDC(uint32_t dutyCycle); 48 | uint32_t getDC(); 49 | 50 | private: 51 | uint8_t _pwm_pin; 52 | uint8_t _chnl; 53 | uint32_t _freq; 54 | uint8_t _res; 55 | 56 | uint32_t _curDutyCycle; 57 | }; 58 | 59 | // Special sequences 60 | #define FCSEQ_STARTUP 1 61 | #define FCSEQ_NOAUDIO 2 62 | #define FCSEQ_WAIT 3 63 | #define FCSEQ_BADINP 4 64 | #define FCSEQ_ALARM 5 65 | #define FCSEQ_LEARNSTART 6 66 | #define FCSEQ_LEARNNEXT 7 67 | #define FCSEQ_LEARNDONE 8 68 | #define FCSEQ_ERRCOPY 9 69 | #define FCSEQ_MAX FCSEQ_ERRCOPY 70 | 71 | /* 72 | * FC LEDs class 73 | */ 74 | 75 | class FCLEDs { 76 | 77 | public: 78 | 79 | FCLEDs(uint8_t timer_no, uint8_t shift_clk, uint8_t reg_clk, uint8_t ser_data, uint8_t mreset); 80 | void begin(); 81 | 82 | void on(); 83 | void off(); 84 | 85 | void stop(bool stop); 86 | 87 | void setSpeed(uint16_t speed); 88 | uint16_t getSpeed(); 89 | 90 | void setSequence(uint8_t seq); 91 | 92 | void SpecialSignal(uint8_t signum); 93 | bool SpecialDone(); 94 | 95 | private: 96 | hw_timer_t *_FCLTimer_Cfg = NULL; 97 | uint8_t _timer_no; 98 | 99 | }; 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_TIMER_H 23 | # define LIBMAD_TIMER_H 24 | 25 | typedef struct { 26 | signed long seconds; /* whole seconds */ 27 | unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ 28 | } mad_timer_t; 29 | 30 | extern mad_timer_t const mad_timer_zero; 31 | 32 | # define MAD_TIMER_RESOLUTION 352800000UL 33 | 34 | enum mad_units { 35 | MAD_UNITS_HOURS = -2, 36 | MAD_UNITS_MINUTES = -1, 37 | MAD_UNITS_SECONDS = 0, 38 | 39 | /* metric units */ 40 | 41 | MAD_UNITS_DECISECONDS = 10, 42 | MAD_UNITS_CENTISECONDS = 100, 43 | MAD_UNITS_MILLISECONDS = 1000, 44 | 45 | /* audio sample units */ 46 | 47 | MAD_UNITS_8000_HZ = 8000, 48 | MAD_UNITS_11025_HZ = 11025, 49 | MAD_UNITS_12000_HZ = 12000, 50 | 51 | MAD_UNITS_16000_HZ = 16000, 52 | MAD_UNITS_22050_HZ = 22050, 53 | MAD_UNITS_24000_HZ = 24000, 54 | 55 | MAD_UNITS_32000_HZ = 32000, 56 | MAD_UNITS_44100_HZ = 44100, 57 | MAD_UNITS_48000_HZ = 48000, 58 | 59 | /* video frame/field units */ 60 | 61 | MAD_UNITS_24_FPS = 24, 62 | MAD_UNITS_25_FPS = 25, 63 | MAD_UNITS_30_FPS = 30, 64 | MAD_UNITS_48_FPS = 48, 65 | MAD_UNITS_50_FPS = 50, 66 | MAD_UNITS_60_FPS = 60, 67 | 68 | /* CD audio frames */ 69 | 70 | MAD_UNITS_75_FPS = 75, 71 | 72 | /* video drop-frame units */ 73 | 74 | MAD_UNITS_23_976_FPS = -24, 75 | MAD_UNITS_24_975_FPS = -25, 76 | MAD_UNITS_29_97_FPS = -30, 77 | MAD_UNITS_47_952_FPS = -48, 78 | MAD_UNITS_49_95_FPS = -50, 79 | MAD_UNITS_59_94_FPS = -60 80 | }; 81 | 82 | # define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) 83 | 84 | int mad_timer_compare(mad_timer_t, mad_timer_t); 85 | 86 | # define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) 87 | 88 | void mad_timer_negate(mad_timer_t *); 89 | mad_timer_t mad_timer_abs(mad_timer_t); 90 | 91 | void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); 92 | void mad_timer_add(mad_timer_t *, mad_timer_t); 93 | void mad_timer_multiply(mad_timer_t *, signed long); 94 | 95 | signed long mad_timer_count(mad_timer_t, enum mad_units); 96 | unsigned long mad_timer_fraction(mad_timer_t, unsigned long); 97 | void mad_timer_string(mad_timer_t, char *, char const *, 98 | enum mad_units, enum mad_units, unsigned long); 99 | 100 | # endif 101 | -------------------------------------------------------------------------------- /src/input.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * FCRemote Class: Remote control handling 9 | * 10 | * ------------------------------------------------------------------- 11 | * License: MIT 12 | * 13 | * Permission is hereby granted, free of charge, to any person 14 | * obtaining a copy of this software and associated documentation 15 | * files (the "Software"), to deal in the Software without restriction, 16 | * including without limitation the rights to use, copy, modify, 17 | * merge, publish, distribute, sublicense, and/or sell copies of the 18 | * Software, and to permit persons to whom the Software is furnished to 19 | * do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be 22 | * included in all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 29 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef _FCINPUT_H 34 | #define _FCINPUT_H 35 | 36 | 37 | /* 38 | * IRRemote class 39 | */ 40 | 41 | #define IRBUFSIZE 100 42 | 43 | typedef enum { 44 | IRSTATE_IDLE, 45 | IRSTATE_LIGHT, 46 | IRSTATE_DARK, 47 | IRSTATE_STOP 48 | } IRState; 49 | 50 | class IRRemote { 51 | 52 | public: 53 | IRRemote(uint8_t timerno, uint8_t ir_pin); 54 | void begin(); 55 | 56 | bool loop(); 57 | uint32_t readHash(); 58 | void resume(); 59 | 60 | private: 61 | uint32_t compare(unsigned int oldval, unsigned int newval); 62 | bool calcHash(); 63 | 64 | uint8_t _timer_no = 0; 65 | hw_timer_t *_IRTimer = NULL; 66 | 67 | uint32_t _buflen; 68 | uint32_t _buf[IRBUFSIZE]; 69 | uint32_t _hvalue; 70 | 71 | unsigned long _prevTime; 72 | uint32_t _prevHash; 73 | }; 74 | 75 | 76 | /* 77 | * FCButton class 78 | */ 79 | 80 | typedef enum { 81 | TCBS_IDLE, 82 | TCBS_PRESSED, 83 | TCBS_RELEASED, 84 | TCBS_LONGPRESS, 85 | TCBS_LONGPRESSEND 86 | } ButtonState; 87 | 88 | class FCButton { 89 | 90 | public: 91 | FCButton(const int pin, const boolean activeLow = true, const bool pullupActive = true); 92 | 93 | void setDebounceTicks(const int ticks); 94 | void setPressTicks(const int ticks); 95 | void setLongPressTicks(const int ticks); 96 | 97 | void attachPress(void (*newFunction)(void)); 98 | void attachLongPressStart(void (*newFunction)(void)); 99 | void attachLongPressStop(void (*newFunction)(void)); 100 | 101 | void scan(void); 102 | 103 | private: 104 | 105 | void reset(void); 106 | void transitionTo(ButtonState nextState); 107 | 108 | void (*_pressFunc)(void) = NULL; 109 | void (*_longPressStartFunc)(void) = NULL; 110 | void (*_longPressStopFunc)(void) = NULL; 111 | 112 | int _pin; 113 | 114 | unsigned int _debounceTicks = 50; 115 | unsigned int _pressTicks = 400; 116 | unsigned int _longPressTicks = 800; 117 | 118 | int _buttonPressed; 119 | 120 | ButtonState _state = TCBS_IDLE; 121 | ButtonState _lastState = TCBS_IDLE; 122 | 123 | unsigned long _startTime; 124 | 125 | bool _pressNotified = false; 126 | }; 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /src/fc_global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * Global definitions 9 | */ 10 | 11 | #ifndef _FC_GLOBAL_H 12 | #define _FC_GLOBAL_H 13 | 14 | // Version strings. 15 | #define FC_VERSION "V1.14" 16 | #define FC_VERSION_EXTRA "SEP302023" 17 | 18 | //#define FC_DBG // debug output on Serial 19 | 20 | /************************************************************************* 21 | *** mDNS (Bonjour) support *** 22 | *************************************************************************/ 23 | 24 | // Supply mDNS service 25 | // Allows accessing the Config Portal via http://hostname.local 26 | // is configurable in the Config Portal 27 | // This needs to be commented if WiFiManager provides mDNS 28 | #define FC_MDNS 29 | 30 | // Uncomment this if WiFiManager has mDNS enabled 31 | //#define FC_WM_HAS_MDNS 32 | 33 | /************************************************************************* 34 | *** Configuration for peripherals/features *** 35 | *************************************************************************/ 36 | 37 | // Uncomment for HomeAssistant MQTT protocol support 38 | #define FC_HAVEMQTT 39 | 40 | // --- end of config options 41 | 42 | /************************************************************************* 43 | *** Miscellaneous *** 44 | *************************************************************************/ 45 | 46 | // Uncomment this if using a FC control board v1.2 47 | // Comment for all later versions 48 | //#define BOARD_1_2 49 | 50 | // Use SPIFFS (if defined) or LittleFS (if undefined; esp32-arduino >= 2.x) 51 | //#define USE_SPIFFS 52 | 53 | // External time travel lead time, as defined by TCD firmware 54 | // If FC is connected by wire, the option "Signal Time Travel without 5s 55 | // lead" on the TCD must NOT be set. 56 | #define ETTO_LEAD 5000 57 | 58 | /************************************************************************* 59 | *** esp32-arduino version detection *** 60 | *************************************************************************/ 61 | 62 | #if defined __has_include && __has_include() 63 | #include 64 | #ifdef ESP_ARDUINO_VERSION_MAJOR 65 | #if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2,0,8) 66 | #define HAVE_GETNEXTFILENAME 67 | #endif 68 | #endif 69 | #endif 70 | 71 | /************************************************************************* 72 | *** GPIO pins *** 73 | *************************************************************************/ 74 | 75 | // FC LEDs 76 | #define SHIFT_CLK_PIN 21 77 | #define REG_CLK_PIN 18 78 | #define MRESET_PIN 19 79 | #define SERDATA_PIN 22 80 | 81 | // Box LEDs 82 | #define BLED_PWM_PIN 2 83 | 84 | // Center LED 85 | #define LED_PWM_PIN 17 86 | 87 | // GPIO14 (for alternative box lights) 88 | #define GPIO_14 14 89 | 90 | // IR Remote input 91 | #define IRREMOTE_PIN 27 92 | 93 | // IR feedback LED 94 | #ifndef BOARD_1_2 95 | #define IR_FB_PIN 12 96 | #else 97 | #define IR_FB_PIN 14 98 | #endif 99 | 100 | // Time Travel button (or TCD tt trigger input) 101 | #define TT_IN_PIN 13 102 | 103 | // I2S audio pins 104 | #define I2S_BCLK_PIN 26 105 | #define I2S_LRCLK_PIN 25 106 | #define I2S_DIN_PIN 33 107 | 108 | // SD Card pins 109 | #define SD_CS_PIN 5 110 | #define SPI_MOSI_PIN 23 111 | #define SPI_MISO_PIN 16 112 | #define SPI_SCK_PIN 15 113 | 114 | // analog input pin, used for Speed 115 | #define SPEED_PIN 32 116 | 117 | // analog input, for volume 118 | #define VOLUME_PIN 35 // Board Rev 1.3 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/qc_table.dat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: qc_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | /* 23 | * These are the Layer II classes of quantization. 24 | * The table is derived from Table B.4 of ISO/IEC 11172-3. 25 | */ 26 | 27 | { 3, 2, 5, 28 | MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */, 29 | MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, 30 | { 5, 3, 7, 31 | MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */, 32 | MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, 33 | { 7, 0, 3, 34 | MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */, 35 | MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ }, 36 | { 9, 4, 10, 37 | MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */, 38 | MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, 39 | { 15, 0, 4, 40 | MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */, 41 | MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ }, 42 | { 31, 0, 5, 43 | MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */, 44 | MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ }, 45 | { 63, 0, 6, 46 | MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */, 47 | MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ }, 48 | { 127, 0, 7, 49 | MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */, 50 | MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ }, 51 | { 255, 0, 8, 52 | MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */, 53 | MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ }, 54 | { 511, 0, 9, 55 | MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */, 56 | MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ }, 57 | { 1023, 0, 10, 58 | MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */, 59 | MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ }, 60 | { 2047, 0, 11, 61 | MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */, 62 | MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ }, 63 | { 4095, 0, 12, 64 | MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */, 65 | MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ }, 66 | { 8191, 0, 13, 67 | MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */, 68 | MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ }, 69 | { 16383, 0, 14, 70 | MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */, 71 | MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ }, 72 | { 32767, 0, 15, 73 | MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */, 74 | MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ }, 75 | { 65535, 0, 16, 76 | MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */, 77 | MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ } 78 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_FRAME_H 23 | # define LIBMAD_FRAME_H 24 | 25 | # include "fixed.h" 26 | # include "timer.h" 27 | # include "stream.h" 28 | 29 | enum mad_layer { 30 | MAD_LAYER_I = 1, /* Layer I */ 31 | MAD_LAYER_II = 2, /* Layer II */ 32 | MAD_LAYER_III = 3 /* Layer III */ 33 | }; 34 | 35 | enum mad_mode { 36 | MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ 37 | MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ 38 | MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ 39 | MAD_MODE_STEREO = 3 /* normal LR stereo */ 40 | }; 41 | 42 | enum mad_emphasis { 43 | MAD_EMPHASIS_NONE = 0, /* no emphasis */ 44 | MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ 45 | MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ 46 | MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ 47 | }; 48 | 49 | struct mad_header { 50 | enum mad_layer layer; /* audio layer (1, 2, or 3) */ 51 | enum mad_mode mode; /* channel mode (see above) */ 52 | int mode_extension; /* additional mode info */ 53 | enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ 54 | 55 | unsigned long bitrate; /* stream bitrate (bps) */ 56 | unsigned int samplerate; /* sampling frequency (Hz) */ 57 | 58 | unsigned short crc_check; /* frame CRC accumulator */ 59 | unsigned short crc_target; /* final target CRC checksum */ 60 | 61 | int flags; /* flags (see below) */ 62 | int private_bits; /* private bits (see below) */ 63 | 64 | mad_timer_t duration; /* audio playing time of frame */ 65 | }; 66 | 67 | struct mad_frame { 68 | struct mad_header header; /* MPEG audio header */ 69 | 70 | int options; /* decoding options (from stream) */ 71 | 72 | mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ 73 | mad_fixed_t overlap[2][32][18]; /* Layer III block overlap data */ 74 | 75 | mad_fixed_t xr_raw[576*2]; 76 | mad_fixed_t tmp[576]; 77 | }; 78 | 79 | # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) 80 | # define MAD_NSBSAMPLES(header) \ 81 | ((header)->layer == MAD_LAYER_I ? 12 : \ 82 | (((header)->layer == MAD_LAYER_III && \ 83 | ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) 84 | 85 | enum { 86 | MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ 87 | MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ 88 | 89 | MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ 90 | MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ 91 | MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ 92 | MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ 93 | 94 | MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ 95 | MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ 96 | MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ 97 | 98 | MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ 99 | MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ 100 | MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ 101 | }; 102 | 103 | enum { 104 | MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ 105 | MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ 106 | }; 107 | 108 | void mad_header_init(struct mad_header *); 109 | 110 | # define mad_header_finish(header) /* nothing */ 111 | 112 | int mad_header_decode(struct mad_header *, struct mad_stream *); 113 | 114 | void mad_frame_init(struct mad_frame *); 115 | void mad_frame_finish(struct mad_frame *); 116 | 117 | int mad_frame_decode(struct mad_frame *, struct mad_stream *); 118 | 119 | void mad_frame_mute(struct mad_frame *); 120 | 121 | # endif 122 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp $ 20 | */ 21 | 22 | # ifndef LIBMAD_STREAM_H 23 | # define LIBMAD_STREAM_H 24 | 25 | # include "bit.h" 26 | 27 | # define MAD_BUFFER_GUARD 8 28 | # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) 29 | 30 | enum mad_error { 31 | MAD_ERROR_NONE = 0x0000, /* no error */ 32 | 33 | MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ 34 | MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ 35 | 36 | MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ 37 | 38 | MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ 39 | MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ 40 | MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ 41 | MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ 42 | MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ 43 | 44 | MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ 45 | MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ 46 | MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ 47 | MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ 48 | MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ 49 | MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ 50 | MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ 51 | MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ 52 | MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ 53 | MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ 54 | MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ 55 | MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ 56 | MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ 57 | }; 58 | 59 | # define MAD_RECOVERABLE(error) ((error) & 0xff00) 60 | 61 | struct mad_stream { 62 | unsigned char const *buffer; /* input bitstream buffer */ 63 | unsigned char const *bufend; /* end of buffer */ 64 | unsigned long skiplen; /* bytes to skip before next frame */ 65 | 66 | int sync; /* stream sync found */ 67 | unsigned long freerate; /* free bitrate (fixed) */ 68 | 69 | unsigned char const *this_frame; /* start of current frame */ 70 | unsigned char const *next_frame; /* start of next frame */ 71 | struct mad_bitptr ptr; /* current processing bit pointer */ 72 | 73 | struct mad_bitptr anc_ptr; /* ancillary bits pointer */ 74 | unsigned int anc_bitlen; /* number of ancillary bits */ 75 | 76 | unsigned char main_data[MAD_BUFFER_MDLEN]; 77 | /* Layer III main_data() */ 78 | unsigned int md_len; /* bytes in main_data */ 79 | 80 | int options; /* decoding options (see below) */ 81 | enum mad_error error; /* error code (see above) */ 82 | }; 83 | 84 | enum { 85 | MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ 86 | MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ 87 | # if 0 /* not yet implemented */ 88 | MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ 89 | MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ 90 | MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ 91 | # endif 92 | }; 93 | 94 | void mad_stream_init(struct mad_stream *); 95 | void mad_stream_finish(struct mad_stream *); 96 | 97 | # define mad_stream_options(stream, opts) \ 98 | ((void) ((stream)->options = (opts))) 99 | 100 | void mad_stream_buffer(struct mad_stream *, 101 | unsigned char const *, unsigned long); 102 | void mad_stream_skip(struct mad_stream *, unsigned long); 103 | 104 | int mad_stream_sync(struct mad_stream *); 105 | 106 | char const *mad_stream_errorstr(struct mad_stream const *); 107 | 108 | # endif 109 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/CREDITS: -------------------------------------------------------------------------------- 1 | 2 | libmad - MPEG audio decoder library 3 | Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | 5 | $Id: CREDITS,v 1.5 2004/02/17 02:02:03 rob Exp $ 6 | 7 | =============================================================================== 8 | 9 | AUTHOR 10 | 11 | Except where otherwise noted, all code was authored by: 12 | 13 | Robert Leslie 14 | 15 | CONTRIBUTORS 16 | 17 | Significant contributions have been incorporated with thanks to: 18 | 19 | Anonymous 20 | 2002/03/15: frame.c 21 | - Reported problem with use of reserved emphasis value. 22 | 2003/08/31: layer12.c 23 | - Suggested support for certain disallowed bitrate/mode 24 | combinations. 25 | 26 | Niek Albers 27 | 2003/04/21: layer3.c 28 | - Reported runtime uninitialized use of `ptr' in designating 29 | ancillary bits after a decoding error. 30 | 31 | Christian Biere 32 | 2003/02/01: frame.c 33 | - Reported assertion failure in layer3.c due to an 34 | invalid/unsupported Layer III free format bitrate. 35 | 36 | David Blythe 37 | 2001/01/30: fixed.h 38 | - Provided initial PowerPC fixed-point assembly. 39 | 40 | Simon Burge 41 | 2000/09/20: imdct_l_arm.S 42 | - Suggested patch for a.out compatibility. 43 | 44 | Brian Cameron 45 | 2003/07/02: huffman.c 46 | - Suggested changes for improved portability. 47 | 48 | Joshua Haberman 49 | 2001/08/10: decoder.c, huffman.c 50 | - Suggested portability fixes. 51 | 52 | Timothy King 53 | 2002/05/04: sf_table.dat, layer12.c 54 | - Reported problem with use of (missing) scalefactor index 63. 55 | 56 | Felix von Leitner 57 | 2003/01/21: fixed.h 58 | - Suggested Intel scaling alternative for possible speedup. 59 | 60 | Andre McCurdy 61 | 2000/08/10: imdct_l_arm.S 62 | - ARM optimized assembly replacement for III_imdct_l(). 63 | 2000/09/15: imdct_l_arm.S 64 | - Applied Nicolas Pitre's rounding optimisation in all remaining 65 | places. 66 | 2001/02/10: layer3.c 67 | - Inspiration for Huffman decoding and requantization rewrite, and 68 | other miscellany. 69 | 2001/03/24: imdct_l_arm.S 70 | - Corrected PIC unsafe code. 71 | 2002/02/16: fixed.h 72 | - Discovered bug in ARM version of mad_f_scale64(). 73 | 74 | Haruhiko OGASAWARA 75 | 2001/01/28: layer3.c 76 | - Reported discrepancy in alias reduction for mixed short blocks. 77 | 78 | Brett Paterson 79 | 2001/10/28: global.h 80 | - Reported missing et al. under MS Embedded Visual C. 81 | 82 | Sean 'Shaleh' Perry 83 | 2000/04/04: fixed.h 84 | - Suggested use of size-dependent typedefs. 85 | 2001/10/22: config.guess, config.sub 86 | - Keep up to date for proper Debian packaging. 87 | 88 | Bertrand Petit 89 | 2001/11/05: synth.h 90 | - Suggested PCM channel enumeration constants. 91 | 2001/11/05: stream.h 92 | - Suggested MAD_ERROR_NONE enumeration constant. 93 | 2001/11/05: stream.c 94 | - Suggested mad_stream_errorstr() function. 95 | 96 | Nicolas Pitre 97 | 2000/09/09: fixed.h 98 | - Parameterized all scaling for correct use of all multiplication 99 | methods within mad_synth_frame(). 100 | - Rewrote the FPM_ARM version of mad_f_mul() so we have 64-bit 101 | multiplication result, rounding and scaling with 3 instructions. 102 | 2000/09/09: imdct_l_arm.S 103 | - Optimized rounding + scaling operations. 104 | 2000/09/17: synth.c 105 | - Changed D[] run-time shifts to compile-time. 106 | - Modified synthesis for better multiply/accumulate code output. 107 | 2001/08/11: fixed.h, synth.c 108 | - Suggested 64-bit FPM negation and negative term factorization 109 | during synthesis. 110 | 2001/08/11: fixed.h 111 | - Suggested unrounded behavior for FPM_DEFAULT when OPT_SPEED. 112 | 2001/11/19: fixed.c 113 | - Suggested computation of any resampling ratio. 114 | 115 | =============================================================================== 116 | 117 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to enable diagnostic debugging support. */ 5 | /* #undef DEBUG */ 6 | 7 | // Uncomment to show heap and stack space on entry 8 | #define stack(a,b,c) 9 | 10 | // Helper function to see if we can allocate one chunk on the stack 11 | # ifdef __cplusplus 12 | extern "C" { 13 | # endif 14 | extern int stackfree(); 15 | # ifdef __cplusplus 16 | } 17 | # endif 18 | 19 | /* Define to enable experimental code. */ 20 | /* #undef EXPERIMENTAL */ 21 | 22 | /* Define to 1 if you have the header file. */ 23 | //#define HAVE_ASSERT_H 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #undef HAVE_DLFCN_H 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #undef HAVE_ERRNO_H 30 | 31 | /* Define to 1 if you have the `fcntl' function. */ 32 | #undef HAVE_FCNTL 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #undef HAVE_FCNTL_H 36 | 37 | /* Define to 1 if you have the `fork' function. */ 38 | #undef HAVE_FORK 39 | 40 | /* Define to 1 if you have the header file. */ 41 | #undef HAVE_INTTYPES_H 42 | 43 | /* Define to 1 if you have the header file. */ 44 | #undef HAVE_LIMITS_H 45 | 46 | /* Define if your MIPS CPU supports a 2-operand MADD16 instruction. */ 47 | /* #undef HAVE_MADD16_ASM */ 48 | 49 | #define FPM_DEFAULT 50 | 51 | /* Define if your MIPS CPU supports a 2-operand MADD instruction. */ 52 | #define HAVE_MADD_ASM 1 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #undef HAVE_MEMORY_H 56 | 57 | /* Define to 1 if you have the `pipe' function. */ 58 | #undef HAVE_PIPE 59 | 60 | /* Define to 1 if you have the header file. */ 61 | #define HAVE_STDINT_H 1 62 | 63 | /* Define to 1 if you have the header file. */ 64 | #undef HAVE_STDLIB_H 65 | 66 | /* Define to 1 if you have the header file. */ 67 | #undef HAVE_STRINGS_H 68 | 69 | /* Define to 1 if you have the header file. */ 70 | #undef HAVE_STRING_H 71 | 72 | /* Define to 1 if you have the header file. */ 73 | #undef HAVE_SYS_STAT_H 74 | 75 | /* Define to 1 if you have the header file. */ 76 | #undef HAVE_SYS_TYPES_H 77 | 78 | /* Define to 1 if you have that is POSIX.1 compatible. */ 79 | #undef HAVE_SYS_WAIT_H 80 | 81 | /* Define to 1 if you have the header file. */ 82 | #undef HAVE_UNISTD_H 83 | 84 | /* Define to 1 if you have the `waitpid' function. */ 85 | #undef HAVE_WAITPID 86 | 87 | /* Define to disable debugging assertions. */ 88 | #define NDEBUG 1 89 | 90 | /* Define to optimize for accuracy over speed. */ 91 | /* #undef OPT_ACCURACY */ 92 | 93 | /* Define to optimize for speed over accuracy. */ 94 | #define OPT_SPEED 1 95 | 96 | /* Define to enable a fast subband synthesis approximation optimization. */ 97 | #define OPT_SSO 1 98 | 99 | /* Define to influence a strict interpretation of the ISO/IEC standards, even 100 | if this is in opposition with best accepted practices. */ 101 | #undef OPT_STRICT 102 | 103 | /* Name of package */ 104 | #define PACKAGE "libmad" 105 | 106 | /* Define to the address where bug reports for this package should be sent. */ 107 | #define PACKAGE_BUGREPORT "support@underbit.com" 108 | 109 | /* Define to the full name of this package. */ 110 | #define PACKAGE_NAME "MPEG Audio Decoder" 111 | 112 | /* Define to the full name and version of this package. */ 113 | #define PACKAGE_STRING "MPEG Audio Decoder 0.15.1b" 114 | 115 | /* Define to the one symbol short name of this package. */ 116 | #define PACKAGE_TARNAME "libmad" 117 | 118 | /* Define to the version of this package. */ 119 | #define PACKAGE_VERSION "0.15.1b" 120 | 121 | /* The size of a `int', as computed by sizeof. */ 122 | #define SIZEOF_INT 4 123 | 124 | /* The size of a `long', as computed by sizeof. */ 125 | #define SIZEOF_LONG 4 126 | 127 | /* The size of a `long long', as computed by sizeof. */ 128 | #define SIZEOF_LONG_LONG 8 129 | 130 | /* Define to 1 if you have the ANSI C header files. */ 131 | #undef STDC_HEADERS 132 | 133 | /* Version number of package */ 134 | #define VERSION "0.15.1b-esp8266" 135 | 136 | /* Define to 1 if your processor stores words with the most significant byte 137 | first (like Motorola and SPARC, unlike Intel and VAX). */ 138 | #undef WORDS_BIGENDIAN 139 | 140 | /* Define to empty if `const' does not conform to ANSI C. */ 141 | /* #undef const */ 142 | 143 | /* Define to `__inline__' or `__inline' if that's what the C compiler 144 | calls it, or to nothing if 'inline' is not supported under any name. */ 145 | #ifndef __cplusplus 146 | /* #undef inline */ 147 | #endif 148 | 149 | /* Define to `int' if does not define. */ 150 | /* #undef pid_t */ 151 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/stream.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $ 20 | */ 21 | 22 | #pragma GCC optimize ("O3") 23 | 24 | #include 25 | # include "config.h" 26 | 27 | # include "global.h" 28 | 29 | # include 30 | 31 | # include "bit.h" 32 | # include "stream.h" 33 | 34 | /* 35 | * NAME: stream->init() 36 | * DESCRIPTION: initialize stream struct 37 | */ 38 | void mad_stream_init(struct mad_stream *stream) 39 | { 40 | stack(__FUNCTION__, __FILE__, __LINE__); 41 | stream->buffer = 0; 42 | stream->bufend = 0; 43 | stream->skiplen = 0; 44 | 45 | stream->sync = 0; 46 | stream->freerate = 0; 47 | 48 | stream->this_frame = 0; 49 | stream->next_frame = 0; 50 | mad_bit_init(&stream->ptr, 0); 51 | 52 | mad_bit_init(&stream->anc_ptr, 0); 53 | stream->anc_bitlen = 0; 54 | 55 | stream->md_len = 0; 56 | 57 | stream->options = 0; 58 | stream->error = MAD_ERROR_NONE; 59 | } 60 | 61 | /* 62 | * NAME: stream->finish() 63 | * DESCRIPTION: deallocate any dynamic memory associated with stream 64 | */ 65 | void mad_stream_finish(struct mad_stream *stream) 66 | { 67 | stack(__FUNCTION__, __FILE__, __LINE__); 68 | (void) stream; 69 | 70 | mad_bit_finish(&stream->anc_ptr); 71 | mad_bit_finish(&stream->ptr); 72 | } 73 | 74 | /* 75 | * NAME: stream->buffer() 76 | * DESCRIPTION: set stream buffer pointers 77 | */ 78 | void mad_stream_buffer(struct mad_stream *stream, 79 | unsigned char const *buffer, unsigned long length) 80 | { 81 | stack(__FUNCTION__, __FILE__, __LINE__); 82 | stream->buffer = buffer; 83 | stream->bufend = buffer + length; 84 | 85 | stream->this_frame = buffer; 86 | stream->next_frame = buffer; 87 | 88 | stream->sync = 1; 89 | 90 | mad_bit_init(&stream->ptr, buffer); 91 | } 92 | 93 | /* 94 | * NAME: stream->skip() 95 | * DESCRIPTION: arrange to skip bytes before the next frame 96 | */ 97 | void mad_stream_skip(struct mad_stream *stream, unsigned long length) 98 | { 99 | stack(__FUNCTION__, __FILE__, __LINE__); 100 | stream->skiplen += length; 101 | } 102 | 103 | /* 104 | * NAME: stream->sync() 105 | * DESCRIPTION: locate the next stream sync word 106 | */ 107 | int mad_stream_sync(struct mad_stream *stream) 108 | { 109 | register unsigned char const *ptr, *end; 110 | stack(__FUNCTION__, __FILE__, __LINE__); 111 | 112 | ptr = mad_bit_nextbyte(&stream->ptr); 113 | end = stream->bufend; 114 | 115 | while (ptr < end - 1 && 116 | !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) 117 | ++ptr; 118 | 119 | if (end - ptr < MAD_BUFFER_GUARD) 120 | return -1; 121 | 122 | mad_bit_init(&stream->ptr, ptr); 123 | 124 | return 0; 125 | } 126 | 127 | /* 128 | * NAME: stream->errorstr() 129 | * DESCRIPTION: return a string description of the current error condition 130 | */ 131 | char const *mad_stream_errorstr(struct mad_stream const *stream) 132 | { 133 | stack(__FUNCTION__, __FILE__, __LINE__); 134 | switch (stream->error) { 135 | case MAD_ERROR_NONE: return PSTR("no error"); 136 | 137 | case MAD_ERROR_BUFLEN: return PSTR("input buffer too small (or EOF)"); 138 | case MAD_ERROR_BUFPTR: return PSTR("invalid (null) buffer pointer"); 139 | 140 | case MAD_ERROR_NOMEM: return PSTR("not enough memory"); 141 | 142 | case MAD_ERROR_LOSTSYNC: return PSTR("lost synchronization"); 143 | case MAD_ERROR_BADLAYER: return PSTR("reserved header layer value"); 144 | case MAD_ERROR_BADBITRATE: return PSTR("forbidden bitrate value"); 145 | case MAD_ERROR_BADSAMPLERATE: return PSTR("reserved sample frequency value"); 146 | case MAD_ERROR_BADEMPHASIS: return PSTR("reserved emphasis value"); 147 | 148 | case MAD_ERROR_BADCRC: return PSTR("CRC check failed"); 149 | case MAD_ERROR_BADBITALLOC: return PSTR("forbidden bit allocation value"); 150 | case MAD_ERROR_BADSCALEFACTOR: return PSTR("bad scalefactor index"); 151 | case MAD_ERROR_BADMODE: return PSTR("bad bitrate/mode combination"); 152 | case MAD_ERROR_BADFRAMELEN: return PSTR("bad frame length"); 153 | case MAD_ERROR_BADBIGVALUES: return PSTR("bad big_values count"); 154 | case MAD_ERROR_BADBLOCKTYPE: return PSTR("reserved block_type"); 155 | case MAD_ERROR_BADSCFSI: return PSTR("bad scalefactor selection info"); 156 | case MAD_ERROR_BADDATAPTR: return PSTR("bad main_data_begin pointer"); 157 | case MAD_ERROR_BADPART3LEN: return PSTR("bad audio data length"); 158 | case MAD_ERROR_BADHUFFTABLE: return PSTR("bad Huffman table select"); 159 | case MAD_ERROR_BADHUFFDATA: return PSTR("Huffman data overrun"); 160 | case MAD_ERROR_BADSTEREO: return PSTR("incompatible block_type for JS"); 161 | } 162 | 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /src/fc_settings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * Settings handling 9 | * 10 | * ------------------------------------------------------------------- 11 | * License: MIT 12 | * 13 | * Permission is hereby granted, free of charge, to any person 14 | * obtaining a copy of this software and associated documentation 15 | * files (the "Software"), to deal in the Software without restriction, 16 | * including without limitation the rights to use, copy, modify, 17 | * merge, publish, distribute, sublicense, and/or sell copies of the 18 | * Software, and to permit persons to whom the Software is furnished to 19 | * do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be 22 | * included in all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 29 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 30 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef _FC_SETTINGS_H 34 | #define _FC_SETTINGS_H 35 | 36 | extern bool haveFS; 37 | extern bool haveSD; 38 | extern bool FlashROMode; 39 | 40 | extern uint8_t musFolderNum; 41 | 42 | #define MS(s) XMS(s) 43 | #define XMS(s) #s 44 | 45 | // Default settings 46 | 47 | #define DEF_PLAY_FLUX_SND 1 // 1: Play "flux" sound permantly, 0: Do not 48 | #define DEF_SS_TIMER 0 // "Screen saver" timeout in minutes; 0 = ss off 49 | 50 | #define DEF_BLEDSWAP 0 // 0: Use box led connectors for box leds; 1: use "panel light" connector (both PWM!) 51 | #define DEF_VKNOB 0 // 0: Don't use knob for audio volume, 1: do 52 | #define DEF_SKNOB 0 // 0: Don't use knob for chase speed; 1: do 53 | #define DEF_DISDIR 0 // 0: Do not disable default IR remote control; 1: do 54 | 55 | #define DEF_HOSTNAME "flux" 56 | #define DEF_WIFI_RETRY 3 // 1-10; Default: 3 retries 57 | #define DEF_WIFI_TIMEOUT 7 // 7-25; Default: 7 seconds 58 | 59 | #define DEF_TCD_PRES 0 // 0: No TCD connected, 1: connected via GPIO 60 | #define DEF_NO_ETTO_LEAD 0 // Default: 0: TCD signals TT with ETTO_LEAD lead time; 1 without 61 | 62 | #define DEF_TCD_IP "" // TCD ip address for networked polling 63 | #define DEF_WAIT_FOR_TCD 0 // 0: Boot normally 1: Delay WiFi setup for a few seconds (to wait for TCD if powered up simultaneously) 64 | #define DEF_USE_GPSS 0 // 0: Ignore GPS speed; 1: Use it for chase speed 65 | #define DEF_USE_NM 0 // 0: Ignore TCD night mode; 1: Follow TCD night mode 66 | #define DEF_USE_FPO 0 // 0: Ignore TCD fake power; 1: Follow TCD fake power 67 | #define DEF_WAIT_FPO 1 // 0: Don't wait for fake power on during boot, 1: Do 68 | 69 | #define DEF_PLAY_TT_SND 1 // 1: Play time travel sounds (0: Do not; for use with external equipment) 70 | #define DEF_STTBL_ANIM 0 // 1: Skip box light animation in tt; 0: Play anim 71 | #define DEF_PLAY_ALM_SND 0 // 1: Play TCD-alarm sound, 0: do not 72 | 73 | #define DEF_SHUFFLE 0 // Music Player: Do not shuffle by default 74 | 75 | #define DEF_CFG_ON_SD 1 // Default: Save vol/spd/IR/mbl settings on SD card 76 | #define DEF_SD_FREQ 0 // SD/SPI frequency: Default 16MHz 77 | 78 | 79 | struct Settings { 80 | char playFLUXsnd[4] = MS(DEF_PLAY_FLUX_SND); 81 | char ssTimer[6] = MS(DEF_SS_TIMER); 82 | 83 | char usePLforBL[4] = MS(DEF_BLEDSWAP); 84 | char useVknob[4] = MS(DEF_VKNOB); 85 | char useSknob[4] = MS(DEF_SKNOB); 86 | char disDIR[4] = MS(DEF_DISDIR); 87 | 88 | char hostName[32] = DEF_HOSTNAME; 89 | char systemID[8] = ""; 90 | char appw[10] = ""; 91 | char wifiConRetries[4] = MS(DEF_WIFI_RETRY); 92 | char wifiConTimeout[4] = MS(DEF_WIFI_TIMEOUT); 93 | 94 | char TCDpresent[4] = MS(DEF_TCD_PRES); 95 | char noETTOLead[4] = MS(DEF_NO_ETTO_LEAD); 96 | 97 | char tcdIP[16] = DEF_TCD_IP; 98 | //char wait4TCD[4] = MS(DEF_WAIT_FOR_TCD); 99 | char useGPSS[4] = MS(DEF_USE_GPSS); 100 | char useNM[4] = MS(DEF_USE_NM); 101 | char useFPO[4] = MS(DEF_USE_FPO); 102 | char wait4FPOn[4] = MS(DEF_WAIT_FPO); 103 | 104 | char playTTsnds[4] = MS(DEF_PLAY_TT_SND); 105 | char skipTTBLAnim[4] = MS(DEF_STTBL_ANIM); 106 | char playALsnd[4] = MS(DEF_PLAY_ALM_SND); 107 | 108 | #ifdef FC_HAVEMQTT 109 | char useMQTT[4] = "0"; 110 | char mqttServer[80] = ""; // ip or domain [:port] 111 | char mqttUser[128] = ""; // user[:pass] (UTF8) 112 | #endif 113 | 114 | char shuffle[4] = MS(DEF_SHUFFLE); 115 | 116 | char CfgOnSD[4] = MS(DEF_CFG_ON_SD); 117 | char sdFreq[4] = MS(DEF_SD_FREQ); 118 | }; 119 | 120 | struct IPSettings { 121 | char ip[20] = ""; 122 | char gateway[20] = ""; 123 | char netmask[20] = ""; 124 | char dns[20] = ""; 125 | }; 126 | 127 | extern struct Settings settings; 128 | extern struct IPSettings ipsettings; 129 | 130 | void settings_setup(); 131 | void write_settings(); 132 | bool checkConfigExists(); 133 | 134 | bool loadCurVolume(); 135 | void saveCurVolume(bool useCache = true); 136 | 137 | bool loadCurSpeed(); 138 | void saveCurSpeed(bool useCache = true); 139 | 140 | bool loadBLLevel(); 141 | void saveBLLevel(bool useCache = true); 142 | 143 | bool loadIdlePat(); 144 | void saveIdlePat(bool useCache = true); 145 | 146 | bool loadIRLock(); 147 | void saveIRLock(bool useCache = true); 148 | 149 | bool loadMusFoldNum(); 150 | void saveMusFoldNum(); 151 | 152 | void copySettings(); 153 | 154 | bool saveIRKeys(); 155 | void deleteIRKeys(); 156 | 157 | bool loadIpSettings(); 158 | void writeIpSettings(); 159 | void deleteIpSettings(); 160 | 161 | void doCopyAudioFiles(); 162 | bool copy_audio_files(); 163 | 164 | bool check_allow_CPA(); 165 | void delete_ID_file(); 166 | 167 | bool audio_files_present(); 168 | 169 | void rewriteSecondarySettings(); 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/sf_table.dat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: sf_table.dat,v 1.7 2004/01/23 09:41:33 rob Exp $ 20 | */ 21 | 22 | /* 23 | * These are the scalefactor values for Layer I and Layer II. 24 | * The values are from Table B.1 of ISO/IEC 11172-3. 25 | * 26 | * There is some error introduced by the 32-bit fixed-point representation; 27 | * the amount of error is shown. For 16-bit PCM output, this shouldn't be 28 | * too much of a problem. 29 | * 30 | * Strictly speaking, Table B.1 has only 63 entries (0-62), thus a strict 31 | * interpretation of ISO/IEC 11172-3 would suggest that a scalefactor index of 32 | * 63 is invalid. However, for better compatibility with current practices, we 33 | * add a 64th entry. 34 | */ 35 | 36 | MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ 37 | MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ 38 | MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ 39 | MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ 40 | MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ 41 | MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ 42 | MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ 43 | MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ 44 | 45 | MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ 46 | MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ 47 | MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ 48 | MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ 49 | MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ 50 | MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ 51 | MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ 52 | MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ 53 | 54 | MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ 55 | MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ 56 | MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */ 57 | MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */ 58 | MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */ 59 | MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */ 60 | MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */ 61 | MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */ 62 | 63 | MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */ 64 | MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */ 65 | MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */ 66 | MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */ 67 | MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */ 68 | MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */ 69 | MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */ 70 | MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */ 71 | 72 | MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */ 73 | MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */ 74 | MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */ 75 | MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */ 76 | MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */ 77 | MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */ 78 | MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */ 79 | MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */ 80 | 81 | MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */ 82 | MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */ 83 | MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */ 84 | MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */ 85 | MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */ 86 | MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */ 87 | MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */ 88 | MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */ 89 | 90 | MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */ 91 | MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */ 92 | MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */ 93 | MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */ 94 | MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */ 95 | MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */ 96 | MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */ 97 | MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */ 98 | 99 | MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */ 100 | MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */ 101 | MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */ 102 | MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */ 103 | MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */ 104 | MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */ 105 | MAD_F(0x00000143), /* 0.000001201554 => 0.000001203269, e -0.000000001714 */ 106 | MAD_F(0x00000000) /* this compatibility entry is not part of Table B.1 */ 107 | -------------------------------------------------------------------------------- /src/mqtt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * PubSubClient.h - A simple client for MQTT. 4 | * Nick O'Leary 5 | * http://knolleary.net 6 | * Minimized & adapted by Thomas Winischhofer (A10001986) in 2023 7 | * 8 | * Copyright (c) 2008-2020 Nicholas O'Leary 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining 11 | * a copy of this software and associated documentation files (the 12 | * "Software"), to deal in the Software without restriction, including 13 | * without limitation the rights to use, copy, modify, merge, publish, 14 | * distribute, sublicense, and/or sell copies of the Software, and to 15 | * permit persons to whom the Software is furnished to do so, subject to 16 | * the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be 19 | * included in all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #ifndef PubSubClient_h 32 | #define PubSubClient_h 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #define MQTT_VERSION_3_1 3 39 | #define MQTT_VERSION_3_1_1 4 40 | 41 | // MQTT_VERSION : Pick the version 42 | //#define MQTT_VERSION MQTT_VERSION_3_1 43 | #ifndef MQTT_VERSION 44 | #define MQTT_VERSION MQTT_VERSION_3_1_1 45 | #endif 46 | 47 | // MQTT_MAX_PACKET_SIZE : Maximum packet size. Override with setBufferSize(). 48 | #ifndef MQTT_MAX_PACKET_SIZE 49 | #define MQTT_MAX_PACKET_SIZE 512 50 | #endif 51 | 52 | // MQTT_KEEPALIVE : keepAlive interval in Seconds. Override with setKeepAlive() 53 | #ifndef MQTT_KEEPALIVE 54 | #define MQTT_KEEPALIVE 15 55 | #endif 56 | 57 | // MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds. Override with setSocketTimeout() 58 | #ifndef MQTT_SOCKET_TIMEOUT 59 | #define MQTT_SOCKET_TIMEOUT 15 60 | #endif 61 | 62 | // MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client 63 | // in each write call. Needed for the Arduino Wifi Shield. Leave undefined to 64 | // pass the entire MQTT packet in each write call. 65 | //#define MQTT_MAX_TRANSFER_SIZE 80 66 | 67 | // Possible values for client.state() 68 | #define MQTT_CONNECTING -5 69 | #define MQTT_CONNECTION_TIMEOUT -4 70 | #define MQTT_CONNECTION_LOST -3 71 | #define MQTT_CONNECT_FAILED -2 72 | #define MQTT_DISCONNECTED -1 73 | #define MQTT_CONNECTED 0 74 | #define MQTT_CONNECT_BAD_PROTOCOL 1 75 | #define MQTT_CONNECT_BAD_CLIENT_ID 2 76 | #define MQTT_CONNECT_UNAVAILABLE 3 77 | #define MQTT_CONNECT_BAD_CREDENTIALS 4 78 | #define MQTT_CONNECT_UNAUTHORIZED 5 79 | 80 | #define MQTTCONNECT 1 << 4 // Client request to connect to Server 81 | #define MQTTCONNACK 2 << 4 // Connect Acknowledgment 82 | #define MQTTPUBLISH 3 << 4 // Publish message 83 | #define MQTTPUBACK 4 << 4 // Publish Acknowledgment 84 | #define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1) 85 | #define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2) 86 | #define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3) 87 | #define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request 88 | #define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment 89 | #define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request 90 | #define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment 91 | #define MQTTPINGREQ 12 << 4 // PING Request 92 | #define MQTTPINGRESP 13 << 4 // PING Response 93 | #define MQTTDISCONNECT 14 << 4 // Client is Disconnecting 94 | #define MQTTReserved 15 << 4 // Reserved 95 | 96 | #define MQTTQOS0 (0 << 1) 97 | #define MQTTQOS1 (1 << 1) 98 | #define MQTTQOS2 (2 << 1) 99 | 100 | // Maximum size of fixed header and variable length size header 101 | #define MQTT_MAX_HEADER_SIZE 5 102 | 103 | #define PING_ERROR -1 104 | #define PING_IDLE 0 105 | #define PING_PINGING 1 106 | 107 | #define CHECK_STRING_LENGTH(l,s) if(l+2+strnlen(s, this->bufferSize) > this->bufferSize) { _client->stop(); return false; } 108 | 109 | class PubSubClient { 110 | 111 | public: 112 | PubSubClient(); 113 | PubSubClient(WiFiClient& client); 114 | 115 | ~PubSubClient(); 116 | 117 | void setServer(IPAddress ip, uint16_t port); 118 | void setServer(const char *domain, uint16_t port); 119 | void setCallback(void (*callback)(char *, uint8_t *, unsigned int)); 120 | void setLooper(void (*looper)()); 121 | void setClient(WiFiClient& client); 122 | void setKeepAlive(uint16_t keepAlive); 123 | void setSocketTimeout(uint16_t timeout); 124 | 125 | bool setBufferSize(uint16_t size); 126 | uint16_t getBufferSize(); 127 | 128 | bool connect(const char *id); 129 | bool connect(const char *id, const char *user, const char *pass); 130 | bool connect(const char *id, const char *user, const char *pass, bool cleanSession); 131 | 132 | void disconnect(); 133 | 134 | bool publish(const char *topic, const uint8_t *payload, unsigned int plength, bool retained = false); 135 | 136 | bool subscribe(const char *topic, const char *topic2 = NULL, uint8_t qos = 0); 137 | bool unsubscribe(const char *topic); 138 | 139 | bool loop(); 140 | 141 | bool connected(); 142 | int state(); 143 | 144 | bool sendPing(); 145 | bool pollPing(); 146 | void cancelPing(); 147 | int pstate(); 148 | 149 | private: 150 | 151 | bool subscribe_int(bool unsubscribe, const char *topic, const char *topic2L, uint8_t qos); 152 | uint32_t readPacket(uint8_t *); 153 | bool readByte(uint8_t *result); 154 | bool readByte(uint8_t *result, uint16_t *index); 155 | bool write(uint8_t header, uint8_t *buf, uint16_t length); 156 | uint16_t writeString(const char *string, uint8_t *buf, uint16_t pos); 157 | // Build up the header ready to send 158 | // Returns the size of the header 159 | // Note: the header is built at the end of the first MQTT_MAX_HEADER_SIZE bytes, so will start 160 | // (MQTT_MAX_HEADER_SIZE - ) bytes into the buffer 161 | size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length); 162 | 163 | WiFiClient* _client; 164 | uint8_t* buffer; 165 | uint16_t bufferSize; 166 | uint16_t keepAlive; 167 | unsigned long socketTimeout; 168 | uint16_t nextMsgId; 169 | unsigned long lastOutActivity; 170 | unsigned long lastInActivity; 171 | bool pingOutstanding; 172 | void (*callback)(char *, uint8_t *, unsigned int); 173 | void (*looper)(); 174 | 175 | IPAddress ip; 176 | const char* domain; 177 | uint16_t port; 178 | int _state; 179 | 180 | int _s; 181 | int _pstate = PING_IDLE; 182 | uint16_t _pseq_num = 34; 183 | }; 184 | 185 | #endif 186 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/bit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: bit.c,v 1.12 2004/01/23 09:41:32 rob Exp $ 20 | */ 21 | 22 | #pragma GCC optimize ("O3") 23 | 24 | #include 25 | # include "config.h" 26 | 27 | # include "global.h" 28 | 29 | # ifdef HAVE_LIMITS_H 30 | # include 31 | # else 32 | # define CHAR_BIT 8 33 | # endif 34 | 35 | # include "bit.h" 36 | 37 | /* 38 | * This is the lookup table for computing the CRC-check word. 39 | * As described in section 2.4.3.1 and depicted in Figure A.9 40 | * of ISO/IEC 11172-3, the generator polynomial is: 41 | * 42 | * G(X) = X^16 + X^15 + X^2 + 1 43 | */ 44 | static const unsigned int crc_table[256] PROGMEM = { 45 | 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 46 | 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 47 | 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 48 | 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 49 | 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, 50 | 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, 51 | 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 52 | 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, 53 | 54 | 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, 55 | 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 56 | 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 57 | 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 58 | 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 59 | 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, 60 | 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, 61 | 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 62 | 63 | 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, 64 | 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, 65 | 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 66 | 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 67 | 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 68 | 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 69 | 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, 70 | 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, 71 | 72 | 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 73 | 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, 74 | 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, 75 | 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 76 | 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, 77 | 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 78 | 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 79 | 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 80 | }; 81 | 82 | # define CRC_POLY 0x8005 83 | 84 | /* 85 | * NAME: bit->init() 86 | * DESCRIPTION: initialize bit pointer struct 87 | */ 88 | void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte) 89 | { 90 | stack(__FUNCTION__, __FILE__, __LINE__); 91 | bitptr->byte = byte; 92 | bitptr->cache = 0; 93 | bitptr->left = CHAR_BIT; 94 | } 95 | 96 | /* 97 | * NAME: bit->length() 98 | * DESCRIPTION: return number of bits between start and end points 99 | */ 100 | unsigned int mad_bit_length(struct mad_bitptr const *begin, 101 | struct mad_bitptr const *end) 102 | { 103 | stack(__FUNCTION__, __FILE__, __LINE__); 104 | return begin->left + 105 | CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left); 106 | } 107 | 108 | /* 109 | * NAME: bit->nextbyte() 110 | * DESCRIPTION: return pointer to next unprocessed byte 111 | */ 112 | unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr) 113 | { 114 | stack(__FUNCTION__, __FILE__, __LINE__); 115 | return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1; 116 | } 117 | 118 | /* 119 | * NAME: bit->skip() 120 | * DESCRIPTION: advance bit pointer 121 | */ 122 | void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len) 123 | { 124 | stack(__FUNCTION__, __FILE__, __LINE__); 125 | bitptr->byte += len / CHAR_BIT; 126 | bitptr->left -= len % CHAR_BIT; 127 | 128 | if (bitptr->left > CHAR_BIT) { 129 | bitptr->byte++; 130 | bitptr->left += CHAR_BIT; 131 | } 132 | 133 | if (bitptr->left < CHAR_BIT) 134 | bitptr->cache = *bitptr->byte; 135 | } 136 | 137 | /* 138 | * NAME: bit->read() 139 | * DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value 140 | */ 141 | unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) 142 | { 143 | unsigned long value; 144 | 145 | if (bitptr->left == CHAR_BIT) 146 | bitptr->cache = *bitptr->byte; 147 | 148 | if (len < bitptr->left) { 149 | value = (bitptr->cache & ((1 << bitptr->left) - 1)) >> 150 | (bitptr->left - len); 151 | bitptr->left -= len; 152 | 153 | return value; 154 | } 155 | 156 | /* remaining bits in current byte */ 157 | 158 | value = bitptr->cache & ((1 << bitptr->left) - 1); 159 | len -= bitptr->left; 160 | 161 | bitptr->byte++; 162 | bitptr->left = CHAR_BIT; 163 | 164 | /* more bytes */ 165 | 166 | while (len >= CHAR_BIT) { 167 | value = (value << CHAR_BIT) | *bitptr->byte++; 168 | len -= CHAR_BIT; 169 | } 170 | 171 | if (len > 0) { 172 | bitptr->cache = *bitptr->byte; 173 | 174 | value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); 175 | bitptr->left -= len; 176 | } 177 | 178 | return value; 179 | } 180 | 181 | # if 0 182 | /* 183 | * NAME: bit->write() 184 | * DESCRIPTION: write an arbitrary number of bits 185 | */ 186 | void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, 187 | unsigned long value) 188 | { 189 | unsigned char *ptr; 190 | stack(__FUNCTION__, __FILE__, __LINE__); 191 | 192 | ptr = (unsigned char *) bitptr->byte; 193 | 194 | /* ... */ 195 | } 196 | # endif 197 | 198 | /* 199 | * NAME: bit->crc() 200 | * DESCRIPTION: compute CRC-check word 201 | */ 202 | unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, 203 | unsigned short init) 204 | { 205 | unsigned int crc; 206 | stack(__FUNCTION__, __FILE__, __LINE__); 207 | 208 | for (crc = init; len >= 32; len -= 32) { 209 | unsigned long data; 210 | 211 | data = mad_bit_read(&bitptr, 32); 212 | 213 | crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; 214 | crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; 215 | crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; 216 | crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; 217 | } 218 | 219 | switch (len / 8) { 220 | case 3: crc = (crc << 8) ^ 221 | crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; 222 | /* Falls Through. */ 223 | case 2: crc = (crc << 8) ^ 224 | crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; 225 | /* Falls Through. */ 226 | case 1: crc = (crc << 8) ^ 227 | crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; 228 | 229 | len %= 8; 230 | /* Falls Through. */ 231 | 232 | case 0: break; 233 | } 234 | 235 | while (len--) { 236 | unsigned int msb; 237 | 238 | msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); 239 | 240 | crc <<= 1; 241 | if (msb & 1) 242 | crc ^= CRC_POLY; 243 | } 244 | 245 | return crc & 0xffff; 246 | } 247 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioGeneratorWAV.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | AudioGeneratorWAV 3 | Audio output generator that reads 8 and 16-bit WAV files 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include "AudioGeneratorWAV.h" 22 | 23 | AudioGeneratorWAV::AudioGeneratorWAV() 24 | { 25 | running = false; 26 | file = NULL; 27 | output = NULL; 28 | buffSize = 128; 29 | buff = NULL; 30 | buffPtr = 0; 31 | buffLen = 0; 32 | } 33 | 34 | AudioGeneratorWAV::~AudioGeneratorWAV() 35 | { 36 | free(buff); 37 | buff = NULL; 38 | } 39 | 40 | bool AudioGeneratorWAV::stop() 41 | { 42 | if (!running) return true; 43 | running = false; 44 | free(buff); 45 | buff = NULL; 46 | output->stop(); 47 | return file->close(); 48 | } 49 | 50 | bool AudioGeneratorWAV::isRunning() 51 | { 52 | return running; 53 | } 54 | 55 | 56 | // Handle buffered reading, reload each time we run out of data 57 | bool AudioGeneratorWAV::GetBufferedData(int bytes, void *dest) 58 | { 59 | if (!running) return false; // Nothing to do here! 60 | uint8_t *p = reinterpret_cast(dest); 61 | while (bytes--) { 62 | // Potentially load next batch of data... 63 | if (buffPtr >= buffLen) { 64 | buffPtr = 0; 65 | uint32_t toRead = availBytes > buffSize ? buffSize : availBytes; 66 | buffLen = file->read( buff, toRead ); 67 | availBytes -= buffLen; 68 | } 69 | if (buffPtr >= buffLen) 70 | return false; // No data left! 71 | *(p++) = buff[buffPtr++]; 72 | } 73 | return true; 74 | } 75 | 76 | bool AudioGeneratorWAV::loop() 77 | { 78 | if (!running) goto done; // Nothing to do here! 79 | 80 | // First, try and push in the stored sample. If we can't, then punt and try later 81 | if (!output->ConsumeSample(lastSample)) goto done; // Can't send, but no error detected 82 | 83 | // Try and stuff the buffer one sample at a time 84 | do 85 | { 86 | if (bitsPerSample == 8) { 87 | uint8_t l, r; 88 | if (!GetBufferedData(1, &l)) stop(); 89 | if (channels == 2) { 90 | if (!GetBufferedData(1, &r)) stop(); 91 | } else { 92 | r = 0; 93 | } 94 | lastSample[AudioOutput::LEFTCHANNEL] = l; 95 | lastSample[AudioOutput::RIGHTCHANNEL] = r; 96 | } else if (bitsPerSample == 16) { 97 | if (!GetBufferedData(2, &lastSample[AudioOutput::LEFTCHANNEL])) stop(); 98 | if (channels == 2) { 99 | if (!GetBufferedData(2, &lastSample[AudioOutput::RIGHTCHANNEL])) stop(); 100 | } else { 101 | lastSample[AudioOutput::RIGHTCHANNEL] = 0; 102 | } 103 | } 104 | } while (running && output->ConsumeSample(lastSample)); 105 | 106 | done: 107 | file->loop(); 108 | output->loop(); 109 | 110 | return running; 111 | } 112 | 113 | 114 | bool AudioGeneratorWAV::ReadWAVInfo() 115 | { 116 | uint32_t u32; 117 | uint16_t u16; 118 | int toSkip; 119 | 120 | // WAV specification document: 121 | // https://www.aelius.com/njh/wavemetatools/doc/riffmci.pdf 122 | 123 | // Header == "RIFF" 124 | if (!ReadU32(&u32)) { 125 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 126 | return false; 127 | }; 128 | if (u32 != 0x46464952) { 129 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, invalid RIFF header, got: %08X \n"), (uint32_t) u32); 130 | return false; 131 | } 132 | 133 | // Skip ChunkSize 134 | if (!ReadU32(&u32)) { 135 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 136 | return false; 137 | }; 138 | 139 | // Format == "WAVE" 140 | if (!ReadU32(&u32)) { 141 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 142 | return false; 143 | }; 144 | if (u32 != 0x45564157) { 145 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, invalid WAVE header, got: %08X \n"), (uint32_t) u32); 146 | return false; 147 | } 148 | 149 | // there might be JUNK or PAD - ignore it by continuing reading until we get to "fmt " 150 | while (1) { 151 | if (!ReadU32(&u32)) { 152 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 153 | return false; 154 | }; 155 | if (u32 == 0x20746d66) break; // 'fmt ' 156 | }; 157 | 158 | // subchunk size 159 | if (!ReadU32(&u32)) { 160 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 161 | return false; 162 | }; 163 | if (u32 == 16) { toSkip = 0; } 164 | else if (u32 == 18) { toSkip = 18 - 16; } 165 | else if (u32 == 40) { toSkip = 40 - 16; } 166 | else { 167 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, appears not to be standard PCM \n")); 168 | return false; 169 | } // we only do standard PCM 170 | 171 | // AudioFormat 172 | if (!ReadU16(&u16)) { 173 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 174 | return false; 175 | }; 176 | if (u16 != 1) { 177 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, AudioFormat appears not to be standard PCM \n")); 178 | return false; 179 | } // we only do standard PCM 180 | 181 | // NumChannels 182 | if (!ReadU16(&channels)) { 183 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 184 | return false; 185 | }; 186 | if ((channels<1) || (channels>2)) { 187 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, only mono and stereo are supported \n")); 188 | return false; 189 | } // Mono or stereo support only 190 | 191 | // SampleRate 192 | if (!ReadU32(&sampleRate)) { 193 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 194 | return false; 195 | }; 196 | if (sampleRate < 1) { 197 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, unknown sample rate \n")); 198 | return false; 199 | } // Weird rate, punt. Will need to check w/DAC to see if supported 200 | 201 | // Ignore byterate and blockalign 202 | if (!ReadU32(&u32)) { 203 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 204 | return false; 205 | }; 206 | if (!ReadU16(&u16)) { 207 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 208 | return false; 209 | }; 210 | 211 | // Bits per sample 212 | if (!ReadU16(&bitsPerSample)) { 213 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 214 | return false; 215 | }; 216 | if ((bitsPerSample!=8) && (bitsPerSample != 16)) { 217 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, only 8 or 16 bits is supported \n")); 218 | return false; 219 | } // Only 8 or 16 bits 220 | 221 | // Skip any extra header 222 | while (toSkip) { 223 | uint8_t ign; 224 | if (!ReadU8(&ign)) { 225 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 226 | return false; 227 | }; 228 | toSkip--; 229 | } 230 | 231 | // look for data subchunk 232 | do { 233 | // id == "data" 234 | if (!ReadU32(&u32)) { 235 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 236 | return false; 237 | }; 238 | if (u32 == 0x61746164) break; // "data" 239 | // Skip size, read until end of chunk 240 | if (!ReadU32(&u32)) { 241 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 242 | return false; 243 | }; 244 | if(!file->seek(u32, SEEK_CUR)) { 245 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data, seek failed\n")); 246 | return false; 247 | } 248 | } while (1); 249 | if (!file->isOpen()) { 250 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, file is not open\n")); 251 | return false; 252 | }; 253 | 254 | // Skip size, read until end of file... 255 | if (!ReadU32(&u32)) { 256 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); 257 | return false; 258 | }; 259 | availBytes = u32; 260 | 261 | // Now set up the buffer or fail 262 | buff = reinterpret_cast(malloc(buffSize)); 263 | if (!buff) { 264 | Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, failed to set up buffer \n")); 265 | return false; 266 | }; 267 | buffPtr = 0; 268 | buffLen = 0; 269 | 270 | return true; 271 | } 272 | 273 | bool AudioGeneratorWAV::begin(AudioFileSource *source, AudioOutput *output) 274 | { 275 | if (!source) { 276 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed: invalid source\n")); 277 | return false; 278 | } 279 | file = source; 280 | if (!output) { 281 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: invalid output\n")); 282 | return false; 283 | } 284 | this->output = output; 285 | if (!file->isOpen()) { 286 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: file not open\n")); 287 | return false; 288 | } // Error 289 | 290 | if (!ReadWAVInfo()) { 291 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed during ReadWAVInfo\n")); 292 | return false; 293 | } 294 | 295 | if (!output->SetRate( sampleRate )) { 296 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetRate in output\n")); 297 | return false; 298 | } 299 | if (!output->SetBitsPerSample( bitsPerSample )) { 300 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetBitsPerSample in output\n")); 301 | return false; 302 | } 303 | if (!output->SetChannels( channels )) { 304 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetChannels in output\n")); 305 | return false; 306 | } 307 | if (!output->begin()) { 308 | Serial.printf_P(PSTR("AudioGeneratorWAV::begin: output's begin did not return true\n")); 309 | return false; 310 | } 311 | 312 | running = true; 313 | 314 | return true; 315 | } 316 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/AudioOutputI2S.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | AudioOutputI2S 3 | Base class for I2S interface port 4 | 5 | Copyright (C) 2017 Earle F. Philhower, III 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | #ifdef ESP32 23 | #include "driver/i2s.h" 24 | #elif defined(ARDUINO_ARCH_RP2040) || ARDUINO_ESP8266_MAJOR >= 3 25 | #include 26 | #elif ARDUINO_ESP8266_MAJOR < 3 27 | #include 28 | #endif 29 | #include "AudioOutputI2S.h" 30 | 31 | #if defined(ESP32) || defined(ESP8266) 32 | AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int use_apll) 33 | { 34 | this->portNo = port; 35 | this->i2sOn = false; 36 | this->dma_buf_count = dma_buf_count; 37 | if (output_mode != EXTERNAL_I2S && output_mode != INTERNAL_DAC && output_mode != INTERNAL_PDM) { 38 | output_mode = EXTERNAL_I2S; 39 | } 40 | this->output_mode = output_mode; 41 | this->use_apll = use_apll; 42 | 43 | //set defaults 44 | mono = false; 45 | lsb_justified = false; 46 | bps = 16; 47 | channels = 2; 48 | hertz = 44100; 49 | bclkPin = 26; 50 | wclkPin = 25; 51 | doutPin = 22; 52 | SetGain(1.0); 53 | } 54 | 55 | bool AudioOutputI2S::SetPinout() 56 | { 57 | #ifdef ESP32 58 | if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) 59 | return false; // Not allowed 60 | 61 | i2s_pin_config_t pins = { 62 | .bck_io_num = bclkPin, 63 | .ws_io_num = wclkPin, 64 | .data_out_num = doutPin, 65 | .data_in_num = I2S_PIN_NO_CHANGE}; 66 | i2s_set_pin((i2s_port_t)portNo, &pins); 67 | return true; 68 | #else 69 | (void)bclkPin; 70 | (void)wclkPin; 71 | (void)doutPin; 72 | return false; 73 | #endif 74 | } 75 | 76 | bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout) 77 | { 78 | bclkPin = bclk; 79 | wclkPin = wclk; 80 | doutPin = dout; 81 | if (i2sOn) 82 | return SetPinout(); 83 | 84 | return true; 85 | } 86 | #elif defined(ARDUINO_ARCH_RP2040) 87 | AudioOutputI2S::AudioOutputI2S(long sampleRate, pin_size_t sck, pin_size_t data) { 88 | i2sOn = false; 89 | mono = false; 90 | bps = 16; 91 | channels = 2; 92 | hertz = sampleRate; 93 | bclkPin = sck; 94 | doutPin = data; 95 | SetGain(1.0); 96 | } 97 | #endif 98 | 99 | AudioOutputI2S::~AudioOutputI2S() 100 | { 101 | /* 102 | #ifdef ESP32 103 | if (i2sOn) { 104 | audioLogger->printf("UNINSTALL I2S\n"); 105 | i2s_driver_uninstall((i2s_port_t)portNo); //stop & destroy i2s driver 106 | } 107 | #elif defined(ESP8266) 108 | if (i2sOn) 109 | i2s_end(); 110 | #elif defined(ARDUINO_ARCH_RP2040) 111 | stop(); 112 | #endif 113 | i2sOn = false; 114 | */ 115 | stop(); 116 | } 117 | 118 | bool AudioOutputI2S::SetRate(int hz) 119 | { 120 | // TODO - have a list of allowable rates from constructor, check them 121 | this->hertz = hz; 122 | if (i2sOn) 123 | { 124 | #ifdef ESP32 125 | i2s_set_sample_rates((i2s_port_t)portNo, AdjustI2SRate(hz)); 126 | #elif defined(ESP8266) 127 | i2s_set_rate(AdjustI2SRate(hz)); 128 | #elif defined(ARDUINO_ARCH_RP2040) 129 | I2S.setFrequency(hz); 130 | #endif 131 | } 132 | return true; 133 | } 134 | 135 | bool AudioOutputI2S::SetBitsPerSample(int bits) 136 | { 137 | if ( (bits != 16) && (bits != 8) ) return false; 138 | this->bps = bits; 139 | return true; 140 | } 141 | 142 | bool AudioOutputI2S::SetChannels(int channels) 143 | { 144 | if ( (channels < 1) || (channels > 2) ) return false; 145 | this->channels = channels; 146 | return true; 147 | } 148 | 149 | bool AudioOutputI2S::SetOutputModeMono(bool mono) 150 | { 151 | this->mono = mono; 152 | return true; 153 | } 154 | 155 | bool AudioOutputI2S::SetLsbJustified(bool lsbJustified) 156 | { 157 | this->lsb_justified = lsbJustified; 158 | return true; 159 | } 160 | 161 | bool AudioOutputI2S::begin(bool txDAC) 162 | { 163 | #ifdef ESP32 164 | if (!i2sOn) 165 | { 166 | if (use_apll == APLL_AUTO) 167 | { 168 | // don't use audio pll on buggy rev0 chips 169 | use_apll = APLL_DISABLE; 170 | esp_chip_info_t out_info; 171 | esp_chip_info(&out_info); 172 | if (out_info.revision > 0) 173 | { 174 | use_apll = APLL_ENABLE; 175 | } 176 | } 177 | 178 | i2s_mode_t mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX); 179 | if (output_mode == INTERNAL_DAC) 180 | { 181 | #if CONFIG_IDF_TARGET_ESP32 182 | mode = (i2s_mode_t)(mode | I2S_MODE_DAC_BUILT_IN); 183 | #else 184 | return false; 185 | #endif 186 | } 187 | else if (output_mode == INTERNAL_PDM) 188 | { 189 | #if CONFIG_IDF_TARGET_ESP32 190 | mode = (i2s_mode_t)(mode | I2S_MODE_PDM); 191 | #else 192 | return false; 193 | #endif 194 | } 195 | 196 | i2s_comm_format_t comm_fmt; 197 | if (output_mode == INTERNAL_DAC) 198 | { 199 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) 200 | comm_fmt = (i2s_comm_format_t) I2S_COMM_FORMAT_STAND_MSB; 201 | #else 202 | comm_fmt = (i2s_comm_format_t) I2S_COMM_FORMAT_I2S_MSB; 203 | #endif 204 | } 205 | else if (lsb_justified) 206 | { 207 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) 208 | comm_fmt = (i2s_comm_format_t) I2S_COMM_FORMAT_STAND_MSB; 209 | #else 210 | comm_fmt = (i2s_comm_format_t) (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB); 211 | #endif 212 | } 213 | else 214 | { 215 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) 216 | comm_fmt = (i2s_comm_format_t) (I2S_COMM_FORMAT_STAND_I2S); 217 | #else 218 | comm_fmt = (i2s_comm_format_t) (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB); 219 | #endif 220 | } 221 | 222 | i2s_config_t i2s_config_dac = { 223 | .mode = mode, 224 | .sample_rate = 44100, 225 | .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, 226 | .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, 227 | .communication_format = comm_fmt, 228 | .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // lowest interrupt priority 229 | .dma_buf_count = dma_buf_count, 230 | .dma_buf_len = 64, 231 | .use_apll = use_apll // Use audio PLL 232 | }; 233 | audioLogger->printf("+%d %p\n", portNo, &i2s_config_dac); 234 | if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_dac, 0, NULL) != ESP_OK) 235 | { 236 | audioLogger->println("ERROR: Unable to install I2S drives\n"); 237 | } 238 | if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) 239 | { 240 | #if CONFIG_IDF_TARGET_ESP32 241 | i2s_set_pin((i2s_port_t)portNo, NULL); 242 | i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); 243 | #else 244 | return false; 245 | #endif 246 | } 247 | else 248 | { 249 | SetPinout(); 250 | } 251 | i2s_zero_dma_buffer((i2s_port_t)portNo); 252 | } 253 | #elif defined(ESP8266) 254 | (void)dma_buf_count; 255 | (void)use_apll; 256 | if (!i2sOn) 257 | { 258 | orig_bck = READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U); 259 | orig_ws = READ_PERI_REG(PERIPHS_IO_MUX_GPIO2_U); 260 | #ifdef I2S_HAS_BEGIN_RXTX_DRIVE_CLOCKS 261 | if (!i2s_rxtxdrive_begin(false, true, false, txDAC)) { 262 | return false; 263 | } 264 | #else 265 | if (!i2s_rxtx_begin(false, true)) { 266 | return false; 267 | } 268 | if (!txDAC) { 269 | audioLogger->printf_P(PSTR("I2SNoDAC: esp8266 arduino core should be upgraded to avoid conflicts with SPI\n")); 270 | } 271 | #endif 272 | } 273 | #elif defined(ARDUINO_ARCH_RP2040) 274 | (void)txDAC; 275 | if (!i2sOn) { 276 | I2S.setBCLK(bclkPin); 277 | I2S.setDOUT(doutPin); 278 | I2S.begin(hertz); 279 | } 280 | #endif 281 | i2sOn = true; 282 | SetRate(hertz); // Default 283 | return true; 284 | } 285 | 286 | bool AudioOutputI2S::ConsumeSample(int16_t sample[2]) 287 | { 288 | 289 | //return if we haven't called ::begin yet 290 | if (!i2sOn) 291 | return false; 292 | 293 | int16_t ms[2]; 294 | 295 | ms[0] = sample[0]; 296 | ms[1] = sample[1]; 297 | MakeSampleStereo16( ms ); 298 | 299 | if (this->mono) { 300 | // Average the two samples and overwrite 301 | int32_t ttl = ms[LEFTCHANNEL] + ms[RIGHTCHANNEL]; 302 | ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl>>1) & 0xffff; 303 | } 304 | #ifdef ESP32 305 | uint32_t s32; 306 | if (output_mode == INTERNAL_DAC) 307 | { 308 | int16_t l = Amplify(ms[LEFTCHANNEL]) + 0x8000; 309 | int16_t r = Amplify(ms[RIGHTCHANNEL]) + 0x8000; 310 | s32 = (r << 16) | (l & 0xffff); 311 | } 312 | else 313 | { 314 | s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff); 315 | } 316 | //"i2s_write_bytes" has been removed in the ESP32 Arduino 2.0.0, use "i2s_write" instead. 317 | // return i2s_write_bytes((i2s_port_t)portNo, (const char *)&s32, sizeof(uint32_t), 0); 318 | 319 | size_t i2s_bytes_written; 320 | i2s_write((i2s_port_t)portNo, (const char*)&s32, sizeof(uint32_t), &i2s_bytes_written, 0); 321 | return i2s_bytes_written; 322 | #elif defined(ESP8266) 323 | uint32_t s32 = ((Amplify(ms[RIGHTCHANNEL])) << 16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff); 324 | return i2s_write_sample_nb(s32); // If we can't store it, return false. OTW true 325 | #elif defined(ARDUINO_ARCH_RP2040) 326 | return !!I2S.write((void*)ms, 4); 327 | #endif 328 | } 329 | 330 | void AudioOutputI2S::flush() 331 | { 332 | #ifdef ESP32 333 | // makes sure that all stored DMA samples are consumed / played 334 | int buffersize = 64 * this->dma_buf_count; 335 | int16_t samples[2] = {0x0, 0x0}; 336 | for (int i = 0; i < buffersize; i++) 337 | { 338 | while (!ConsumeSample(samples)) 339 | { 340 | delay(10); 341 | } 342 | } 343 | #elif defined(ARDUINO_ARCH_RP2040) 344 | I2S.flush(); 345 | #endif 346 | } 347 | 348 | bool AudioOutputI2S::stop() 349 | { 350 | if (!i2sOn) 351 | return false; 352 | 353 | #ifdef ESP32 354 | i2s_zero_dma_buffer((i2s_port_t)portNo); 355 | i2s_driver_uninstall((i2s_port_t)portNo); //stop & destroy i2s driver 356 | #elif defined(ESP8266) 357 | i2s_end(); 358 | #elif defined(ARDUINO_ARCH_RP2040) 359 | I2S.end(); 360 | #endif 361 | i2sOn = false; 362 | return true; 363 | } 364 | -------------------------------------------------------------------------------- /src/input.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------------------- 3 | * CircuitSetup.us Flux Capacitor 4 | * (C) 2023 Thomas Winischhofer (A10001986) 5 | * https://github.com/realA10001986/Flux-Capacitor 6 | * http://fc.backtothefutu.re 7 | * 8 | * FCRemote Class: Remote control handling 9 | * Inspired by Ken Shirriff's IRRemote library 10 | * 11 | * ------------------------------------------------------------------- 12 | * License: MIT 13 | * 14 | * Permission is hereby granted, free of charge, to any person 15 | * obtaining a copy of this software and associated documentation 16 | * files (the "Software"), to deal in the Software without restriction, 17 | * including without limitation the rights to use, copy, modify, 18 | * merge, publish, distribute, sublicense, and/or sell copies of the 19 | * Software, and to permit persons to whom the Software is furnished to 20 | * do so, subject to the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 28 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 29 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 30 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 31 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | 34 | #include 35 | 36 | #include "input.h" 37 | 38 | /* 39 | * IRRemote class 40 | */ 41 | 42 | #define TMR_TIME 0.00005 // 0.00005s = 50us 43 | #define TMR_PRESCALE 80 44 | #define TMR_TICKS (uint64_t)(((double)TMR_TIME * 80000000.0) / (double)TMR_PRESCALE) 45 | #define TME_TIMEUS (TMR_TIME * 1000000) 46 | 47 | #define GAP_DUR 5000 // Minimum gap between transmissions in us (microseconds) 48 | #define GAP_TICKS (GAP_DUR / TME_TIMEUS) 49 | 50 | // IR receiver pin polarity 51 | #define IR_LIGHT 0 52 | #define IR_DARK 1 53 | 54 | static void IRAM_ATTR IRTimer_ISR(); 55 | 56 | static uint8_t _ir_pin; 57 | 58 | static volatile uint32_t _cnt = 0; 59 | static volatile IRState _irstate = IRSTATE_IDLE; 60 | static volatile uint32_t _irlen = 0; 61 | static volatile uint32_t _irbuf[IRBUFSIZE]; 62 | 63 | // ISR 64 | // Record duration of marks/spaces through a simple state machine 65 | static void IRAM_ATTR IRTimer_ISR() 66 | { 67 | uint8_t irpin = (uint8_t)digitalRead(_ir_pin); 68 | 69 | _cnt++; 70 | 71 | switch(_irstate) { 72 | case IRSTATE_IDLE: 73 | if(irpin == IR_LIGHT) { 74 | if(_cnt >= GAP_TICKS) { 75 | // Current gap longer than minimum gap size, 76 | // start recording. 77 | // (In case of a smaller gap, we assume being in 78 | // the middle of a transmission whose start we 79 | // missed. Do nothing then. 80 | _irstate = IRSTATE_LIGHT; 81 | _irbuf[0] = _cnt; // First is length of previous gap 82 | _irlen = 1; 83 | } 84 | _cnt = 0; 85 | } 86 | break; 87 | case IRSTATE_LIGHT: 88 | if(irpin == IR_DARK) { 89 | _irstate = IRSTATE_DARK; 90 | _irbuf[_irlen++] = _cnt; 91 | _cnt = 0; 92 | if(_irlen >= IRBUFSIZE) _irstate = IRSTATE_STOP; 93 | } 94 | break; 95 | case IRSTATE_DARK: 96 | if(irpin == IR_LIGHT) { 97 | _irstate = IRSTATE_LIGHT; 98 | _irbuf[_irlen++] = _cnt; 99 | _cnt = 0; 100 | if(_irlen >= IRBUFSIZE) _irstate = IRSTATE_STOP; 101 | } else if(_cnt > GAP_TICKS) { 102 | // Gap longer than usual space, transmission finished. 103 | _irstate = IRSTATE_STOP; 104 | } 105 | break; 106 | case IRSTATE_STOP: 107 | if(irpin == IR_LIGHT) _cnt = 0; // Reset cnt whenever we see something, even if we miss recording it 108 | break; 109 | } 110 | } 111 | 112 | // Store basic config data 113 | IRRemote::IRRemote(uint8_t timer_no, uint8_t ir_pin) 114 | { 115 | _timer_no = timer_no; 116 | _ir_pin = ir_pin; 117 | } 118 | 119 | void IRRemote::begin() 120 | { 121 | pinMode(_ir_pin, INPUT); 122 | _irstate = IRSTATE_IDLE; 123 | _irlen = 0; 124 | 125 | // Install & enable interrupt 126 | _IRTimer = timerBegin(_timer_no, TMR_PRESCALE, true); 127 | timerAttachInterrupt(_IRTimer, &IRTimer_ISR, true); 128 | timerAlarmWrite(_IRTimer, TMR_TICKS, true); 129 | timerAlarmEnable(_IRTimer); 130 | } 131 | 132 | // Decode IR signal 133 | bool IRRemote::loop() 134 | { 135 | // No new transmission, bail... 136 | if(_irstate != IRSTATE_STOP) 137 | return false; 138 | 139 | // Copy result to backup buffer 140 | _buflen = _irlen; 141 | for(uint8_t i = 0; i < _buflen; i++) { 142 | _buf[i] = _irbuf[i]; 143 | } 144 | 145 | // Continue recording 146 | resume(); 147 | 148 | // Calc hash on received "code" 149 | if(calcHash()) { 150 | unsigned long now = millis(); 151 | if(_hvalue == _prevHash) { 152 | if(now - _prevTime < 300) { 153 | _prevTime = now; 154 | return false; 155 | } 156 | } 157 | _prevHash = _hvalue; 158 | _prevTime = now; 159 | return true; 160 | } 161 | 162 | return false; 163 | } 164 | 165 | void IRRemote::resume() 166 | { 167 | _irstate = IRSTATE_IDLE; 168 | } 169 | 170 | uint32_t IRRemote::readHash() 171 | { 172 | return _hvalue; 173 | } 174 | 175 | 176 | /* CalcHash: Calculate hash over an arbitrary IR code 177 | * 178 | * Based on code published here: 179 | * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html 180 | * 181 | */ 182 | 183 | uint32_t IRRemote::compare(uint32_t a, uint32_t b) 184 | { 185 | if(b < a * 80 / 100) return 0; 186 | if(a < b * 80 / 100) return 2; 187 | return 1; 188 | } 189 | 190 | /* Converts the raw code values into a 32-bit hash code. 191 | * Use FNV-1 (Fowler–Noll–Vo) hash algorithm. 192 | * https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function 193 | */ 194 | 195 | #define FNV_PRIME_32 16777619 196 | #define FNV_BASIS_32 2166136261 197 | 198 | bool IRRemote::calcHash() 199 | { 200 | if(_buflen < 6) 201 | return false; 202 | 203 | uint32_t hash = FNV_BASIS_32; 204 | 205 | for(int i = 1; i + 2 < _buflen; i++) { 206 | hash = (hash * FNV_PRIME_32) ^ compare(_buf[i], _buf[i+2]); 207 | } 208 | 209 | _hvalue = hash; 210 | 211 | return true; 212 | } 213 | 214 | /* 215 | * FCButton class 216 | * 217 | * If a Long-Press-function is registered, a "press" is only reported only after 218 | * the button is released. If no such function is registered, a press is 219 | * reported immediately (after PressTicks have elapsed), regardless of a button 220 | * release. The latter mode is used for when the TCD is connected to trigger 221 | * time travels. 222 | */ 223 | 224 | /* pin: The pin to be used 225 | * activeLow: Set to true when the input level is LOW when the button is pressed, Default is true. 226 | * pullupActive: Activate the internal pullup when available. Default is true. 227 | */ 228 | FCButton::FCButton(const int pin, const boolean activeLow, const bool pullupActive) 229 | { 230 | _pin = pin; 231 | 232 | _buttonPressed = activeLow ? LOW : HIGH; 233 | 234 | pinMode(pin, pullupActive ? INPUT_PULLUP : INPUT); 235 | } 236 | 237 | 238 | // Number of millisec that have to pass by before a click is assumed stable. 239 | void FCButton::setDebounceTicks(const int ticks) 240 | { 241 | _debounceTicks = ticks; 242 | } 243 | 244 | 245 | // Number of millisec that have to pass by before a short press is detected. 246 | void FCButton::setPressTicks(const int ticks) 247 | { 248 | _pressTicks = ticks; 249 | } 250 | 251 | 252 | // Number of millisec that have to pass by before a long press is detected. 253 | void FCButton::setLongPressTicks(const int ticks) 254 | { 255 | _longPressTicks = ticks; 256 | } 257 | 258 | // Register function for short press event 259 | void FCButton::attachPress(void (*newFunction)(void)) 260 | { 261 | _pressFunc = newFunction; 262 | } 263 | 264 | // Register function for long press start event 265 | void FCButton::attachLongPressStart(void (*newFunction)(void)) 266 | { 267 | _longPressStartFunc = newFunction; 268 | } 269 | 270 | // Register function for long press stop event 271 | void FCButton::attachLongPressStop(void (*newFunction)(void)) 272 | { 273 | _longPressStopFunc = newFunction; 274 | } 275 | 276 | // Check input of the pin and advance the state machine 277 | void FCButton::scan(void) 278 | { 279 | unsigned long now = millis(); 280 | unsigned long waitTime = now - _startTime; 281 | bool active = (digitalRead(_pin) == _buttonPressed); 282 | 283 | switch(_state) { 284 | case TCBS_IDLE: 285 | if(active) { 286 | transitionTo(TCBS_PRESSED); 287 | _startTime = now; 288 | } 289 | break; 290 | 291 | case TCBS_PRESSED: 292 | if((!active) && (waitTime < _debounceTicks)) { // de-bounce 293 | transitionTo(_lastState); 294 | } else if(!active) { 295 | transitionTo(TCBS_RELEASED); 296 | _startTime = now; 297 | } else if(active) { 298 | if(!_longPressStartFunc) { 299 | if(waitTime > _pressTicks) { 300 | if(_pressFunc) _pressFunc(); 301 | _pressNotified = true; 302 | } 303 | } else if(waitTime > _longPressTicks) { 304 | if(_longPressStartFunc) _longPressStartFunc(); 305 | transitionTo(TCBS_LONGPRESS); 306 | } 307 | } 308 | break; 309 | 310 | case TCBS_RELEASED: 311 | if((active) && (waitTime < _debounceTicks)) { // de-bounce 312 | transitionTo(_lastState); 313 | } else if((!active) && (waitTime > _pressTicks)) { 314 | if(!_pressNotified && _pressFunc) _pressFunc(); 315 | reset(); 316 | } 317 | break; 318 | 319 | case TCBS_LONGPRESS: 320 | if(!active) { 321 | transitionTo(TCBS_LONGPRESSEND); 322 | _startTime = now; 323 | } 324 | break; 325 | 326 | case TCBS_LONGPRESSEND: 327 | if((active) && (waitTime < _debounceTicks)) { // de-bounce 328 | transitionTo(_lastState); 329 | } else if(waitTime >= _debounceTicks) { 330 | if(_longPressStopFunc) _longPressStopFunc(); 331 | reset(); 332 | } 333 | break; 334 | 335 | default: 336 | transitionTo(TCBS_IDLE); 337 | break; 338 | } 339 | } 340 | 341 | /* 342 | * Private 343 | */ 344 | 345 | void FCButton::reset(void) 346 | { 347 | _state = TCBS_IDLE; 348 | _lastState = TCBS_IDLE; 349 | _startTime = 0; 350 | _pressNotified = false; 351 | } 352 | 353 | // Advance to new state 354 | void FCButton::transitionTo(ButtonState nextState) 355 | { 356 | _lastState = _state; 357 | _state = nextState; 358 | } 359 | 360 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/README: -------------------------------------------------------------------------------- 1 | 2 | libmad - MPEG audio decoder library 3 | Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | 5 | $Id: README,v 1.4 2004/01/23 09:41:32 rob Exp $ 6 | 7 | =============================================================================== 8 | 9 | INTRODUCTION 10 | 11 | MAD (libmad) is a high-quality MPEG audio decoder. It currently supports 12 | MPEG-1 and the MPEG-2 extension to Lower Sampling Frequencies, as well as 13 | the so-called MPEG 2.5 format. All three audio layers (Layer I, Layer II, 14 | and Layer III a.k.a. MP3) are fully implemented. 15 | 16 | MAD does not yet support MPEG-2 multichannel audio (although it should be 17 | backward compatible with such streams) nor does it currently support AAC. 18 | 19 | MAD has the following special features: 20 | 21 | - 24-bit PCM output 22 | - 100% fixed-point (integer) computation 23 | - completely new implementation based on the ISO/IEC standards 24 | - distributed under the terms of the GNU General Public License (GPL) 25 | 26 | Because MAD provides full 24-bit PCM output, applications using MAD are 27 | able to produce high quality audio. Even when the output device supports 28 | only 16-bit PCM, applications can use the extra resolution to increase the 29 | audible dynamic range through the use of dithering or noise shaping. 30 | 31 | Because MAD uses integer computation rather than floating point, it is 32 | well suited for architectures without a floating point unit. All 33 | calculations are performed with a 32-bit fixed-point integer 34 | representation. 35 | 36 | Because MAD is a new implementation of the ISO/IEC standards, it is 37 | unencumbered by the errors of other implementations. MAD is NOT a 38 | derivation of the ISO reference source or any other code. Considerable 39 | effort has been expended to ensure a correct implementation, even in cases 40 | where the standards are ambiguous or misleading. 41 | 42 | Because MAD is distributed under the terms of the GPL, its redistribution 43 | is not generally restricted, so long as the terms of the GPL are followed. 44 | This means MAD can be incorporated into other software as long as that 45 | software is also distributed under the GPL. (Should this be undesirable, 46 | alternate arrangements may be possible by contacting Underbit.) 47 | 48 | =============================================================================== 49 | 50 | ABOUT THE CODE 51 | 52 | The code is optimized and performs very well, although specific 53 | improvements can still be made. The output from the decoder library 54 | consists of 32-bit signed linear fixed-point values that can be easily 55 | scaled for any size PCM output, up to 24 bits per sample. 56 | 57 | The API for libmad can be found in the `mad.h' header file. Note that this 58 | file is automatically generated, and will not exist until after you have 59 | built the library. 60 | 61 | There are two APIs available, one high-level, and the other low-level. 62 | With the low-level API, each step of the decoding process must be handled 63 | explicitly, offering the greatest amount of control. With the high-level 64 | API, after callbacks are configured, a single routine will decode an 65 | entire bitstream. 66 | 67 | The high-level API may either be used synchronously or asynchronously. If 68 | used asynchronously, decoding will occur in a separate process. 69 | Communication is possible with the decoding process by passing control 70 | messages. 71 | 72 | The file `minimad.c' contains an example usage of the libmad API that 73 | shows only the bare minimum required to implement a useful decoder. It 74 | expects a regular file to be redirected to standard input, and it sends 75 | decoded 16-bit signed little-endian PCM samples to standard output. If a 76 | decoding error occurs, it is reported to standard error and decoding 77 | continues. Note that the scale() routine in this code is only provided as 78 | an example; it rounds MAD's high-resolution samples down to 16 bits, but 79 | does not perform any dithering or noise shaping. It is therefore not 80 | recommended to use this routine as-is in your own code if sound quality is 81 | important. 82 | 83 | Integer Performance 84 | 85 | To get the best possible performance, it is recommended that an assembly 86 | version of the fixed-point multiply and related routines be selected. 87 | Several such assembly routines have been written for various CPUs. 88 | 89 | If an assembly version is not available, a fast approximation version will 90 | be used. This will result in reduced accuracy of the decoder. 91 | 92 | Alternatively, if 64-bit integers are supported as a datatype by the 93 | compiler, another version can be used that is much more accurate. 94 | However, using an assembly version is generally much faster and just as 95 | accurate. 96 | 97 | More information can be gathered from the `fixed.h' header file. 98 | 99 | MAD's CPU-intensive subband synthesis routine can be further optimized at 100 | the expense of a slight loss in output accuracy due to a modified method 101 | for fixed-point multiplication with a small windowing constant. While this 102 | is helpful for performance and the output accuracy loss is generally 103 | undetectable, it is disabled by default and must be explicitly enabled. 104 | 105 | Under some architectures, other special optimizations may also be 106 | available. 107 | 108 | Audio Quality 109 | 110 | The output from MAD has been found to satisfy the ISO/IEC 11172-4 111 | computational accuracy requirements for compliance. In most 112 | configurations, MAD is a Full Layer III ISO/IEC 11172-3 audio decoder as 113 | defined by the standard. 114 | 115 | When the approximation version of the fixed-point multiply is used, MAD is 116 | a limited accuracy ISO/IEC 11172-3 audio decoder as defined by the 117 | standard. 118 | 119 | MAD can alternatively be configured to produce output with less or more 120 | accuracy than the default, as a tradeoff with performance. 121 | 122 | MAD produces output samples with a precision greater than 24 bits. Because 123 | most output formats use fewer bits, typically 16, it is recommended that a 124 | dithering algorithm be used (rather than rounding or truncating) to obtain 125 | the highest quality audio. However, dithering may unfavorably affect an 126 | analytic examination of the output (such as compliance testing); you may 127 | therefore wish to use rounding in this case instead. 128 | 129 | Portability Issues 130 | 131 | GCC is preferred to compile the code, but other compilers may also work. 132 | The assembly code in `fixed.h' depends on the inline assembly features of 133 | your compiler. If you're not using GCC or MSVC++, you can either write 134 | your own assembly macros or use the default (low quality output) version. 135 | 136 | The union initialization of `huffman.c' may not be portable to all 137 | platforms when GCC is not used. 138 | 139 | The code should not be sensitive to word sizes or byte ordering, however 140 | it does assume A % B has the same sign as A. 141 | 142 | =============================================================================== 143 | 144 | BUILDING AND INSTALLING 145 | 146 | Windows Platforms 147 | 148 | MAD can be built under Windows using either MSVC++ or Cygwin. A MSVC++ 149 | project file can be found under the `msvc++' subdirectory. 150 | 151 | To build libmad using Cygwin, you will first need to install the Cygwin 152 | tools: 153 | 154 | http://www.cygwin.com/ 155 | 156 | You may then proceed with the following POSIX instructions within the 157 | Cygwin shell. 158 | 159 | Note that by default Cygwin will build a library that depends on the 160 | Cygwin DLL. You can use MinGW to build a library that does not depend on 161 | the Cygwin DLL. To do so, give the option --host=mingw32 to `configure'. 162 | 163 | POSIX Platforms (including Cygwin) 164 | 165 | The code is distributed with a `configure' script that will generate for 166 | you a `Makefile' and a `config.h' for your platform. See the file 167 | `INSTALL' for generic instructions. 168 | 169 | The specific options you may want to give `configure' are: 170 | 171 | --enable-speed optimize for speed over accuracy 172 | 173 | --enable-accuracy optimize for accuracy over speed 174 | 175 | --disable-debugging do not compile with debugging support, and 176 | use more optimizations 177 | 178 | --disable-shared do not build a shared library 179 | 180 | Note that you need not specify one of --enable-speed or --enable-accuracy; 181 | in its default configuration, MAD is optimized for both. You should only 182 | use one of these options if you wish to compromise speed or accuracy for 183 | the other. 184 | 185 | By default the package will build a shared library if possible for your 186 | platform. If you want only a static library, use --disable-shared. 187 | 188 | It is not normally necessary to use the following options, but you may 189 | fine-tune the configuration with them if desired: 190 | 191 | --enable-fpm=ARCH use the ARCH-specific version of the 192 | fixed-point math assembly routines 193 | (current options are: intel, arm, mips, 194 | sparc, ppc; also allowed are: 64bit, approx) 195 | 196 | --enable-sso use the subband synthesis optimization, 197 | with reduced accuracy 198 | 199 | --disable-aso do not use certain architecture-specific 200 | optimizations 201 | 202 | By default an appropriate fixed-point assembly routine will be selected 203 | for the configured host type, if it can be determined. Thus if you are 204 | cross-compiling for another architecture, you should be sure either to 205 | give `configure' a host type argument (--host) or to use an explicit 206 | --enable-fpm option. 207 | 208 | If an appropriate assembly routine cannot be determined, the default 209 | approximation version will be used. In this case, use of an alternate 210 | --enable-fpm is highly recommended. 211 | 212 | Experimenting and Developing 213 | 214 | Further options for `configure' that may be useful to developers and 215 | experimenters are: 216 | 217 | --enable-debugging enable diagnostic debugging support and 218 | debugging symbols 219 | 220 | --enable-profiling generate `gprof' profiling code 221 | 222 | --enable-experimental enable code using the EXPERIMENTAL 223 | preprocessor define 224 | 225 | =============================================================================== 226 | 227 | COPYRIGHT 228 | 229 | Please read the `COPYRIGHT' file for copyright and warranty information. 230 | Also, the file `COPYING' contains the full text of the GNU GPL. 231 | 232 | Send inquiries, comments, bug reports, suggestions, patches, etc. to: 233 | 234 | Underbit Technologies, Inc. 235 | 236 | See also the MAD home page on the Web: 237 | 238 | http://www.underbit.com/products/mad/ 239 | 240 | =============================================================================== 241 | 242 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/CHANGES: -------------------------------------------------------------------------------- 1 | 2 | libmad - MPEG audio decoder library 3 | Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | 5 | $Id: CHANGES,v 1.14 2004/02/17 02:02:03 rob Exp $ 6 | 7 | =============================================================================== 8 | 9 | Version 0.15.1 (beta) 10 | 11 | * Updated to autoconf 2.59, automake 1.8.2, libtool 1.5.2. 12 | 13 | * Replaced Layer III IMDCT routine with one based on a faster algorithm, 14 | improving both speed and accuracy. 15 | 16 | * Improved portability of the Huffman table initialization. 17 | 18 | * Fixed a problem that could result in an assertion failure in layer3.c 19 | due to an invalid Layer III free format bitrate. 20 | 21 | * Improved the robustness of Layer II bitrate/mode combinations, and added 22 | a new MAD_ERROR_BADMODE error enum. The allowability of low-bitrate 23 | stereo streams is influenced by the --enable-strict-iso option to 24 | `configure'. 25 | 26 | Version 0.15.0 (beta) 27 | 28 | * Updated to autoconf 2.57, automake 1.7.5, libtool 1.4.3. 29 | 30 | * Added new mad_f_div() API routine. 31 | 32 | * Added a 64th entry to the Layer I/Layer II scalefactor table, for better 33 | compatibility with existing streams. The --enable-strict-iso option to 34 | `configure' can be used to disable use of this entry. 35 | 36 | * Modified the header decoding routine to allow the reserved emphasis 37 | value, for better compatibility with existing streams. The 38 | --enable-strict-iso option to `configure' can be used to restore the 39 | previous behavior of reporting this value as an error. 40 | 41 | * Added new MAD_EMPHASIS_RESERVED enumeration constant. 42 | 43 | * Fixed a bug in the ARM version of mad_f_scale64() discovered by Andre 44 | McCurdy. 45 | 46 | * Rewrote PowerPC assembly for minor gains. 47 | 48 | * Modified mad_timer_fraction() to avoid the possibility of division by 49 | zero when 0 is passed as the second argument. 50 | 51 | * Fixed a non-fatal problem caused by attempting to designate ancillary 52 | bits in Layer III after a decoding error. 53 | 54 | * Changed to build a shared library by default. 55 | 56 | * Changed to use native Cygwin build by default; give --host=mingw32 to 57 | `configure' to use MinGW (and avoid a dependency on the Cygwin DLL). 58 | 59 | Version 0.14.2 (beta) 60 | 61 | * Changed Cygwin builds to use MinGW; resulting Win32 executables no 62 | longer have a dependency on Cygwin DLLs. 63 | 64 | * Added a new mad_stream_errorstr() API function to libmad for retrieving 65 | a string description of the current error condition. 66 | 67 | Version 0.14.1 (beta) 68 | 69 | * Updated config.guess and config.sub to latest upstream versions. 70 | 71 | * Enabled libtool versioning rather than release numbering. 72 | 73 | * Improved the documentation in minimad.c. 74 | 75 | * Several other small fixes. 76 | 77 | Version 0.14.0 (beta) 78 | 79 | * Added a 64-bit FPM negation operation to improve performance of subband 80 | synthesis on some platforms. 81 | 82 | * Improved MSVC++ portability and added MSVC++ project files. 83 | 84 | * Added rounding to Layer III requantization for slightly better accuracy. 85 | 86 | Version 0.13.0 (beta) 87 | 88 | * Ancillary data is now properly extracted from Layer III streams. 89 | 90 | * Rewrote the Layer III joint stereo decoding routine to correct a major 91 | MPEG-2 problem and a minor MPEG-1 problem decoding intensity stereo. 92 | 93 | * Eliminated the dependency on sign-extending right shifts for Layer I and 94 | Layer II. 95 | 96 | * Renamed `private' field to `private_bits' for better C++ compatibility. 97 | 98 | * Gratuitously renamed `sfreq' field to `samplerate' and 99 | MAD_ERROR_BADSAMPLEFREQ constant to MAD_ERROR_BADSAMPLERATE. 100 | 101 | * Added `samplerate' and `channels' fields to synth.pcm struct to allow 102 | these to be different from the decoded frame, and for simpler access. 103 | 104 | * Added new mad_stream_options() and mad_decoder_options() API entries for 105 | special runtime decoding options. 106 | 107 | * Added new MAD_OPTION_IGNORECRC and MAD_OPTION_HALFSAMPLERATE options. 108 | 109 | * Added new MAD_FLAG_FREEFORMAT indicator flag. 110 | 111 | * Fixed some bugs in the async decoder. 112 | 113 | * Added a new mad_timer_multiply() API routine. 114 | 115 | * Eliminated `+' from asm constraints under Intel for better compatibility 116 | with some compilers. 117 | 118 | * Fixed a PIC-related problem in imdct_l_arm.S. 119 | 120 | * Eliminated a static variable to make libmad thread-safe. 121 | 122 | Version 0.12.5 (beta) 123 | 124 | * Modified Layer III requantization to occur during Huffman decoding for 125 | significant performance gains. 126 | 127 | * Optimized short block IMDCT by eliminating redundant calculations. 128 | 129 | * Made several other Layer III performance improvements; added 130 | ASO_INTERLEAVE1, ASO_INTERLEAVE2, and ASO_ZEROCHECK 131 | architecture-specific options for best performance on various 132 | architectures. 133 | 134 | * Optimized synthesis DCT to store result values as soon as they are 135 | calculated. 136 | 137 | Version 0.12.4 (beta) 138 | 139 | * New PowerPC fixed-point assembly courtesy of David Blythe. 140 | 141 | * Reorganized fixed-point assembly routines for easier maintenance and 142 | better performance. 143 | 144 | * Improved performance of subband synthesis through better indexing and 145 | fewer local variables. 146 | 147 | * Added alias reduction for the lower two subbands of mixed short blocks, 148 | per a report of ambiguity with ISO/IEC 11172-3 and for uniformity with 149 | most other implementations. Also improved alias reduction performance 150 | using multiply/accumulate. 151 | 152 | * Added --enable-strict-iso option to `configure' to override best 153 | accepted practices such as the alias reduction for mixed short blocks. 154 | 155 | * Improved performance of Layer III IMDCT by using longer 156 | multiply/accumulate runs where possible. 157 | 158 | Version 0.12.3 (beta) 159 | 160 | * Added MPEG 2.5 support. 161 | 162 | * Added preliminary support for parameterizing the binary point position 163 | in the fixed-point representation. 164 | 165 | * Added multiply/accumulate optimization to the Layer III IMDCT for long 166 | blocks. 167 | 168 | * Fixed a bug in the handling of Layer III mixed_block_flag. 169 | 170 | * Fixed a configure problem when multiple -O CFLAGS are present. 171 | 172 | Version 0.12.2 (beta) 173 | 174 | * Rearranged the synthesis polyphase filterbank memory vector for better 175 | locality of reference, and rewrote mad_synth_frame() to accommodate, 176 | resulting in improved performance. 177 | 178 | * Discovered a combination of compiler optimization flags that further 179 | improve performance. 180 | 181 | * Changed some array references in layer3.c to pointer derefs. 182 | 183 | Version 0.12.1 (beta) 184 | 185 | * Resolved the intensity + MS joint stereo issue (a simple bug). 186 | OPT_ISKLUGE is no longer considered to be a kluge. 187 | 188 | * Fixed another, hopefully last main_data memory bug. 189 | 190 | * Split part of struct mad_frame into struct mad_header for convenience 191 | and size. 192 | 193 | Version 0.12.0 (alpha) 194 | 195 | * Changed the build environment to use automake and libtool. A libmad 196 | shared library can now be built using the --enable-shared option to 197 | `configure'. 198 | 199 | * Added another callback to MAD's high-level decoder API after the frame 200 | header has been read but before the frame's audio data is decoded. 201 | 202 | * Streamlined header processing so that mad_frame_decode() can be called 203 | with or without having already called mad_frame_header(). 204 | 205 | * Fixed some other header reading miscellany, including CRC handling and 206 | free bitrate detection, and frame length verification with free 207 | bitrates. 208 | 209 | * Fixed a problem with Layer III free bitrates > 320 kbps. The main_data 210 | buffer size should now be large enough to handle any size frame, by 211 | virtue of the maximum possible part2_3_length. 212 | 213 | * Further developed the async API; arbitrary messages can now be passed to 214 | the subsidiary decoding process. 215 | 216 | * Streamlined timer.c and extended its interface. It now has support for 217 | video frame/field lengths, including output support for drop-frame 218 | encoding. 219 | 220 | * Replaced many constant integer preprocessor defines with enums. 221 | 222 | Version 0.11.4 (beta) 223 | 224 | * Fixed free format bitrate discovery. 225 | 226 | * Changed the timer implementation and extended its interface. 227 | 228 | * Integrated Nicolas Pitre's patch for pre-shifting at compile-time and 229 | for better multiply/accumulate code output. 230 | 231 | * Applied Simon Burge's patch to imdct_l_arm.S for a.out compatibility. 232 | 233 | * Added -mtune=strongarm for all ARM targets. 234 | 235 | Version 0.11.3 (beta) 236 | 237 | * Added new --enable-speed and --enable-accuracy options for `configure' 238 | to automatically select appropriate SSO/ASO options, et al. 239 | 240 | * Modified subband synthesis to use multiply/accumulate optimization (if 241 | available) for better speed and/or accuracy. 242 | 243 | * Incorporated Andre McCurdy's changes for further rounding optimizations 244 | in the rest of his code. 245 | 246 | Version 0.11.2 (beta) 247 | 248 | * Incorporated Nicolas Pitre's ARM assembly and parameterized scaling 249 | changes. 250 | 251 | * Incorporated Andre McCurdy's ARM assembly optimization (used only if 252 | --enable-aso is given to `configure' to enable architecture-specific 253 | optimizations.) 254 | 255 | * Reduced FPM_INTEL assembly to two instructions. 256 | 257 | * Fixed accuracy problems with certain FPM modes in synth.c. 258 | 259 | * Improved the accuracy of FPM_APPROX. 260 | 261 | * Improved the accuracy of SSO. 262 | 263 | * Improved sync discovery by checking for a sync word in the following 264 | frame. 265 | 266 | * Minor code clean-up. 267 | 268 | * Added experimental rules for generating a libmad.so shared library. 269 | 270 | Version 0.11.1 (beta) 271 | 272 | * Moved libmad code into a separate directory. 273 | 274 | * Changed SSO to be disabled by default, as output accuracy is deemed to 275 | be more important than speed in the general case. 276 | 277 | * Fixed a bug in Layer III sanity checking that could cause a crash on 278 | certain random data input. 279 | 280 | * Extended the Layer III requantization table from 8191 to 8206 as some 281 | encoders are known to use these values, even though ISO/IEC 11172-3 282 | suggests the maximum should be 8191. 283 | 284 | Version 0.11.0 (beta) 285 | 286 | * Implemented MPEG-2 extension to Lower Sampling Frequencies. 287 | 288 | * Improved Layer III performance by avoiding IMDCT calculation when all 289 | input samples are zero. 290 | 291 | * Significantly reduced size of Layer II tables. 292 | 293 | Version 0.10.3 (beta) 294 | 295 | * Improved SSO output quality. 296 | 297 | * Made portable to cygwin. 298 | 299 | * Localized memory references in III_huffdecode() for better performance. 300 | 301 | Version 0.10.2 (beta) 302 | 303 | * Rewrote Layer III long block 36-point IMDCT routine for better 304 | performance. 305 | 306 | * Improved subband synthesis fixed-point games somewhat. 307 | 308 | Version 0.10.1 (beta) 309 | 310 | * Added a subband synthesis optimization (SSO) which involves modifying 311 | the fixed-point multiplication method during windowing. This produces 312 | subtle differences in the output but improves performance greatly. 313 | 314 | * Added I_STEREO and MS_STEREO flags to frame struct. 315 | 316 | * Eliminated privately-used CRCFAILED flag. 317 | 318 | * Fixed a bug where Layer III decoding could crash on some badly-formatted 319 | (e.g. non-MPEG) bitstreams. 320 | 321 | * Miscellaneous code clean-up. 322 | 323 | Version 0.10.0 (beta) 324 | 325 | * Added SPARC fixed-point math support. 326 | 327 | * Revamped libmad API for better high- and low-level support. 328 | 329 | * Documented more of the code. 330 | 331 | * Changed sync semantics such that new stream buffers are assumed to be 332 | sync-aligned. 333 | 334 | * Changed Layer III to dynamically allocate static memory so as not to 335 | waste it (about 6.4K) when only decoding Layer I or Layer II. 336 | 337 | =============================================================================== 338 | 339 | -------------------------------------------------------------------------------- /src/src/ESP8266Audio/libmad/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libmad - MPEG audio decoder library 3 | * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $ 20 | */ 21 | 22 | #pragma GCC optimize ("O3") 23 | 24 | # include "config.h" 25 | 26 | # include "global.h" 27 | 28 | # include 29 | 30 | # ifdef HAVE_ASSERT_H 31 | # include 32 | # endif 33 | 34 | # include "timer.h" 35 | 36 | mad_timer_t const mad_timer_zero = { 0, 0 }; 37 | 38 | /* 39 | * NAME: timer->compare() 40 | * DESCRIPTION: indicate relative order of two timers 41 | */ 42 | int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) 43 | { 44 | signed long diff; 45 | 46 | diff = timer1.seconds - timer2.seconds; 47 | if (diff < 0) 48 | return -1; 49 | else if (diff > 0) 50 | return +1; 51 | 52 | diff = timer1.fraction - timer2.fraction; 53 | if (diff < 0) 54 | return -1; 55 | else if (diff > 0) 56 | return +1; 57 | 58 | return 0; 59 | } 60 | 61 | /* 62 | * NAME: timer->negate() 63 | * DESCRIPTION: invert the sign of a timer 64 | */ 65 | void mad_timer_negate(mad_timer_t *timer) 66 | { 67 | timer->seconds = -timer->seconds; 68 | 69 | if (timer->fraction) { 70 | timer->seconds -= 1; 71 | timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; 72 | } 73 | } 74 | 75 | /* 76 | * NAME: timer->abs() 77 | * DESCRIPTION: return the absolute value of a timer 78 | */ 79 | mad_timer_t mad_timer_abs(mad_timer_t timer) 80 | { 81 | if (timer.seconds < 0) 82 | mad_timer_negate(&timer); 83 | 84 | return timer; 85 | } 86 | 87 | /* 88 | * NAME: reduce_timer() 89 | * DESCRIPTION: carry timer fraction into seconds 90 | */ 91 | static 92 | void reduce_timer(mad_timer_t *timer) 93 | { 94 | timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION; 95 | timer->fraction %= MAD_TIMER_RESOLUTION; 96 | } 97 | 98 | /* 99 | * NAME: gcd() 100 | * DESCRIPTION: compute greatest common denominator 101 | */ 102 | static 103 | unsigned long gcd(unsigned long num1, unsigned long num2) 104 | { 105 | unsigned long tmp; 106 | 107 | while (num2) { 108 | tmp = num2; 109 | num2 = num1 % num2; 110 | num1 = tmp; 111 | } 112 | 113 | return num1; 114 | } 115 | 116 | /* 117 | * NAME: reduce_rational() 118 | * DESCRIPTION: convert rational expression to lowest terms 119 | */ 120 | static 121 | void reduce_rational(unsigned long *numer, unsigned long *denom) 122 | { 123 | unsigned long factor; 124 | 125 | factor = gcd(*numer, *denom); 126 | 127 | assert(factor != 0); 128 | 129 | *numer /= factor; 130 | *denom /= factor; 131 | } 132 | 133 | /* 134 | * NAME: scale_rational() 135 | * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing 136 | */ 137 | static 138 | unsigned long scale_rational(unsigned long numer, unsigned long denom, 139 | unsigned long scale) 140 | { 141 | reduce_rational(&numer, &denom); 142 | reduce_rational(&scale, &denom); 143 | 144 | assert(denom != 0); 145 | 146 | if (denom < scale) 147 | return numer * (scale / denom) + numer * (scale % denom) / denom; 148 | if (denom < numer) 149 | return scale * (numer / denom) + scale * (numer % denom) / denom; 150 | 151 | return numer * scale / denom; 152 | } 153 | 154 | /* 155 | * NAME: timer->set() 156 | * DESCRIPTION: set timer to specific (positive) value 157 | */ 158 | void mad_timer_set(mad_timer_t *timer, unsigned long seconds, 159 | unsigned long numer, unsigned long denom) 160 | { 161 | timer->seconds = seconds; 162 | if (numer >= denom && denom > 0) { 163 | timer->seconds += numer / denom; 164 | numer %= denom; 165 | } 166 | 167 | switch (denom) { 168 | case 0: 169 | case 1: 170 | timer->fraction = 0; 171 | break; 172 | 173 | case MAD_TIMER_RESOLUTION: 174 | timer->fraction = numer; 175 | break; 176 | 177 | case 1000: 178 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); 179 | break; 180 | 181 | case 8000: 182 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); 183 | break; 184 | 185 | case 11025: 186 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); 187 | break; 188 | 189 | case 12000: 190 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); 191 | break; 192 | 193 | case 16000: 194 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); 195 | break; 196 | 197 | case 22050: 198 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); 199 | break; 200 | 201 | case 24000: 202 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); 203 | break; 204 | 205 | case 32000: 206 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); 207 | break; 208 | 209 | case 44100: 210 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); 211 | break; 212 | 213 | case 48000: 214 | timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); 215 | break; 216 | 217 | default: 218 | timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); 219 | break; 220 | } 221 | 222 | if (timer->fraction >= MAD_TIMER_RESOLUTION) 223 | reduce_timer(timer); 224 | } 225 | 226 | /* 227 | * NAME: timer->add() 228 | * DESCRIPTION: add one timer to another 229 | */ 230 | void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) 231 | { 232 | timer->seconds += incr.seconds; 233 | timer->fraction += incr.fraction; 234 | 235 | if (timer->fraction >= MAD_TIMER_RESOLUTION) 236 | reduce_timer(timer); 237 | } 238 | 239 | /* 240 | * NAME: timer->multiply() 241 | * DESCRIPTION: multiply a timer by a scalar value 242 | */ 243 | void mad_timer_multiply(mad_timer_t *timer, signed long scalar) 244 | { 245 | mad_timer_t addend; 246 | unsigned long factor; 247 | 248 | factor = scalar; 249 | if (scalar < 0) { 250 | factor = -scalar; 251 | mad_timer_negate(timer); 252 | } 253 | 254 | addend = *timer; 255 | *timer = mad_timer_zero; 256 | 257 | while (factor) { 258 | if (factor & 1) 259 | mad_timer_add(timer, addend); 260 | 261 | mad_timer_add(&addend, addend); 262 | factor >>= 1; 263 | } 264 | } 265 | 266 | /* 267 | * NAME: timer->count() 268 | * DESCRIPTION: return timer value in selected units 269 | */ 270 | signed long mad_timer_count(mad_timer_t timer, enum mad_units units) 271 | { 272 | switch (units) { 273 | case MAD_UNITS_HOURS: 274 | return timer.seconds / 60 / 60; 275 | 276 | case MAD_UNITS_MINUTES: 277 | return timer.seconds / 60; 278 | 279 | case MAD_UNITS_SECONDS: 280 | return timer.seconds; 281 | 282 | case MAD_UNITS_DECISECONDS: 283 | case MAD_UNITS_CENTISECONDS: 284 | case MAD_UNITS_MILLISECONDS: 285 | 286 | case MAD_UNITS_8000_HZ: 287 | case MAD_UNITS_11025_HZ: 288 | case MAD_UNITS_12000_HZ: 289 | case MAD_UNITS_16000_HZ: 290 | case MAD_UNITS_22050_HZ: 291 | case MAD_UNITS_24000_HZ: 292 | case MAD_UNITS_32000_HZ: 293 | case MAD_UNITS_44100_HZ: 294 | case MAD_UNITS_48000_HZ: 295 | 296 | case MAD_UNITS_24_FPS: 297 | case MAD_UNITS_25_FPS: 298 | case MAD_UNITS_30_FPS: 299 | case MAD_UNITS_48_FPS: 300 | case MAD_UNITS_50_FPS: 301 | case MAD_UNITS_60_FPS: 302 | case MAD_UNITS_75_FPS: 303 | return timer.seconds * (signed long) units + 304 | (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, 305 | units); 306 | 307 | case MAD_UNITS_23_976_FPS: 308 | case MAD_UNITS_24_975_FPS: 309 | case MAD_UNITS_29_97_FPS: 310 | case MAD_UNITS_47_952_FPS: 311 | case MAD_UNITS_49_95_FPS: 312 | case MAD_UNITS_59_94_FPS: 313 | return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; 314 | } 315 | 316 | /* unsupported units */ 317 | return 0; 318 | } 319 | 320 | /* 321 | * NAME: timer->fraction() 322 | * DESCRIPTION: return fractional part of timer in arbitrary terms 323 | */ 324 | unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) 325 | { 326 | timer = mad_timer_abs(timer); 327 | 328 | switch (denom) { 329 | case 0: 330 | return timer.fraction ? 331 | MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1; 332 | 333 | case MAD_TIMER_RESOLUTION: 334 | return timer.fraction; 335 | 336 | default: 337 | return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); 338 | } 339 | } 340 | 341 | /* 342 | * NAME: timer->string() 343 | * DESCRIPTION: write a string representation of a timer using a template 344 | */ 345 | void mad_timer_string(mad_timer_t timer, 346 | char *dest, char const *format, enum mad_units units, 347 | enum mad_units fracunits, unsigned long subparts) 348 | { 349 | unsigned long hours, minutes, seconds, sub; 350 | unsigned int frac; 351 | 352 | timer = mad_timer_abs(timer); 353 | 354 | seconds = timer.seconds; 355 | frac = sub = 0; 356 | 357 | switch (fracunits) { 358 | case MAD_UNITS_HOURS: 359 | case MAD_UNITS_MINUTES: 360 | case MAD_UNITS_SECONDS: 361 | break; 362 | 363 | case MAD_UNITS_DECISECONDS: 364 | case MAD_UNITS_CENTISECONDS: 365 | case MAD_UNITS_MILLISECONDS: 366 | 367 | case MAD_UNITS_8000_HZ: 368 | case MAD_UNITS_11025_HZ: 369 | case MAD_UNITS_12000_HZ: 370 | case MAD_UNITS_16000_HZ: 371 | case MAD_UNITS_22050_HZ: 372 | case MAD_UNITS_24000_HZ: 373 | case MAD_UNITS_32000_HZ: 374 | case MAD_UNITS_44100_HZ: 375 | case MAD_UNITS_48000_HZ: 376 | 377 | case MAD_UNITS_24_FPS: 378 | case MAD_UNITS_25_FPS: 379 | case MAD_UNITS_30_FPS: 380 | case MAD_UNITS_48_FPS: 381 | case MAD_UNITS_50_FPS: 382 | case MAD_UNITS_60_FPS: 383 | case MAD_UNITS_75_FPS: 384 | { 385 | unsigned long denom; 386 | 387 | denom = MAD_TIMER_RESOLUTION / fracunits; 388 | 389 | frac = timer.fraction / denom; 390 | sub = scale_rational(timer.fraction % denom, denom, subparts); 391 | } 392 | break; 393 | 394 | case MAD_UNITS_23_976_FPS: 395 | case MAD_UNITS_24_975_FPS: 396 | case MAD_UNITS_29_97_FPS: 397 | case MAD_UNITS_47_952_FPS: 398 | case MAD_UNITS_49_95_FPS: 399 | case MAD_UNITS_59_94_FPS: 400 | /* drop-frame encoding */ 401 | /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ 402 | { 403 | unsigned long frame, cycle, d, m; 404 | 405 | frame = mad_timer_count(timer, fracunits); 406 | 407 | cycle = -fracunits * 60 * 10 - (10 - 1) * 2; 408 | 409 | d = frame / cycle; 410 | m = frame % cycle; 411 | frame += (10 - 1) * 2 * d; 412 | if (m > 2) 413 | frame += 2 * ((m - 2) / (cycle / 10)); 414 | 415 | frac = frame % -fracunits; 416 | seconds = frame / -fracunits; 417 | } 418 | break; 419 | } 420 | 421 | switch (units) { 422 | case MAD_UNITS_HOURS: 423 | minutes = seconds / 60; 424 | hours = minutes / 60; 425 | 426 | sprintf(dest, format, 427 | hours, 428 | (unsigned int) (minutes % 60), 429 | (unsigned int) (seconds % 60), 430 | frac, sub); 431 | break; 432 | 433 | case MAD_UNITS_MINUTES: 434 | minutes = seconds / 60; 435 | 436 | sprintf(dest, format, 437 | minutes, 438 | (unsigned int) (seconds % 60), 439 | frac, sub); 440 | break; 441 | 442 | case MAD_UNITS_SECONDS: 443 | sprintf(dest, format, 444 | seconds, 445 | frac, sub); 446 | break; 447 | 448 | case MAD_UNITS_23_976_FPS: 449 | case MAD_UNITS_24_975_FPS: 450 | case MAD_UNITS_29_97_FPS: 451 | case MAD_UNITS_47_952_FPS: 452 | case MAD_UNITS_49_95_FPS: 453 | case MAD_UNITS_59_94_FPS: 454 | if (fracunits < 0) { 455 | /* not yet implemented */ 456 | sub = 0; 457 | } 458 | 459 | /* fall through */ 460 | 461 | case MAD_UNITS_DECISECONDS: 462 | case MAD_UNITS_CENTISECONDS: 463 | case MAD_UNITS_MILLISECONDS: 464 | 465 | case MAD_UNITS_8000_HZ: 466 | case MAD_UNITS_11025_HZ: 467 | case MAD_UNITS_12000_HZ: 468 | case MAD_UNITS_16000_HZ: 469 | case MAD_UNITS_22050_HZ: 470 | case MAD_UNITS_24000_HZ: 471 | case MAD_UNITS_32000_HZ: 472 | case MAD_UNITS_44100_HZ: 473 | case MAD_UNITS_48000_HZ: 474 | 475 | case MAD_UNITS_24_FPS: 476 | case MAD_UNITS_25_FPS: 477 | case MAD_UNITS_30_FPS: 478 | case MAD_UNITS_48_FPS: 479 | case MAD_UNITS_50_FPS: 480 | case MAD_UNITS_60_FPS: 481 | case MAD_UNITS_75_FPS: 482 | sprintf(dest, format, mad_timer_count(timer, units), sub); 483 | break; 484 | } 485 | } 486 | --------------------------------------------------------------------------------