add sound

This commit is contained in:
asrael 2026-01-07 17:45:46 -06:00
parent 99d9c43ea3
commit 01d6e09a91
22 changed files with 1825 additions and 39 deletions

View file

@ -12,8 +12,9 @@ local gui = require("pxl8.gui")
local world = require("pxl8.world")
local transition = require("pxl8.transition")
local anim = require("pxl8.anim")
local sfx = require("pxl8.sfx")
core.init(_pxl8_gfx, _pxl8_input, _pxl8_sys)
core.init(_pxl8_gfx, _pxl8_input, _pxl8_sfx_mixer, _pxl8_sys)
local pxl8 = {}
@ -189,4 +190,57 @@ pxl8.anim_set_state = anim.set_state
pxl8.anim_stop = anim.stop
pxl8.anim_update = anim.update
pxl8.sfx_compressor_create = sfx.compressor_create
pxl8.sfx_compressor_set_attack = sfx.compressor_set_attack
pxl8.sfx_compressor_set_ratio = sfx.compressor_set_ratio
pxl8.sfx_compressor_set_release = sfx.compressor_set_release
pxl8.sfx_compressor_set_threshold = sfx.compressor_set_threshold
pxl8.sfx_context_append_node = sfx.context_append_node
pxl8.sfx_context_create = sfx.context_create
pxl8.sfx_context_destroy = sfx.context_destroy
pxl8.sfx_context_get_head = sfx.context_get_head
pxl8.sfx_context_get_volume = sfx.context_get_volume
pxl8.sfx_context_insert_node = sfx.context_insert_node
pxl8.sfx_context_remove_node = sfx.context_remove_node
pxl8.sfx_context_set_volume = sfx.context_set_volume
pxl8.sfx_delay_create = sfx.delay_create
pxl8.sfx_delay_set_feedback = sfx.delay_set_feedback
pxl8.sfx_delay_set_mix = sfx.delay_set_mix
pxl8.sfx_delay_set_time = sfx.delay_set_time
pxl8.sfx_get_master_volume = sfx.get_master_volume
pxl8.sfx_mixer_attach = sfx.mixer_attach
pxl8.sfx_mixer_detach = sfx.mixer_detach
pxl8.sfx_node_destroy = sfx.node_destroy
pxl8.sfx_note_to_freq = sfx.note_to_freq
pxl8.sfx_play_note = sfx.play_note
pxl8.sfx_release_voice = sfx.release_voice
pxl8.sfx_reverb_create = sfx.reverb_create
pxl8.sfx_reverb_set_damping = sfx.reverb_set_damping
pxl8.sfx_reverb_set_mix = sfx.reverb_set_mix
pxl8.sfx_reverb_set_room = sfx.reverb_set_room
pxl8.sfx_set_master_volume = sfx.set_master_volume
pxl8.sfx_stop_all = sfx.stop_all
pxl8.sfx_stop_voice = sfx.stop_voice
pxl8.sfx_voice_params = sfx.voice_params
pxl8.SFX_FILTER_BANDPASS = sfx.FILTER_BANDPASS
pxl8.SFX_FILTER_HIGHPASS = sfx.FILTER_HIGHPASS
pxl8.SFX_FILTER_LOWPASS = sfx.FILTER_LOWPASS
pxl8.SFX_FILTER_NONE = sfx.FILTER_NONE
pxl8.SFX_LFO_AMPLITUDE = sfx.LFO_AMPLITUDE
pxl8.SFX_LFO_FILTER = sfx.LFO_FILTER
pxl8.SFX_LFO_PITCH = sfx.LFO_PITCH
pxl8.SFX_NODE_COMPRESSOR = sfx.NODE_COMPRESSOR
pxl8.SFX_NODE_DELAY = sfx.NODE_DELAY
pxl8.SFX_NODE_REVERB = sfx.NODE_REVERB
pxl8.SFX_WAVE_NOISE = sfx.WAVE_NOISE
pxl8.SFX_WAVE_PULSE = sfx.WAVE_PULSE
pxl8.SFX_WAVE_SAW = sfx.WAVE_SAW
pxl8.SFX_WAVE_SINE = sfx.WAVE_SINE
pxl8.SFX_WAVE_SQUARE = sfx.WAVE_SQUARE
pxl8.SFX_WAVE_TRIANGLE = sfx.WAVE_TRIANGLE
return pxl8

