Berry specific moved to berry_tasmota

This commit is contained in:
Stephan Hadinger 2022-01-05 09:50:38 +01:00
parent bfdf34813f
commit 4406eb9f3b
81 changed files with 1441 additions and 1104 deletions

View File

@ -1,113 +0,0 @@
/********************************************************************
* Tasmota I2S audio classes
*
*
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_I2S
#ifdef USE_I2S_AUDIO_BERRY
extern int i2s_output_i2s_init(bvm *vm);
extern int i2s_output_i2s_deinit(bvm *vm);
extern int i2s_output_i2s_stop(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_deinit(bvm *vm);
extern int i2s_generator_mp3_begin(bvm *vm);
extern int i2s_generator_mp3_loop(bvm *vm);
extern int i2s_generator_mp3_stop(bvm *vm);
extern int i2s_generator_mp3_isrunning(bvm *vm);
#ifdef USE_UFILESYS
extern int i2s_file_source_fs_init(bvm *vm);
extern int i2s_file_source_fs_deinit(bvm *vm);
#endif // USE_UFILESYS
#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_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_file_source.h"
#include "../generate/be_fixed_be_class_audio_file_source_fs.h"
void be_load_driver_audio_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_audio_output);
be_setglobal(vm, "AudioOutput");
be_pop(vm, 1);
be_pushntvclass(vm, &be_class_audio_output_i2s);
be_setglobal(vm, "AudioOutputI2S");
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_setglobal(vm, "AudioGeneratorMP3");
be_pop(vm, 1);
#ifdef USE_UFILESYS
be_pushntvclass(vm, &be_class_audio_file_source_fs);
be_setglobal(vm, "AudioFileSourceFS");
be_pop(vm, 1);
#endif // USE_UFILESYS
}
/* @const_object_info_begin
class be_class_audio_output (scope: global, name: AudioOutput) {
.p, var
}
class be_class_audio_generator (scope: global, name: AudioGenerator) {
.p, var
}
class be_class_audio_file_source (scope: global, name: AudioFileSource) {
.p, var
}
class be_class_audio_output_i2s (scope: global, name: AudioOutputI2S, super: be_class_audio_output) {
init, func(i2s_output_i2s_init)
deinit, func(i2s_output_i2s_deinit)
stop, func(i2s_output_i2s_stop)
}
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)
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) {
init, func(i2s_generator_mp3_init)
deinit, func(i2s_generator_mp3_deinit)
begin, func(i2s_generator_mp3_begin)
loop, func(i2s_generator_mp3_loop)
stop, func(i2s_generator_mp3_stop)
isrunning, func(i2s_generator_mp3_isrunning)
}
class be_class_audio_file_source_fs (scope: global, name: AudioFileSourceFS, super: be_class_audio_file_source) {
init, func(i2s_file_source_fs_init)
deinit, func(i2s_file_source_fs_deinit)
}
@const_object_info_end */
#endif // USE_I2S_AUDIO_BERRY
#endif // USE_I2S

View File

@ -159,6 +159,7 @@ extern void be_load_ctypes_energy_definitions_lib(bvm *vm);
#ifdef USE_I2S_AUDIO_BERRY
extern void be_load_driver_audio_lib(bvm *vm);
extern void be_load_driver_audio_opus_decoder(bvm *vm);
#endif
#ifdef USE_LVGL
@ -214,6 +215,7 @@ BERRY_API void be_load_custom_libs(bvm *vm)
#endif // USE_WS2812
#ifdef USE_I2S_AUDIO_BERRY
be_load_driver_audio_lib(vm);
be_load_driver_audio_opus_decoder(vm);
#endif
#ifdef USE_LVGL
// LVGL

View File

@ -1,2 +1,2 @@
#!/bin/bash
python3 tools/pycoc/main.py -o generate src default ../berry_mapping/src ../../libesp32_lvgl/lv_berry/src ../../libesp32_lvgl/lv_berry/generate -c default/berry_conf.h
python3 tools/pycoc/main.py -o generate src default ../berry_tasmota/src ../berry_mapping/src ../../libesp32_lvgl/lv_berry/src ../../libesp32_lvgl/lv_berry/generate -c default/berry_conf.h

View File

@ -51,6 +51,7 @@ extern const bcstring be_const_str_MD5;
extern const bcstring be_const_str_None;
extern const bcstring be_const_str_OPTION_A;
extern const bcstring be_const_str_OneWire;
extern const bcstring be_const_str_OpusDecoder;
extern const bcstring be_const_str_PART_MAIN;
extern const bcstring be_const_str_POST;
extern const bcstring be_const_str_Parameter_X20error;
@ -281,6 +282,9 @@ extern const bcstring be_const_str_connect;
extern const bcstring be_const_str_connected;
extern const bcstring be_const_str_connection_error;
extern const bcstring be_const_str_constructor_cb;
extern const bcstring be_const_str_consume_mono;
extern const bcstring be_const_str_consume_silence;
extern const bcstring be_const_str_consume_stereo;
extern const bcstring be_const_str_contains;
extern const bcstring be_const_str_content_button;
extern const bcstring be_const_str_content_flush;
@ -305,6 +309,7 @@ extern const bcstring be_const_str_ctypes_bytes_dyn;
extern const bcstring be_const_str_dac_voltage;
extern const bcstring be_const_str_day;
extern const bcstring be_const_str_debug;
extern const bcstring be_const_str_decode;
extern const bcstring be_const_str_decompress;
extern const bcstring be_const_str_decrypt;
extern const bcstring be_const_str_def;
@ -628,11 +633,14 @@ extern const bcstring be_const_str_serial;
extern const bcstring be_const_str_set;
extern const bcstring be_const_str_set_alternate;
extern const bcstring be_const_str_set_auth;
extern const bcstring be_const_str_set_bits_per_sample;
extern const bcstring be_const_str_set_bri;
extern const bcstring be_const_str_set_channels;
extern const bcstring be_const_str_set_chg_current;
extern const bcstring be_const_str_set_dc_voltage;
extern const bcstring be_const_str_set_dcdc_enable;
extern const bcstring be_const_str_set_first_time;
extern const bcstring be_const_str_set_gain;
extern const bcstring be_const_str_set_height;
extern const bcstring be_const_str_set_ldo_enable;
extern const bcstring be_const_str_set_ldo_voltage;
@ -641,6 +649,7 @@ extern const bcstring be_const_str_set_matrix_pixel_color;
extern const bcstring be_const_str_set_percentage;
extern const bcstring be_const_str_set_pixel_color;
extern const bcstring be_const_str_set_power;
extern const bcstring be_const_str_set_rate;
extern const bcstring be_const_str_set_style_bg_color;
extern const bcstring be_const_str_set_style_line_color;
extern const bcstring be_const_str_set_style_pad_right;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_audio_opus_decoder_map) {
{ be_const_key(deinit, -1), be_const_func(be_audio_opus_decoder_deinit) },
{ be_const_key(decode, 2), be_const_func(be_audio_opus_decoder_decode) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(init, 1), be_const_func(be_audio_opus_decoder_init) },
};
static be_define_const_map(
be_class_audio_opus_decoder_map,
4
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_audio_opus_decoder,
1,
NULL,
OpusDecoder
);

View File

@ -1,12 +1,23 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_audio_output_map) {
{ be_const_key(set_bits_per_sample, -1), be_const_func(be_audio_output_set_bits_per_sample) },
{ be_const_key(flush, -1), be_const_func(be_audio_output_flush) },
{ be_const_key(consume_stereo, -1), be_const_func(be_audio_output_consume_stereo) },
{ be_const_key(init, -1), be_const_func(be_audio_output_init) },
{ be_const_key(consume_mono, -1), be_const_func(be_audio_output_consume_mono) },
{ be_const_key(stop, -1), be_const_func(be_audio_output_stop) },
{ be_const_key(begin, -1), be_const_func(be_audio_output_begin) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(set_channels, -1), be_const_func(be_audio_output_set_channels) },
{ be_const_key(consume_silence, 4), be_const_func(be_audio_output_consume_silence) },
{ be_const_key(set_rate, 2), be_const_func(be_audio_output_set_rate) },
{ be_const_key(set_gain, 0), be_const_func(be_audio_output_set_gain) },
};
static be_define_const_map(
be_class_audio_output_map,
1
12
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -17,11 +17,13 @@
"frameworks": "arduino",
"platforms": "espressif32",
"build": {
"includeDir": "generate",
"srcFilter": [
"+<*.c>",
"+<../default/*.c>",
"+<../default/*.cpp>",
"+<../default/*.hpp>",
"+<../generate/*.h>",
"+<*.cpp>",
"+<*.h>"
],

View File

@ -138,6 +138,7 @@ int be_find_global_or_module_member(bvm *vm, const char * name) {
* 'i' be_int
* 'b' be_bool
* 's' be_str
* '&' bytes() object, pointer to buffer returned, and size passed with an additional (size_t*) argument
*
* - arg_type: optionally check the types of input arguments, or throw an error
* string of argument types, '[' indicates that the following parameters are optional
@ -145,8 +146,10 @@ int be_find_global_or_module_member(bvm *vm, const char * name) {
* 'i' be_int
* 'b' be_bool
* 's' be_string
* 'f' be_real (float)
* 'c' C callback
* '-' ignore and don't send to C function
* '-': skip argument and ignore
* '~': send the length of the previous bytes() buffer (or raise an exception if no length known)
* 'lv_obj' be_instance of type or subtype
* '^lv_event_cb' callback of a named class - will call `_lvgl.gen_cb(arg_type, closure, self)` and expects a callback address in return
*
@ -276,12 +279,15 @@ intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *buf
// - '.': any argument (no check)
// - '-': skip argument and ignore
// - '~': send the length of the previous bytes() buffer (or raise an exception if no length known)
// - if return type is '&' (bytes), an implicit additional parameter is passed as (size_t*) to return the length in bytes
//
// - a class name surroungded by parenthesis
// - '(lv_button)' -> lv_button class or derived
// - '[lv_event_cb]' -> callback type, still prefixed with '^' to mark that it is cb
//
void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]) {
// Returns the number of parameters sent to the function
//
int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]) {
bbool arg_type_check = (arg_type != NULL); // is type checking activated
int32_t arg_idx = 0; // position in arg_type string
bbool arg_optional = bfalse; // are remaining types optional?
@ -289,14 +295,17 @@ void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type,
uint32_t p_idx = 0; // index in p[], is incremented with each parameter except '-'
int32_t buf_len = -1; // stores the length of a bytes() buffer to be used as '~' attribute
// special case when no parameters are passed but all are optional
if (NULL != arg_type && arg_type[arg_idx] == '[') {
arg_optional = btrue;
arg_idx++;
}
for (uint32_t i = 0; i < argc; i++) {
type_short_name[0] = 0; // clear string
// extract individual type
if (NULL != arg_type) {
if (arg_type[arg_idx] == '[' || arg_type[arg_idx] == ']') { // '[' is a marker that following parameters are optional and default to NULL
arg_optional = btrue;
arg_idx++;
}
switch (arg_type[arg_idx]) {
case '-':
arg_idx++;
@ -333,6 +342,10 @@ void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type,
arg_type = NULL; // stop iterations
break;
}
if (arg_type[arg_idx] == '[' || arg_type[arg_idx] == ']') { // '[' is a marker that following parameters are optional and default to NULL
arg_optional = btrue;
arg_idx++;
}
}
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : "<null>");
p[p_idx] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : NULL, &buf_len);
@ -353,6 +366,7 @@ void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type,
if (!arg_optional && arg_type != NULL && arg_type[arg_idx] != 0) {
be_raisef(vm, "value_error", "Missing arguments, remaining type '%s'", &arg_type[arg_idx]);
}
return p_idx;
}
//
@ -420,8 +434,12 @@ int be_call_c_func(bvm *vm, void * func, const char * return_type, const char *
}
}
fn_any_callable f = (fn_any_callable) func;
be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
fn_any_callable f = (fn_any_callable) func; // when returning a bytes buffer, this holds the length of the buffer, while the return value of the function is `void*`
size_t return_len = 0;
int c_args = be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
if (return_type != NULL && return_type[0] == '&') {
if (c_args < 8) { p[c_args] = (intptr_t) &return_len; }
}
intptr_t ret = 0;
if (f) ret = (*f)(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
// berry_log_C("be_call_c_func '%s' -> '%s': (%i,%i,%i,%i,%i,%i) -> %i", return_type, arg_type, p[0], p[1], p[2], p[3], p[4], p[5], ret);
@ -438,7 +456,7 @@ int be_call_c_func(bvm *vm, void * func, const char * return_type, const char *
case 'i': be_pushint(vm, ret); break;
case 'b': be_pushbool(vm, ret); break;
case 's': be_pushstring(vm, (const char*) ret); break;
case 'c': be_pushint(vm, ret); break; // TODO missing 'c' general callback type
case '&': be_pushbytes(vm, (void*) ret, return_len); break;
default: be_raise(vm, "internal_error", "Unsupported return type"); break;
}
be_return(vm);

View File

@ -57,7 +57,7 @@ extern int be_find_global_or_module_member(bvm *vm, const char * cl_name);
extern bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len);
extern intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *len);
extern void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]);;
extern int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]);
extern int be_call_c_func(bvm *vm, void * func, const char * return_type, const char * arg_type);
#ifdef __cplusplus

View File

@ -0,0 +1,17 @@
{
"name": "Berry Tasmota mapping",
"version": "1.0",
"description": "Mapping of Tasmota features to Berry",
"license": "MIT",
"homepage": "https://github.com/arendst/Tasmota",
"frameworks": "arduino",
"platforms": "espressif32",
"authors":
{
"name": "Stephan Hadinger",
"maintainer": true
},
"build": {
"flags": [ "-I$PROJECT_DIR/include", "-includetasmota_options.h" ]
}
}

View File

@ -0,0 +1,88 @@
/********************************************************************
* Tasmota I2S audio classes
*
*
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_I2S
#ifdef USE_I2S_AUDIO_BERRY
#include "libopus/opus.h"
#include "be_mapping.h"
// Tasmota Logging
extern void tasmota_log_C(uint32_t loglevel, const char * berry_buf, ...);
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE};
// init(freq:int, channels:int)
void *be_audio_opus_decoder_init_ntv(int freq, int channels) {
if (freq <= 0) { freq = 16000; }
if (channels <= 0) { channels = 1; }
int opus_size = opus_decoder_get_size(channels); // get size for n channel
tasmota_log_C(LOG_LEVEL_DEBUG, "AUD: allocated %i bytes for Opus decoder", opus_size);
void * buf = BE_EXPLICIT_MALLOC(opus_size);
if (!buf) { berry_log_C("OPUS: out of memory"); }
int err = opus_decoder_init((OpusDecoder*)buf, freq, channels);
if (err) { berry_log_C("OPUS: opus_encoder_init error=%i", err); }
return buf;
}
int32_t be_audio_opus_decoder_init(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_opus_decoder_init_ntv, "+.p", "i[i]");
}
// deinit()
void *be_audio_opus_decoder_deinit_ntv(OpusDecoder* buf) {
if (buf) BE_EXPLICIT_FREE(buf);
return NULL;
}
int32_t be_audio_opus_decoder_deinit(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_opus_decoder_deinit_ntv, "", ".");
}
// decode(payload:bytes) -> pcm:bytes()
int32_t be_audio_opus_decoder_decode(struct bvm *vm) {
int32_t argc = be_top(vm);
be_call_c_func(vm, NULL, NULL, ".(bytes)");
OpusDecoder* st = (OpusDecoder*) be_convert_single_elt(vm, 1, NULL, NULL); // get value of '.p'
size_t frames_len;
const uint8_t * opus_frame = be_tobytes(vm, 2, &frames_len);
int samples = opus_decoder_get_nb_samples(st, opus_frame, frames_len);
// tasmota_log_C(LOG_LEVEL_DEBUG, "AUD: frame contains %i samples", samples);
// allocate a buffer for the content
void * pcm = be_pushbytes(vm, NULL, samples * 2);
int ret = opus_decode(st, opus_frame, frames_len, pcm, samples, 0);
if (ret != samples) { be_raisef(vm, "internal_error", "wrong number of frames %i (supposed to be %i", ret, samples); }
be_return(vm);
}
#include "be_fixed_be_class_audio_opus_decoder.h"
void be_load_driver_audio_opus_decoder(bvm *vm) {
be_pushntvclass(vm, &be_class_audio_opus_decoder);
be_setglobal(vm, "OpusDecoder");
be_pop(vm, 1);
}
/* @const_object_info_begin
class be_class_audio_opus_decoder (scope: global, name: OpusDecoder) {
.p, var
init, func(be_audio_opus_decoder_init)
deinit, func(be_audio_opus_decoder_deinit)
decode, func(be_audio_opus_decoder_decode)
}
@const_object_info_end */
#endif // USE_I2S_AUDIO_BERRY
#endif // USE_I2S

View File

@ -17,8 +17,8 @@ extern int m_aes_gcm_tag(bvm *vm);
extern int m_ec_c25519_pubkey(bvm *vm);
extern int m_ec_c25519_sharedkey(bvm *vm);
#include "../generate/be_fixed_be_class_aes_gcm.h"
#include "../generate/be_fixed_be_class_ec_c25519.h"
#include "be_fixed_be_class_aes_gcm.h"
#include "be_fixed_be_class_ec_c25519.h"
void be_load_crypto_lib(bvm *vm) {
// insert the class GCM in module AES

View File

@ -462,8 +462,8 @@ int be_ctypes_dyn_init(bvm *vm) {
BE_EXPORT_VARIABLE extern const bclass be_class_bytes;
#include "../generate/be_fixed_be_class_ctypes.h"
#include "../generate/be_fixed_be_class_ctypes_dyn.h"
#include "be_fixed_be_class_ctypes.h"
#include "be_fixed_be_class_ctypes_dyn.h"
void be_load_ctypes_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_ctypes);

View File

@ -18,4 +18,4 @@ module flash (scope: global) {
erase, func(p_flash_erase)
}
@const_object_info_end */
#include "../generate/be_fixed_flash.h"
#include "be_fixed_flash.h"

View File

@ -31,4 +31,4 @@ module gpio (scope: global) {
pin, func(gp_pin)
}
@const_object_info_end */
#include "../generate/be_fixed_gpio.h"
#include "be_fixed_gpio.h"

View File

@ -0,0 +1,245 @@
/********************************************************************
* Tasmota I2S audio classes
*
*
*******************************************************************/
#include "be_constobj.h"
#ifdef USE_I2S
#ifdef USE_I2S_AUDIO_BERRY
#include "be_mapping.h"
#include "AudioOutput.h"
extern "C" void berry_log_C(const char * berry_buf, ...);
extern "C" {
extern int i2s_output_i2s_init(bvm *vm);
extern int i2s_output_i2s_deinit(bvm *vm);
extern int i2s_output_i2s_stop(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_deinit(bvm *vm);
extern int i2s_generator_mp3_begin(bvm *vm);
extern int i2s_generator_mp3_loop(bvm *vm);
extern int i2s_generator_mp3_stop(bvm *vm);
extern int i2s_generator_mp3_isrunning(bvm *vm);
#ifdef USE_UFILESYS
extern int i2s_file_source_fs_init(bvm *vm);
extern int i2s_file_source_fs_deinit(bvm *vm);
#endif // USE_UFILESYS
}
// AudioOutput.set_rate(rate_hz:int) -> bool
AudioOutput* be_audio_output_init_ntv(void) {
return new AudioOutput();
}
int32_t be_audio_output_init(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_init_ntv, "+.p", "");
}
// AudioOutput.set_rate(rate_hz:int) -> bool
int be_audio_output_set_rate_ntv(AudioOutput* out, int hz) {
return out->SetRate(hz);
}
int32_t be_audio_output_set_rate(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_set_rate_ntv, "b", ".i");
}
// AudioOutput.set_bits_per_sample(bits_per_sample:int) -> bool
int be_audio_output_set_bits_per_sample_ntv(AudioOutput* out, int bps) {
return out->SetBitsPerSample(bps);
}
int32_t be_audio_output_set_bits_per_sample(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_set_bits_per_sample_ntv, "b", ".i");
}
// AudioOutput.set_channels(channels:int) -> bool
int be_audio_output_set_channels_ntv(AudioOutput* out, int channels) {
return out->SetChannels(channels);
}
int32_t be_audio_output_set_channels(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_set_channels_ntv, "b", ".i");
}
// AudioOutput.set_gain(gain:real) -> bool
int be_audio_output_set_gain_ntv(AudioOutput* out, float gain) {
return out->SetGain(gain);
}
int32_t be_audio_output_set_gain(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_set_gain_ntv, "b", ".f");
}
// AudioOutput.begin() -> bool
int be_audio_output_begin_ntv(AudioOutput* out) {
return out->begin();
}
int32_t be_audio_output_begin(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_begin_ntv, "b", ".");
}
// AudioOutput.stop() -> bool
int be_audio_output_stop_ntv(AudioOutput* out) {
return out->stop();
}
int32_t be_audio_output_stop(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_stop_ntv, "b", ".");
}
// AudioOutput.flush() -> bool
void be_audio_output_flush_ntv(AudioOutput* out) {
out->flush();
}
int32_t be_audio_output_flush(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_flush_ntv, "", ".");
}
// AudioOutput.consume_mono(bytes) -> int
int be_audio_output_consume_mono_ntv(AudioOutput* out, uint16_t *pcm, int bytes_len, int index) {
int pcm_len = bytes_len / 2;
int n;
// berry_log_C("be_audio_output_consume_mono_ntv out=%p pcm=%p bytes_len=%i index=%i", out, pcm, bytes_len, index);
for (n = 0; index + n < pcm_len; n++) {
int16_t ms[2];
ms[AudioOutput::LEFTCHANNEL] = ms[AudioOutput::RIGHTCHANNEL] = pcm[index + n];
if (!out->ConsumeSample(ms)) { break; }
}
return n;
}
int32_t be_audio_output_consume_mono(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_consume_mono_ntv, "i", ".(bytes)~i");
}
// AudioOutput.consume_stereo(bytes) -> int
int be_audio_output_consume_stereo_ntv(AudioOutput* out, uint16_t *pcm, int bytes_len, int index) {
int pcm_len = bytes_len / 4; // 2 samples LEFT+RIGHT of 2 bytes each
int n;
// berry_log_C("be_audio_output_consume_stereo_ntv out=%p pcm=%p bytes_len=%i index=%i", out, pcm, bytes_len, index);
for (n = 0; index + n < pcm_len; n++) {
int16_t ms[2];
ms[AudioOutput::LEFTCHANNEL] = pcm[index + n + n];
ms[AudioOutput::RIGHTCHANNEL] = pcm[index + n + n + 1];
if (!out->ConsumeSample(ms)) { break; }
}
return n;
}
int32_t be_audio_output_consume_stereo(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_consume_stereo_ntv, "i", ".(bytes)~i");
}
// AudioOutput.consume_silence() -> int, push silence frames
int be_audio_output_consume_silence_ntv(AudioOutput* out) {
int n = 0;
int16_t ms[2] = {0, 0};
while (true) {
if (!out->ConsumeSample(ms)) { break; }
n++;
}
return n;
}
int32_t be_audio_output_consume_silence(struct bvm *vm) {
return be_call_c_func(vm, (void*) &be_audio_output_consume_silence_ntv, "i", ".");
}
extern "C" {
#include "be_fixed_be_class_audio_output.h"
#include "be_fixed_be_class_audio_output_i2s.h"
#include "be_fixed_be_class_audio_generator.h"
#include "be_fixed_be_class_audio_generator_wav.h"
#include "be_fixed_be_class_audio_generator_mp3.h"
#include "be_fixed_be_class_audio_file_source.h"
#include "be_fixed_be_class_audio_file_source_fs.h"
void be_load_driver_audio_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_audio_output);
be_setglobal(vm, "AudioOutput");
be_pop(vm, 1);
be_pushntvclass(vm, &be_class_audio_output_i2s);
be_setglobal(vm, "AudioOutputI2S");
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_setglobal(vm, "AudioGeneratorMP3");
be_pop(vm, 1);
#ifdef USE_UFILESYS
be_pushntvclass(vm, &be_class_audio_file_source_fs);
be_setglobal(vm, "AudioFileSourceFS");
be_pop(vm, 1);
#endif // USE_UFILESYS
}
}
/* @const_object_info_begin
class be_class_audio_output (scope: global, name: AudioOutput) {
.p, var
init, func(be_audio_output_init)
begin, func(be_audio_output_begin)
stop, func(be_audio_output_stop)
flush, func(be_audio_output_flush)
consume_mono, func(be_audio_output_consume_mono)
consume_stereo, func(be_audio_output_consume_stereo)
consume_silence, func(be_audio_output_consume_silence)
set_rate, func(be_audio_output_set_rate)
set_bits_per_sample, func(be_audio_output_set_bits_per_sample)
set_channels, func(be_audio_output_set_channels)
set_gain, func(be_audio_output_set_gain)
}
class be_class_audio_generator (scope: global, name: AudioGenerator) {
.p, var
}
class be_class_audio_file_source (scope: global, name: AudioFileSource) {
.p, var
}
class be_class_audio_output_i2s (scope: global, name: AudioOutputI2S, super: be_class_audio_output) {
init, func(i2s_output_i2s_init)
deinit, func(i2s_output_i2s_deinit)
stop, func(i2s_output_i2s_stop)
}
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)
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) {
init, func(i2s_generator_mp3_init)
deinit, func(i2s_generator_mp3_deinit)
begin, func(i2s_generator_mp3_begin)
loop, func(i2s_generator_mp3_loop)
stop, func(i2s_generator_mp3_stop)
isrunning, func(i2s_generator_mp3_isrunning)
}
class be_class_audio_file_source_fs (scope: global, name: AudioFileSourceFS, super: be_class_audio_file_source) {
init, func(i2s_file_source_fs_init)
deinit, func(i2s_file_source_fs_deinit)
}
@const_object_info_end */
#endif // USE_I2S_AUDIO_BERRY
#endif // USE_I2S

