mirror of https://github.com/arendst/Tasmota.git
Merge pull request #12791 from s-hadinger/audio_wav
Berry support for WAV audio
This commit is contained in:
commit
9f0b67e60a
|
@ -11,6 +11,13 @@
|
||||||
extern int i2s_output_i2s_init(bvm *vm);
|
extern int i2s_output_i2s_init(bvm *vm);
|
||||||
extern int i2s_output_i2s_deinit(bvm *vm);
|
extern int i2s_output_i2s_deinit(bvm *vm);
|
||||||
|
|
||||||
|
extern int i2s_generator_wav_init(bvm *vm);
|
||||||
|
extern int i2s_generator_wav_deinit(bvm *vm);
|
||||||
|
extern int i2s_generator_wav_begin(bvm *vm);
|
||||||
|
extern int i2s_generator_wav_loop(bvm *vm);
|
||||||
|
extern int i2s_generator_wav_stop(bvm *vm);
|
||||||
|
extern int i2s_generator_wav_isrunning(bvm *vm);
|
||||||
|
|
||||||
extern int i2s_generator_mp3_init(bvm *vm);
|
extern int i2s_generator_mp3_init(bvm *vm);
|
||||||
extern int i2s_generator_mp3_deinit(bvm *vm);
|
extern int i2s_generator_mp3_deinit(bvm *vm);
|
||||||
extern int i2s_generator_mp3_begin(bvm *vm);
|
extern int i2s_generator_mp3_begin(bvm *vm);
|
||||||
|
@ -28,6 +35,7 @@ extern int i2s_file_source_fs_deinit(bvm *vm);
|
||||||
#include "../generate/be_fixed_be_class_audio_output.h"
|
#include "../generate/be_fixed_be_class_audio_output.h"
|
||||||
#include "../generate/be_fixed_be_class_audio_output_i2s.h"
|
#include "../generate/be_fixed_be_class_audio_output_i2s.h"
|
||||||
#include "../generate/be_fixed_be_class_audio_generator.h"
|
#include "../generate/be_fixed_be_class_audio_generator.h"
|
||||||
|
#include "../generate/be_fixed_be_class_audio_generator_wav.h"
|
||||||
#include "../generate/be_fixed_be_class_audio_generator_mp3.h"
|
#include "../generate/be_fixed_be_class_audio_generator_mp3.h"
|
||||||
#include "../generate/be_fixed_be_class_audio_file_source.h"
|
#include "../generate/be_fixed_be_class_audio_file_source.h"
|
||||||
#include "../generate/be_fixed_be_class_audio_file_source_fs.h"
|
#include "../generate/be_fixed_be_class_audio_file_source_fs.h"
|
||||||
|
@ -42,6 +50,10 @@ void be_load_driver_audio_lib(bvm *vm) {
|
||||||
be_setglobal(vm, "AudioOutputI2S");
|
be_setglobal(vm, "AudioOutputI2S");
|
||||||
be_pop(vm, 1);
|
be_pop(vm, 1);
|
||||||
|
|
||||||
|
be_pushntvclass(vm, &be_class_audio_generator_wav);
|
||||||
|
be_setglobal(vm, "AudioGeneratorWAV");
|
||||||
|
be_pop(vm, 1);
|
||||||
|
|
||||||
be_pushntvclass(vm, &be_class_audio_generator_mp3);
|
be_pushntvclass(vm, &be_class_audio_generator_mp3);
|
||||||
be_setglobal(vm, "AudioGeneratorMP3");
|
be_setglobal(vm, "AudioGeneratorMP3");
|
||||||
be_pop(vm, 1);
|
be_pop(vm, 1);
|
||||||
|
@ -73,6 +85,16 @@ class be_class_audio_output_i2s (scope: global, name: AudioOutputI2S, super: be_
|
||||||
close, func(i2s_output_i2s_deinit)
|
close, func(i2s_output_i2s_deinit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class be_class_audio_generator_wav (scope: global, name: AudioGeneratorWAV, super: be_class_audio_generator) {
|
||||||
|
init, func(i2s_generator_wav_init)
|
||||||
|
deinit, func(i2s_generator_wav_deinit)
|
||||||
|
close, func(i2s_generator_wav_deinit)
|
||||||
|
begin, func(i2s_generator_wav_begin)
|
||||||
|
loop, func(i2s_generator_wav_loop)
|
||||||
|
stop, func(i2s_generator_wav_stop)
|
||||||
|
isrunning, func(i2s_generator_wav_isrunning)
|
||||||
|
}
|
||||||
|
|
||||||
class be_class_audio_generator_mp3 (scope: global, name: AudioGeneratorMP3, super: be_class_audio_generator) {
|
class be_class_audio_generator_mp3 (scope: global, name: AudioGeneratorMP3, super: be_class_audio_generator) {
|
||||||
init, func(i2s_generator_mp3_init)
|
init, func(i2s_generator_mp3_init)
|
||||||
deinit, func(i2s_generator_mp3_deinit)
|
deinit, func(i2s_generator_mp3_deinit)
|
||||||
|
|
|
@ -230,6 +230,7 @@ extern const bcstring be_const_str_type;
|
||||||
extern const bcstring be_const_str__request_from;
|
extern const bcstring be_const_str__request_from;
|
||||||
extern const bcstring be_const_str___lower__;
|
extern const bcstring be_const_str___lower__;
|
||||||
extern const bcstring be_const_str_detect;
|
extern const bcstring be_const_str_detect;
|
||||||
|
extern const bcstring be_const_str_AudioGeneratorWAV;
|
||||||
extern const bcstring be_const_str_HPMA_TX;
|
extern const bcstring be_const_str_HPMA_TX;
|
||||||
extern const bcstring be_const_str_input;
|
extern const bcstring be_const_str_input;
|
||||||
extern const bcstring be_const_str_issubclass;
|
extern const bcstring be_const_str_issubclass;
|
||||||
|
|
|
@ -230,6 +230,7 @@ be_define_const_str(type, "type", 1361572173u, 0, 4, NULL);
|
||||||
be_define_const_str(_request_from, "_request_from", 3965148604u, 0, 13, NULL);
|
be_define_const_str(_request_from, "_request_from", 3965148604u, 0, 13, NULL);
|
||||||
be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_detect);
|
be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_detect);
|
||||||
be_define_const_str(detect, "detect", 8884370u, 0, 6, NULL);
|
be_define_const_str(detect, "detect", 8884370u, 0, 6, NULL);
|
||||||
|
be_define_const_str(AudioGeneratorWAV, "AudioGeneratorWAV", 2746509368u, 0, 17, NULL);
|
||||||
be_define_const_str(HPMA_TX, "HPMA_TX", 173233104u, 0, 7, &be_const_str_input);
|
be_define_const_str(HPMA_TX, "HPMA_TX", 173233104u, 0, 7, &be_const_str_input);
|
||||||
be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_issubclass);
|
be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_issubclass);
|
||||||
be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, NULL);
|
be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, NULL);
|
||||||
|
@ -765,7 +766,7 @@ static const bstring* const m_string_table[] = {
|
||||||
(const bstring *)&be_const_str___lower__,
|
(const bstring *)&be_const_str___lower__,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
(const bstring *)&be_const_str_AudioGeneratorWAV,
|
||||||
(const bstring *)&be_const_str_HPMA_TX,
|
(const bstring *)&be_const_str_HPMA_TX,
|
||||||
(const bstring *)&be_const_str_SYMBOL_PLAY,
|
(const bstring *)&be_const_str_SYMBOL_PLAY,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -971,6 +972,6 @@ static const bstring* const m_string_table[] = {
|
||||||
|
|
||||||
static const struct bconststrtab m_const_string_table = {
|
static const struct bconststrtab m_const_string_table = {
|
||||||
.size = 315,
|
.size = 315,
|
||||||
.count = 630,
|
.count = 631,
|
||||||
.table = m_string_table
|
.table = m_string_table
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
static be_define_const_map_slots(be_class_audio_generator_wav_map) {
|
||||||
|
{ be_const_key(close, -1), be_const_func(i2s_generator_wav_deinit) },
|
||||||
|
{ be_const_key(stop, -1), be_const_func(i2s_generator_wav_stop) },
|
||||||
|
{ be_const_key(loop, 0), be_const_func(i2s_generator_wav_loop) },
|
||||||
|
{ be_const_key(isrunning, 1), be_const_func(i2s_generator_wav_isrunning) },
|
||||||
|
{ be_const_key(begin, -1), be_const_func(i2s_generator_wav_begin) },
|
||||||
|
{ be_const_key(deinit, 6), be_const_func(i2s_generator_wav_deinit) },
|
||||||
|
{ be_const_key(init, -1), be_const_func(i2s_generator_wav_init) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static be_define_const_map(
|
||||||
|
be_class_audio_generator_wav_map,
|
||||||
|
7
|
||||||
|
);
|
||||||
|
|
||||||
|
BE_EXPORT_VARIABLE be_define_const_class(
|
||||||
|
be_class_audio_generator_wav,
|
||||||
|
0,
|
||||||
|
(bclass *)&be_class_audio_generator,
|
||||||
|
AudioGeneratorWAV
|
||||||
|
);
|
|
@ -372,7 +372,7 @@ static int m_fromstring(bvm *vm)
|
||||||
int argc = be_top(vm);
|
int argc = be_top(vm);
|
||||||
if (argc >= 2 && be_isstring(vm, 2)) {
|
if (argc >= 2 && be_isstring(vm, 2)) {
|
||||||
const char *s = be_tostring(vm, 2);
|
const char *s = be_tostring(vm, 2);
|
||||||
size_t len = strlen(s);
|
size_t len = be_strlen(vm, 2);
|
||||||
buf_impl * buf = bytes_check_data(vm, 0);
|
buf_impl * buf = bytes_check_data(vm, 0);
|
||||||
buf = bytes_resize(vm, buf, len); /* resize if needed */
|
buf = bytes_resize(vm, buf, len); /* resize if needed */
|
||||||
if (len > buf->size) { len = buf->size; } /* avoid overflow */
|
if (len > buf->size) { len = buf->size; } /* avoid overflow */
|
||||||
|
@ -753,6 +753,20 @@ BERRY_API const void *be_tobytes(bvm *vm, int rel_index, size_t *len)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BERRY_API bbool be_isbytes(bvm *vm, int rel_index)
|
||||||
|
{
|
||||||
|
bbool ret = bfalse;
|
||||||
|
int index = be_absindex(vm, rel_index);
|
||||||
|
if (be_isinstance(vm, index)) {
|
||||||
|
be_getbuiltin(vm, "bytes");
|
||||||
|
if (be_isderived(vm, index)) {
|
||||||
|
ret = btrue;
|
||||||
|
}
|
||||||
|
be_pop(vm, 1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper code to compile bytecode
|
/* Helper code to compile bytecode
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,17 @@
|
||||||
static int i_write(bvm *vm)
|
static int i_write(bvm *vm)
|
||||||
{
|
{
|
||||||
be_getmember(vm, 1, ".p");
|
be_getmember(vm, 1, ".p");
|
||||||
if(be_iscomptr(vm, -1) && be_isstring(vm, 2)) {
|
if(be_iscomptr(vm, -1) && (be_isstring(vm, 2) || be_isbytes(vm, 2))) {
|
||||||
void *fh = be_tocomptr(vm, -1);
|
void *fh = be_tocomptr(vm, -1);
|
||||||
const char *data = be_tostring(vm, 2);
|
size_t size = 0;
|
||||||
be_fwrite(fh, data, be_strlen(vm, 2));
|
const char *data = NULL;
|
||||||
|
if (be_isstring(vm, 2)) {
|
||||||
|
data = be_tostring(vm, 2);
|
||||||
|
size = be_strlen(vm, 2);
|
||||||
|
} else {
|
||||||
|
data = be_tobytes(vm, 2, &size);
|
||||||
|
}
|
||||||
|
be_fwrite(fh, data, size);
|
||||||
}
|
}
|
||||||
be_return_nil(vm);
|
be_return_nil(vm);
|
||||||
}
|
}
|
||||||
|
@ -52,6 +59,43 @@ static int i_read(bvm *vm)
|
||||||
be_return_nil(vm);
|
be_return_nil(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int i_readbytes(bvm *vm)
|
||||||
|
{
|
||||||
|
int argc = be_top(vm);
|
||||||
|
be_getmember(vm, 1, ".p");
|
||||||
|
if (be_iscomptr(vm, -1)) {
|
||||||
|
void *fh = be_tocomptr(vm, -1);
|
||||||
|
size_t size = readsize(vm, argc, fh);
|
||||||
|
if (size) {
|
||||||
|
/* avoid double allocation, using directly the internal buffer of bytes() */
|
||||||
|
be_getbuiltin(vm, "bytes");
|
||||||
|
be_pushint(vm, size);
|
||||||
|
be_call(vm, 1); /* call bytes() constructor with pre-sized buffer */
|
||||||
|
be_pop(vm, 1); /* bytes() instance is at top */
|
||||||
|
|
||||||
|
be_getmember(vm, -1, "resize");
|
||||||
|
be_pushvalue(vm, -2);
|
||||||
|
be_pushint(vm, size);
|
||||||
|
be_call(vm, 2); /* call b.resize(size) */
|
||||||
|
be_pop(vm, 3); /* bytes() instance is at top */
|
||||||
|
|
||||||
|
char *buffer = (char*) be_tobytes(vm, -1, NULL); /* we get the address of the internam buffer of size 'size' */
|
||||||
|
size = be_fread(fh, buffer, size);
|
||||||
|
|
||||||
|
/* resize if something went wrong */
|
||||||
|
be_getmember(vm, -1, "resize");
|
||||||
|
be_pushvalue(vm, -2);
|
||||||
|
be_pushint(vm, size);
|
||||||
|
be_call(vm, 2); /* call b.resize(size) */
|
||||||
|
be_pop(vm, 3); /* bytes() instance is at top */
|
||||||
|
} else {
|
||||||
|
be_pushbytes(vm, NULL, 0);
|
||||||
|
}
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
be_return_nil(vm);
|
||||||
|
}
|
||||||
|
|
||||||
static int i_readline(bvm *vm)
|
static int i_readline(bvm *vm)
|
||||||
{
|
{
|
||||||
be_getmember(vm, 1, ".p");
|
be_getmember(vm, 1, ".p");
|
||||||
|
@ -144,6 +188,7 @@ int be_nfunc_open(bvm *vm)
|
||||||
{ ".p", NULL },
|
{ ".p", NULL },
|
||||||
{ "write", i_write },
|
{ "write", i_write },
|
||||||
{ "read", i_read },
|
{ "read", i_read },
|
||||||
|
{ "readbytes", i_readbytes },
|
||||||
{ "readline", i_readline },
|
{ "readline", i_readline },
|
||||||
{ "seek", i_seek },
|
{ "seek", i_seek },
|
||||||
{ "tell", i_tell },
|
{ "tell", i_tell },
|
||||||
|
|
|
@ -444,6 +444,7 @@ BERRY_API bbool be_ismap(bvm *vm, int index);
|
||||||
BERRY_API bbool be_iscomptr(bvm *vm, int index);
|
BERRY_API bbool be_iscomptr(bvm *vm, int index);
|
||||||
BERRY_API bbool be_iscomobj(bvm *vm, int index);
|
BERRY_API bbool be_iscomobj(bvm *vm, int index);
|
||||||
BERRY_API bbool be_isderived(bvm *vm, int index);
|
BERRY_API bbool be_isderived(bvm *vm, int index);
|
||||||
|
BERRY_API bbool be_isbytes(bvm *vm, int index);
|
||||||
|
|
||||||
BERRY_API bint be_toint(bvm *vm, int index);
|
BERRY_API bint be_toint(bvm *vm, int index);
|
||||||
BERRY_API breal be_toreal(bvm *vm, int index);
|
BERRY_API breal be_toreal(bvm *vm, int index);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
// #include "AudioFileSourceSPIFFS.h"
|
// #include "AudioFileSourceSPIFFS.h"
|
||||||
// #include "AudioFileSourceID3.h"
|
// #include "AudioFileSourceID3.h"
|
||||||
#include "AudioOutputI2S.h"
|
#include "AudioOutputI2S.h"
|
||||||
|
#include "AudioGeneratorWAV.h"
|
||||||
#include "AudioGeneratorMP3.h"
|
#include "AudioGeneratorMP3.h"
|
||||||
#include "AudioFileSourceFS.h"
|
#include "AudioFileSourceFS.h"
|
||||||
|
|
||||||
|
@ -83,6 +84,73 @@ extern "C" {
|
||||||
be_return_nil(vm);
|
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()
|
// AudioGeneratorMP3()
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue