Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: FFT support #2607

Merged
merged 7 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,8 @@ You can find iOS/tvOS version here
* Kolten Pearson - [Github @koltenpearson](https://github.com/koltenpearson)
* Cort Stratton - [Github @cdwfs](https://github.com/cdwfs)
* Alice - [Github @aliceisjustplaying](https://github.com/aliceisjustplaying)
* Sven Knebel - [Github @sknebel](https://github.com/sknebel)
* Graham Bates - [Github @grahambates](https://github.com/grahambates)
* Kii - [Github @kiikrindar](https://github.com/kiikrindar)
* Matt Westcott - [Github @gasman](https://github.com/gasman)
* NuSan - [Github @TheNuSan](https://github.com/thenusan)
4 changes: 4 additions & 0 deletions cmake/core.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(BUILD_DEPRECATED TRUE)

set(TIC80CORE_DIR ${CMAKE_SOURCE_DIR}/src)
set(TIC80CORE_SRC
${TIC80CORE_DIR}/fftdata.c
${TIC80CORE_DIR}/core/core.c
${TIC80CORE_DIR}/core/draw.c
${TIC80CORE_DIR}/core/io.c
Expand All @@ -25,6 +26,9 @@ set(TIC80CORE_SRC
${TIC80CORE_DIR}/zip.c
${TIC80CORE_DIR}/tilesheet.c
${TIC80CORE_DIR}/script.c
${TIC80CORE_DIR}/ext/fft.c
${TIC80CORE_DIR}/ext/kiss_fft.c
${TIC80CORE_DIR}/ext/kiss_fftr.c
)

if(BUILD_DEPRECATED)
Expand Down
4 changes: 4 additions & 0 deletions include/tic80_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,7 @@
# define TIC80_API
# endif
#endif

#if defined(ANDROID) || defined(__ANDROID__) || defined(BAREMETALPI) || defined(_3DS)
# define TIC80_FFT_UNSUPPORTED 1
#endif
30 changes: 29 additions & 1 deletion src/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,35 @@ enum
3, \
0, \
void, \
tic_mem*, s32 index, u8 flag, bool value)
tic_mem*, s32 index, u8 flag, bool value) \
\
\
macro(fft, \
"fft(start_freq end_freq=-1)", \
\
"Retrieves a value from 1024 buckets that map to a region of audible frequencies.\n" \
"Each has value of roughly 0..1 based on the intensity of sound at that frequency at that time.\n" \
"If end_freq is not provided, a single value is returned for the start_freq.\n" \
"If end_freq is provided, a sum of all values in the range is returned.", \
2, \
1, \
0, \
double, \
tic_mem*, s32 startFreq, s32 endFreq) \
\
\
macro(ffts, \
"ffts(start_freq end_freq=-1)", \
\
"Creates 1024 buckets that map to a region of audible frequencies and applies smoothing to it.\n" \
"Each returns a value of roughly 0..1 based on the intensity of sound at that frequency at that time.\n" \
"If end_freq is not provided, a single value is returned for the start_freq.\n" \
"If end_freq is provided, a sum of all values in the range is returned.", \
2, \
1, \
0, \
double, \
tic_mem*, s32 startFreq, s32 endFreq)

#define TIC_API_DEF(name, _, __, ___, ____, _____, ret, ...) ret tic_api_##name(__VA_ARGS__);
TIC_API_LIST(TIC_API_DEF)
Expand Down
32 changes: 32 additions & 0 deletions src/api/janet.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static Janet janet_key(int32_t argc, Janet* argv);
static Janet janet_keyp(int32_t argc, Janet* argv);
static Janet janet_fget(int32_t argc, Janet* argv);
static Janet janet_fset(int32_t argc, Janet* argv);
static Janet janet_fft(int32_t argc, Janet* argv);
static Janet janet_ffts(int32_t argc, Janet* argv);

static void closeJanet(tic_mem* tic);
static bool initJanet(tic_mem* tic, const char* code);
Expand Down Expand Up @@ -140,6 +142,8 @@ static const JanetReg janet_c_functions[] =
{"keyp", janet_keyp, NULL},
{"fget", janet_fget, NULL},
{"fset", janet_fset, NULL},
{"fft", janet_fft, NULL},
{"ffts", janet_ffts, NULL},
{NULL, NULL, NULL}
};

Expand Down Expand Up @@ -1036,6 +1040,34 @@ static Janet janet_fset(int32_t argc, Janet* argv)
return janet_wrap_nil();
}

static Janet janet_fft(int32_t argc, Janet* argv)
{
janet_arity(argc, 1, 2);

s32 start_freq = -1;
s32 end_freq = -1;

if (argc >= 1) start_freq = janet_getinteger(argv, 0);
if (argc >= 2) end_freq = janet_getinteger(argv, 1);

tic_core* core = getJanetMachine(); tic_mem* tic = (tic_mem*)core;
return janet_wrap_number(core->api.fft(tic, start_freq, end_freq));
}

static Janet janet_ffts(int32_t argc, Janet* argv)
{
janet_arity(argc, 1, 2);

s32 start_freq = -1;
s32 end_freq = -1;

if (argc >= 1) start_freq = janet_getinteger(argv, 0);
if (argc >= 2) end_freq = janet_getinteger(argv, 1);

tic_core* core = getJanetMachine(); tic_mem* tic = (tic_mem*)core;
return janet_wrap_number(core->api.fft(tic, start_freq, end_freq));
}

/* ***************** */
static void reportError(tic_core* core, Janet result)
{
Expand Down
18 changes: 18 additions & 0 deletions src/api/js.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,24 @@ static JSValue js_fset(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueC
return JS_UNDEFINED;
}

static JSValue js_fft(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv)
{
tic_core* core = getCore(ctx); tic_mem* tic = (tic_mem*)core;
s32 start_freq = getInteger(ctx, argv[0]);
s32 end_freq = getInteger2(ctx, argv[1], -1);

return JS_NewFloat64(ctx, core->api.fft(tic, start_freq, end_freq));
}

static JSValue js_ffts(JSContext *ctx, JSValueConst this_val, s32 argc, JSValueConst *argv)
{
tic_core* core = getCore(ctx); tic_mem* tic = (tic_mem*)core;
s32 start_freq = getInteger(ctx, argv[0]);
s32 end_freq = getInteger2(ctx, argv[1], -1);

return JS_NewFloat64(ctx, core->api.ffts(tic, start_freq, end_freq));
}

static bool initJavascript(tic_mem* tic, const char* code)
{
closeJavascript(tic);
Expand Down
50 changes: 50 additions & 0 deletions src/api/luaapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,56 @@ static s32 lua_fset(lua_State* lua)
return 0;
}

static s32 lua_fft(lua_State* lua)
{
tic_core* core = getLuaCore(lua);

tic_mem* tic = (tic_mem*)getLuaCore(lua);
s32 top = lua_gettop(lua);

if (top >= 1)
{
s32 start_freq = getLuaNumber(lua, 1);
s32 end_freq = -1;

if (top >= 2)
{
end_freq = getLuaNumber(lua, 2);
}

lua_pushnumber(lua, core->api.fft(tic, start_freq, end_freq));
return 1;
}

luaL_error(lua, "invalid params, fft(start_freq, end_freq=-1)\n");
return 0;
}

static s32 lua_ffts(lua_State* lua)
{
tic_core* core = getLuaCore(lua);

tic_mem* tic = (tic_mem*)getLuaCore(lua);
s32 top = lua_gettop(lua);

if (top >= 1)
{
s32 start_freq = getLuaNumber(lua, 1);
s32 end_freq = -1;

if (top >= 2)
{
end_freq = getLuaNumber(lua, 2);
}

lua_pushnumber(lua, core->api.ffts(tic, start_freq, end_freq));
return 1;
}

luaL_error(lua, "invalid params, ffts(start_freq, end_freq=-1)\n");
return 0;
}

static s32 lua_dofile(lua_State *lua)
{
luaL_error(lua, "unknown method: \"dofile\"\n");
Expand Down
38 changes: 38 additions & 0 deletions src/api/mruby.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,44 @@ static mrb_value mrb_fset(mrb_state* mrb, mrb_value self)
return mrb_nil_value();
}

static mrb_value mrb_fft(mrb_state* mrb, mrb_value self)
{
mrb_int start_freq, end_freq = -1;
mrb_int argc = mrb_get_args(mrb, "i|i", &start_freq, &end_freq);

tic_core* core = getMRubyMachine(mrb);
tic_mem* tic = (tic_mem*)core;

if (argc == 0)
{
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid params, fft [ start_freq end_freq ]\n");
return mrb_nil_value();
}
else
{
return mrb_float_value(mrb, core->api.fft(tic, start_freq, end_freq));
}
}

static mrb_value mrb_ffts(mrb_state* mrb, mrb_value self)
{
mrb_int start_freq, end_freq = -1;
mrb_int argc = mrb_get_args(mrb, "i|i", &start_freq, &end_freq);

tic_core* core = getMRubyMachine(mrb);
tic_mem* tic = (tic_mem*)core;

if (argc == 0)
{
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid params, ffts [ start_freq end_freq ]\n");
return mrb_nil_value();
}
else
{
return mrb_float_value(mrb, core->api.ffts(tic, start_freq, end_freq));
}
}

typedef struct
{
mrb_state* mrb;
Expand Down
44 changes: 44 additions & 0 deletions src/api/python.c
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,44 @@ static int py_vbank(pkpy_vm* vm) {
return 1;
}

static int py_fft(pkpy_vm* vm)
{
tic_core* core;
get_core(vm, &core);
tic_mem* tic = (tic_mem*)core;
if (pkpy_check_error(vm))
return 0;

s32 start_freq = -1;
s32 end_freq = -1;

if (!pkpy_is_none(vm, 0))
pkpy_to_int(vm, 0, &start_freq);
if (!pkpy_is_none(vm, 1))
pkpy_to_int(vm, 1, &end_freq);
pkpy_push_float(vm, core->api.fft(tic, start_freq, end_freq));
return 1;
}

static int py_ffts(pkpy_vm* vm)
{
tic_core* core;
get_core(vm, &core);
tic_mem* tic = (tic_mem*)core;
if (pkpy_check_error(vm))
return 0;

s32 start_freq = -1;
s32 end_freq = -1;

if (!pkpy_is_none(vm, 0))
pkpy_to_int(vm, 0, &start_freq);
if (!pkpy_is_none(vm, 1))
pkpy_to_int(vm, 1, &end_freq);
pkpy_push_float(vm, core->api.ffts(tic, start_freq, end_freq));
return 1;
}

static bool setup_c_bindings(pkpy_vm* vm) {
pkpy_push_function(vm, "btn(id: int) -> bool", py_btn);
pkpy_setglobal_2(vm, "btn");
Expand Down Expand Up @@ -1276,6 +1314,12 @@ static bool setup_c_bindings(pkpy_vm* vm) {
pkpy_push_function(vm, "vbank(bank: int=None) -> int", py_vbank);
pkpy_setglobal_2(vm, "vbank");

pkpy_push_function(vm, "fft(start_freq: int, end_freq: int=-1) -> float", py_fft);
pkpy_setglobal_2(vm, "fft");

pkpy_push_function(vm, "ffts(start_freq: int, end_freq: int=-1) -> float", py_ffts);
pkpy_setglobal_2(vm, "ffts");

if(pkpy_check_error(vm))
return false;

Expand Down
25 changes: 25 additions & 0 deletions src/api/scheme.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,31 @@ s7_pointer scheme_fset(s7_scheme* sc, s7_pointer args)
return s7_nil(sc);
}

s7_pointer scheme_fft(s7_scheme* sc, s7_pointer args)
{
// fft(int start_freq, int end_freq=-1) -> float_value
tic_core* core = getSchemeCore(sc);
tic_mem* tic = (tic_mem*)core;

const int argn = s7_list_length(sc, args);
const s32 start_freq = argn > 0 ? s7_integer(s7_car(args)) : -1;
const s32 end_freq = argn > 1 ? s7_integer(s7_cadr(args)) : -1;

return s7_make_real(sc, core->api.fft(tic, start_freq, end_freq));
}

s7_pointer scheme_ffts(s7_scheme* sc, s7_pointer args)
{
// ffts(int start_freq, int end_freq=-1) -> float_value
tic_core* core = getSchemeCore(sc);
tic_mem* tic = (tic_mem*)core;
const int argn = s7_list_length(sc, args);
const s32 start_freq = argn > 0 ? s7_integer(s7_car(args)) : -1;
const s32 end_freq = argn > 1 ? s7_integer(s7_cadr(args)) : -1;

return s7_make_real(sc, core->api.ffts(tic, start_freq, end_freq));
}

static void initAPI(tic_core* core)
{
s7_scheme* sc = core->currentVM;
Expand Down
Loading
Loading