View File

@ -23,6 +23,6 @@ module light (scope: global) {
reverse_gamma10, func(l_rev_gamma10)
}
@const_object_info_end */
#include "../generate/be_fixed_light.h"
#include "be_fixed_light.h"
#endif // USE_LIGHT

View File

@ -111,6 +111,6 @@ module lv_tasmota (scope: global) {
load_freetype_font, func(lv0_load_freetype_font)
}
@const_object_info_end */
#include "../generate/be_fixed_lv_tasmota.h"
#include "be_fixed_lv_tasmota.h"
#endif // USE_LVGL

View File

@ -81,7 +81,7 @@ int32_t m_md5_finish(struct bvm *vm) {
be_return(vm);
}
#include "../generate/be_fixed_be_class_md5.h"
#include "be_fixed_be_class_md5.h"
void be_load_md5_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_md5);

View File

@ -0,0 +1,2 @@
// TODO

View File

@ -24,7 +24,7 @@ extern int b_onewire_reset_search(bvm *vm);
extern int b_onewire_target_search(bvm *vm);
extern int b_onewire_search(bvm *vm);
#include "../generate/be_fixed_be_class_tasmota_onewire.h"
#include "be_fixed_be_class_tasmota_onewire.h"
void be_load_onewirelib(bvm *vm) {
be_pushntvclass(vm, &be_class_tasmota_onewire);

View File

@ -67,4 +67,4 @@ module path (scope: global, file: tasmota_path) {
remove, func(m_path_remove)
}
@const_object_info_end */
#include "../generate/be_fixed_tasmota_path.h"
#include "be_fixed_tasmota_path.h"

View File

@ -17,7 +17,7 @@ extern int b_serial_read(bvm *vm);
extern int b_serial_available(bvm *vm);
extern int b_serial_flush(bvm *vm);
#include "../generate/be_fixed_be_class_tasmota_serial.h"
#include "be_fixed_be_class_tasmota_serial.h"
void be_load_serial_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_tasmota_serial);