View file

@ -3,10 +3,11 @@ local C = ffi.C
local core = {}
function core.init(gfx_ptr, input_ptr, sys_ptr)
core.gfx = gfx_ptr
core.input = input_ptr
core.sys = sys_ptr
function core.init(gfx, input, sfx_mixer, sys)
core.gfx = gfx
core.input = input
core.sfx_mixer = sfx_mixer
core.sys = sys
end
function core.get_fps()

198
src/lua/pxl8/sfx.lua Normal file
View file

@ -0,0 +1,198 @@
local ffi = require("ffi")
local C = ffi.C
local core = require("pxl8.core")
local sfx = {}
sfx.FILTER_BANDPASS = C.PXL8_SFX_FILTER_BANDPASS
sfx.FILTER_HIGHPASS = C.PXL8_SFX_FILTER_HIGHPASS
sfx.FILTER_LOWPASS = C.PXL8_SFX_FILTER_LOWPASS
sfx.FILTER_NONE = C.PXL8_SFX_FILTER_NONE
sfx.LFO_AMPLITUDE = C.PXL8_SFX_LFO_AMPLITUDE
sfx.LFO_FILTER = C.PXL8_SFX_LFO_FILTER
sfx.LFO_PITCH = C.PXL8_SFX_LFO_PITCH
sfx.NODE_COMPRESSOR = C.PXL8_SFX_NODE_COMPRESSOR
sfx.NODE_DELAY = C.PXL8_SFX_NODE_DELAY
sfx.NODE_REVERB = C.PXL8_SFX_NODE_REVERB
sfx.WAVE_NOISE = C.PXL8_SFX_WAVE_NOISE
sfx.WAVE_PULSE = C.PXL8_SFX_WAVE_PULSE
sfx.WAVE_SAW = C.PXL8_SFX_WAVE_SAW
sfx.WAVE_SINE = C.PXL8_SFX_WAVE_SINE
sfx.WAVE_SQUARE = C.PXL8_SFX_WAVE_SQUARE
sfx.WAVE_TRIANGLE = C.PXL8_SFX_WAVE_TRIANGLE
function sfx.compressor_create(opts)
opts = opts or {}
local cfg = ffi.new("pxl8_sfx_compressor_config")
cfg.attack = opts.attack or 10
cfg.ratio = opts.ratio or 4
cfg.release = opts.release or 100
cfg.threshold = opts.threshold or -12
return C.pxl8_sfx_compressor_create(cfg)
end
function sfx.compressor_set_attack(node, attack)
C.pxl8_sfx_compressor_set_attack(node, attack)
end
function sfx.compressor_set_ratio(node, ratio)
C.pxl8_sfx_compressor_set_ratio(node, ratio)
end
function sfx.compressor_set_release(node, release)
C.pxl8_sfx_compressor_set_release(node, release)
end
function sfx.compressor_set_threshold(node, threshold)
C.pxl8_sfx_compressor_set_threshold(node, threshold)
end
function sfx.context_append_node(ctx, node)
C.pxl8_sfx_context_append_node(ctx, node)
end
function sfx.context_create()
return C.pxl8_sfx_context_create()
end
function sfx.context_destroy(ctx)
C.pxl8_sfx_context_destroy(ctx)
end
function sfx.context_get_head(ctx)
return C.pxl8_sfx_context_get_head(ctx)
end
function sfx.context_get_volume(ctx)
return C.pxl8_sfx_context_get_volume(ctx)
end
function sfx.context_insert_node(ctx, after, node)
C.pxl8_sfx_context_insert_node(ctx, after, node)
end
function sfx.context_remove_node(ctx, node)
C.pxl8_sfx_context_remove_node(ctx, node)
end
function sfx.context_set_volume(ctx, volume)
C.pxl8_sfx_context_set_volume(ctx, volume)
end
function sfx.delay_create(opts)
opts = opts or {}
local cfg = ffi.new("pxl8_sfx_delay_config")
cfg.feedback = opts.feedback or 0.4
cfg.mix = opts.mix or 0.25
cfg.time_l = opts.time_l or 350
cfg.time_r = opts.time_r or 500
return C.pxl8_sfx_delay_create(cfg)
end
function sfx.delay_set_feedback(node, feedback)
C.pxl8_sfx_delay_set_feedback(node, feedback)
end
function sfx.delay_set_mix(node, mix)
C.pxl8_sfx_delay_set_mix(node, mix)
end
function sfx.delay_set_time(node, time_l, time_r)
C.pxl8_sfx_delay_set_time(node, time_l, time_r)
end
function sfx.get_master_volume()
return C.pxl8_sfx_mixer_get_master_volume(core.sfx_mixer)
end
function sfx.mixer_attach(ctx)
C.pxl8_sfx_mixer_attach(core.sfx_mixer, ctx)
end
function sfx.mixer_detach(ctx)
C.pxl8_sfx_mixer_detach(core.sfx_mixer, ctx)
end
function sfx.node_destroy(node)
C.pxl8_sfx_node_destroy(node)
end
function sfx.note_to_freq(note)
return C.pxl8_sfx_note_to_freq(note)
end
function sfx.play_note(ctx, note, params, volume)
return C.pxl8_sfx_play_note(ctx, note, params, volume or 0.8)
end
function sfx.release_voice(ctx, voice_id)
C.pxl8_sfx_release_voice(ctx, voice_id)
end
function sfx.reverb_create(opts)
opts = opts or {}
local cfg = ffi.new("pxl8_sfx_reverb_config")
cfg.damping = opts.damping or 0.5
cfg.mix = opts.mix or 0.3
cfg.room = opts.room or 0.5
return C.pxl8_sfx_reverb_create(cfg)
end
function sfx.reverb_set_damping(node, damping)
C.pxl8_sfx_reverb_set_damping(node, damping)
end
function sfx.reverb_set_mix(node, mix)
C.pxl8_sfx_reverb_set_mix(node, mix)
end
function sfx.reverb_set_room(node, room)
C.pxl8_sfx_reverb_set_room(node, room)
end
function sfx.set_master_volume(volume)
C.pxl8_sfx_mixer_set_master_volume(core.sfx_mixer, volume)
end
function sfx.stop_all(ctx)
C.pxl8_sfx_stop_all(ctx)
end
function sfx.stop_voice(ctx, voice_id)
C.pxl8_sfx_stop_voice(ctx, voice_id)
end
function sfx.voice_params(opts)
opts = opts or {}
local params = ffi.new("pxl8_sfx_voice_params")
params.amp_env.attack = opts.attack or 0.01
params.amp_env.decay = opts.decay or 0.1
params.amp_env.sustain = opts.sustain or 0.5
params.amp_env.release = opts.release or 0.2
params.filter_env.attack = opts.filter_attack or 0.01
params.filter_env.decay = opts.filter_decay or 0.1
params.filter_env.sustain = opts.filter_sustain or 0.3
params.filter_env.release = opts.filter_release or 0.1
params.filter_type = opts.filter_type or C.PXL8_SFX_FILTER_NONE
params.lfo_target = opts.lfo_target or C.PXL8_SFX_LFO_PITCH
params.lfo_waveform = opts.lfo_waveform or C.PXL8_SFX_WAVE_SINE
params.waveform = opts.waveform or C.PXL8_SFX_WAVE_SINE
params.filter_cutoff = opts.filter_cutoff or 4000
params.filter_env_depth = opts.filter_env_depth or 0
params.filter_resonance = opts.filter_resonance or 0
params.fx_send = opts.fx_send or 0
params.lfo_depth = opts.lfo_depth or 0
params.lfo_rate = opts.lfo_rate or 0
params.pulse_width = opts.pulse_width or 0.5
return params
end
return sfx