mirror of https://github.com/arendst/Tasmota.git
266 lines
7.1 KiB
C++
266 lines
7.1 KiB
C++
/*
|
|
xdrv_52_3_berry_audio.ino - Berry scripting language, support for I2S audio
|
|
|
|
Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#ifdef USE_BERRY
|
|
|
|
#ifdef USE_I2S_AUDIO_BERRY
|
|
|
|
// #include "AudioFileSourceSPIFFS.h"
|
|
// #include "AudioFileSourceID3.h"
|
|
#include "AudioOutputI2S.h"
|
|
#include "AudioGeneratorWAV.h"
|
|
#include "AudioGeneratorMP3.h"
|
|
#include "AudioFileSourceFS.h"
|
|
|
|
#include <berry.h>
|
|
|
|
|
|
/*********************************************************************************************\
|
|
* AudioOutput class
|
|
*
|
|
\*********************************************************************************************/
|
|
extern "C" {
|
|
|
|
//
|
|
// AudioOutputI2S(bclkPin: int, wclkPin: int, doutPin: int[, port:int, dmabuf:int, mode: int])
|
|
//
|
|
int i2s_output_i2s_init(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
if (argc > 3) {
|
|
int bclkPin = be_toint(vm, 2);
|
|
int wclkPin = be_toint(vm, 3);
|
|
int doutPin = be_toint(vm, 4);
|
|
int port = 0;
|
|
if (argc > 4) {
|
|
port = be_toint(vm, 5);
|
|
}
|
|
int dma_buf_count = 8; // number of dma buffers of 64 bytes
|
|
if (argc > 5) {
|
|
dma_buf_count = be_toint(vm, 6);
|
|
}
|
|
int mode = 0; // EXTERNAL_I2S
|
|
if (argc > 6) {
|
|
mode = be_toint(vm, 7);
|
|
}
|
|
// AudioOutputI2S(int port=0, int output_mode=EXTERNAL_I2S, int dma_buf_count = 8, int use_apll=APLL_DISABLE);
|
|
AudioOutputI2S * audio = new AudioOutputI2S(port, mode, dma_buf_count);
|
|
if (0 == mode) {
|
|
audio->SetPinout(bclkPin, wclkPin, doutPin); // return value has no useful information for us
|
|
}
|
|
be_pushcomptr(vm, (void*) audio);
|
|
be_setmember(vm, 1, ".p");
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
be_raise(vm, kTypeError, nullptr);
|
|
}
|
|
|
|
int i2s_output_i2s_deinit(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
be_getmember(vm, 1, ".p");
|
|
AudioOutputI2S * audio = (AudioOutputI2S *) be_tocomptr(vm, -1);
|
|
if (audio) {
|
|
delete audio;
|
|
// clear
|
|
be_pushcomptr(vm, (void*) NULL);
|
|
be_setmember(vm, 1, ".p");
|
|
}
|
|
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
int i2s_output_i2s_stop(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
be_getmember(vm, 1, ".p");
|
|
AudioOutputI2S * audio = (AudioOutputI2S *) be_tocomptr(vm, -1);
|
|
if (audio) {
|
|
audio->stop();
|
|
}
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
//
|
|
// AudioGeneratorWAV()
|
|
//
|
|
int i2s_generator_wav_init(bvm *vm) {
|
|
AudioGeneratorWAV * wav = new AudioGeneratorWAV();
|
|
be_pushcomptr(vm, (void*) wav);
|
|
be_setmember(vm, 1, ".p");
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
AudioGeneratorWAV * i2s_generator_wav_get(bvm *vm) {
|
|
be_getmember(vm, 1, ".p");
|
|
AudioGeneratorWAV * wav = (AudioGeneratorWAV *) be_tocomptr(vm, -1);
|
|
return wav;
|
|
}
|
|
|
|
int i2s_generator_wav_deinit(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
AudioGeneratorWAV * wav = i2s_generator_wav_get(vm);
|
|
if (wav) {
|
|
delete wav;
|
|
// clear
|
|
be_pushcomptr(vm, (void*) NULL);
|
|
be_setmember(vm, 1, ".p");
|
|
}
|
|
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
int i2s_generator_wav_begin(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
if (argc > 2) {
|
|
AudioGeneratorWAV * wav = i2s_generator_wav_get(vm);
|
|
be_getmember(vm, 2, ".p");
|
|
AudioFileSource * source = (AudioFileSource*) be_tocomptr(vm, -1);
|
|
be_getmember(vm, 3, ".p");
|
|
AudioOutput * output = (AudioOutput*) be_tocomptr(vm, -1);
|
|
be_pop(vm, 2);
|
|
|
|
bool ret = wav->begin(source, output);
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
int i2s_generator_wav_loop(bvm *vm) {
|
|
AudioGeneratorWAV * wav = i2s_generator_wav_get(vm);
|
|
bool ret = wav->loop();
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
|
|
int i2s_generator_wav_stop(bvm *vm) {
|
|
AudioGeneratorWAV * wav = i2s_generator_wav_get(vm);
|
|
bool ret = wav->stop();
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
|
|
int i2s_generator_wav_isrunning(bvm *vm) {
|
|
AudioGeneratorWAV * wav = i2s_generator_wav_get(vm);
|
|
bool ret = wav->isRunning();
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
|
|
//
|
|
// AudioGeneratorMP3()
|
|
//
|
|
int i2s_generator_mp3_init(bvm *vm) {
|
|
AudioGeneratorMP3 * mp3 = new AudioGeneratorMP3();
|
|
be_pushcomptr(vm, (void*) mp3);
|
|
be_setmember(vm, 1, ".p");
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
AudioGeneratorMP3 * i2s_generator_mp3_get(bvm *vm) {
|
|
be_getmember(vm, 1, ".p");
|
|
AudioGeneratorMP3 * mp3 = (AudioGeneratorMP3 *) be_tocomptr(vm, -1);
|
|
return mp3;
|
|
}
|
|
|
|
int i2s_generator_mp3_deinit(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
AudioGeneratorMP3 * mp3 = i2s_generator_mp3_get(vm);
|
|
if (mp3) {
|
|
delete mp3;
|
|
// clear
|
|
be_pushcomptr(vm, (void*) NULL);
|
|
be_setmember(vm, 1, ".p");
|
|
}
|
|
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
int i2s_generator_mp3_begin(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
if (argc > 2) {
|
|
AudioGeneratorMP3 * mp3 = i2s_generator_mp3_get(vm);
|
|
be_getmember(vm, 2, ".p");
|
|
AudioFileSource * source = (AudioFileSource*) be_tocomptr(vm, -1);
|
|
be_getmember(vm, 3, ".p");
|
|
AudioOutput * output = (AudioOutput*) be_tocomptr(vm, -1);
|
|
be_pop(vm, 2);
|
|
|
|
bool ret = mp3->begin(source, output);
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
be_return_nil(vm);
|
|
}
|
|
|
|
int i2s_generator_mp3_loop(bvm *vm) {
|
|
AudioGeneratorMP3 * mp3 = i2s_generator_mp3_get(vm);
|
|
bool ret = mp3->loop();
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
|
|
int i2s_generator_mp3_stop(bvm *vm) {
|
|
AudioGeneratorMP3 * mp3 = i2s_generator_mp3_get(vm);
|
|
bool ret = mp3->stop();
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
|
|
int i2s_generator_mp3_isrunning(bvm *vm) {
|
|
AudioGeneratorMP3 * mp3 = i2s_generator_mp3_get(vm);
|
|
bool ret = mp3->isRunning();
|
|
be_pushbool(vm, ret);
|
|
be_return(vm);
|
|
}
|
|
|
|
// File Source FS
|
|
//
|
|
#ifdef USE_UFILESYS
|
|
int i2s_file_source_fs_init(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
if (argc > 1 && be_isstring(vm, 2)) {
|
|
const char * file_name = be_tostring(vm, 2);
|
|
AudioFileSourceFS * file_source = new AudioFileSourceFS(*ufsp, file_name);
|
|
be_pushcomptr(vm, (void*) file_source);
|
|
be_setmember(vm, 1, ".p");
|
|
be_return_nil(vm);
|
|
}
|
|
be_raise(vm, kTypeError, nullptr);
|
|
}
|
|
|
|
int i2s_file_source_fs_deinit(bvm *vm) {
|
|
int argc = be_top(vm);
|
|
be_getmember(vm, 1, ".p");
|
|
AudioFileSourceFS * file_source = (AudioFileSourceFS *) be_tocomptr(vm, -1);
|
|
if (file_source) {
|
|
delete file_source;
|
|
// clear
|
|
be_pushcomptr(vm, (void*) NULL);
|
|
be_setmember(vm, 1, ".p");
|
|
}
|
|
|
|
be_return_nil(vm);
|
|
}
|
|
#endif // USE_UFILESYS
|
|
}
|
|
|
|
#endif // USE_I2S_AUDIO_BERRY
|
|
#endif // USE_BERRY
|