View File

@ -31,6 +31,7 @@ extern int l_delay(bvm *vm);
extern int l_scaleuint(bvm *vm);
extern int l_logInfo(bvm *vm);
extern int l_save(bvm *vm);
extern int t_random_byte(bvm *vm);
extern int l_read_sensors(bvm *vm);
@ -1973,7 +1974,7 @@ be_local_closure(Tasmota_get_light, /* name */
);
/*******************************************************************/
#include "../generate/be_fixed_be_class_tasmota.h"
#include "be_fixed_be_class_tasmota.h"
// Class definition

View File

@ -20,7 +20,7 @@ extern int wc_tcp_write(bvm *vm);
extern int wc_tcp_read(bvm *vm);
extern int wc_tcp_readbytes(bvm *vm);
#include "../generate/be_fixed_be_class_tcpclient.h"
#include "be_fixed_be_class_tcpclient.h"
void be_load_tcpclient_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_tcpclient);

View File

@ -116,7 +116,7 @@ extern "C" {
}
}
#include "../generate/be_fixed_be_class_udp.h"
#include "be_fixed_be_class_udp.h"
void be_load_udp_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_udp);

View File

@ -24,7 +24,7 @@ extern int wc_getstring(bvm *vm);
extern int wc_writefile(bvm *vm);
extern int wc_getsize(bvm *vm);
#include "../generate/be_fixed_be_class_webclient.h"
#include "be_fixed_be_class_webclient.h"
void be_load_webclient_lib(bvm *vm) {
be_pushntvclass(vm, &be_class_webclient);

View File

@ -50,6 +50,6 @@ module webserver (scope: global) {
has_arg, func(w_webserver_has_arg)
}
@const_object_info_end */
#include "../generate/be_fixed_webserver.h"
#include "be_fixed_webserver.h"
#endif // USE_WEBSERVER

View File

@ -118,7 +118,7 @@ be_local_closure(read_bytes, /* name */
/*******************************************************************/
#include "../generate/be_fixed_be_class_tasmota_wire.h"
#include "be_fixed_be_class_tasmota_wire.h"
void be_load_wirelib(bvm *vm) {
be_pushntvclass(vm, &be_class_tasmota_wire);

View File

@ -0,0 +1,8 @@
// force include of module by including this file
#ifndef __BERRY_TASMOTA__
#define __BERRY_TASMOTA__
#endif // __BERRY_TASMOTA__

View File

@ -618,6 +618,16 @@ extern "C" {
if (len+3 > LOGSZ) { strcat(log_data, "..."); } // Actual data is more
berry_log(log_data);
}
void tasmota_log_C(int32_t loglevel, const char * berry_buf, ...) {
va_list arg;
va_start(arg, berry_buf);
char* log_data = ext_vsnprintf_malloc_P(berry_buf, arg);
va_end(arg);
if (log_data == nullptr) { return; }
AddLogData(loglevel, log_data);
free(log_data);
}
}
#endif // USE_BERRY

View File

@ -23,6 +23,7 @@
#define XDRV_52 52
#include <berry.h>
#include "berry_tasmota.h"
#include "be_vm.h"
#include "ZipReadFS.h"
@ -727,6 +728,7 @@ bool Xdrv52(uint8_t function)
BrLoad("autoexec.be"); // run autoexec.be at first tick, so we know all modules are initialized
berry.autoexec_done = true;
}
callBerryEventDispatcher(PSTR("every_50ms"), nullptr, 0, nullptr);
break;
// Berry wide commands and events
@ -737,7 +739,9 @@ bool Xdrv52(uint8_t function)
result = callBerryRule(nullptr, true);
break;
case FUNC_MQTT_DATA:
{int32_t now = millis();
result = callBerryEventDispatcher(PSTR("mqtt_data"), XdrvMailbox.topic, 0, XdrvMailbox.data, XdrvMailbox.data_len);
AddLog(LOG_LEVEL_INFO, ">>>: mqtt_data ms = %i", millis()-now);}
break;
case FUNC_COMMAND:
result = DecodeCommand(kBrCommands, BerryCommand);