Merge pull request #12791 from s-hadinger/audio_wav

Berry support for WAV audio
This commit is contained in:
s-hadinger 2021-07-30 13:25:24 +02:00 committed by GitHub
commit 9f0b67e60a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 181 additions and 6 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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
}; };

View File

@ -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
);

View File

@ -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

View File

@ -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 },

View File

@ -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);

View File

@ -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()
// //