mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-21 19:45:10 +00:00
Add basic Bass audio engine (#58)
This commit is contained in:
parent
6da950dc52
commit
b8553162c2
28 changed files with 2227 additions and 14 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -87,6 +87,8 @@ sm64config.txt
|
|||
!/assets/**/*custom*/**/*.bin
|
||||
!/lib/discordsdk/*.*
|
||||
!/lib/discordsdk/x86/*.*
|
||||
!/lib/bass/**
|
||||
!/lib/bass/x86/**
|
||||
!/lib/lua/**/*.*
|
||||
|
||||
# visual studio
|
||||
|
|
29
Makefile
29
Makefile
|
@ -494,7 +494,7 @@ ACTOR_DIR := actors
|
|||
LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h)))
|
||||
|
||||
# Directories containing source files
|
||||
SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets asm lib sound
|
||||
SRC_DIRS := src src/engine src/game src/audio src/bass_audio src/menu src/buffers actors levels bin data assets asm lib sound
|
||||
BIN_DIRS := bin bin/$(VERSION)
|
||||
|
||||
# PC files
|
||||
|
@ -607,6 +607,23 @@ ifeq ($(DISCORD_SDK), 1)
|
|||
endif
|
||||
endif
|
||||
|
||||
BASS_LIBS :=
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
ifeq ($(TARGET_BITS), 32)
|
||||
BASS_LIBS := lib/bass/x86/bass.dll lib/bass/x86/bass_fx.dll
|
||||
else
|
||||
BASS_LIBS := lib/bass/bass.dll lib/bass/bass_fx.dll
|
||||
endif
|
||||
else ifeq ($(OSX_BUILD),1)
|
||||
# needs testing
|
||||
# HACKY! Instead of figuring out all of the dynamic library linking madness...
|
||||
# I copied the library and gave it two names.
|
||||
# This really shouldn't be required, but I got tired of trying to do it the "right way"
|
||||
BASS_LIBS := lib/bass/bass.dylib lib/bass/libbass.dylib lib/bass/bass_fx.dylib lib/bass/libbass_fx.dylib
|
||||
else
|
||||
BASS_LIBS := lib/bass/libbass.so lib/bass/libbass_fx.so
|
||||
endif
|
||||
|
||||
MOD_DIR := mods
|
||||
|
||||
# Remove old mod dir
|
||||
|
@ -893,14 +910,13 @@ endif
|
|||
ifeq ($(WINDOWS_BUILD),1)
|
||||
LDFLAGS += -L"ws2_32" -lwsock32
|
||||
ifeq ($(DISCORD_SDK),1)
|
||||
LDFLAGS += -Wl,-Bdynamic -L./lib/discordsdk/ -ldiscord_game_sdk -Wl,-Bstatic
|
||||
LDFLAGS += -Wl,-Bdynamic -L./lib/discordsdk/ -L./lib/bass/ -ldiscord_game_sdk -lbass -lbass_fx -Wl,-Bstatic
|
||||
endif
|
||||
else
|
||||
ifeq ($(DISCORD_SDK),1)
|
||||
LDFLAGS += -ldiscord_game_sdk -Wl,-rpath . -Wl,-rpath lib/discordsdk
|
||||
LDFLAGS += -ldiscord_game_sdk -lbass -lbass_fx -Wl,-rpath . -Wl,-rpath lib/discordsdk -Wl,-rpath lib/bass
|
||||
endif
|
||||
endif
|
||||
|
||||
# Prevent a crash with -sopt
|
||||
export LANG := C
|
||||
|
||||
|
@ -1142,6 +1158,9 @@ $(BUILD_DIR)/$(RPC_LIBS):
|
|||
$(BUILD_DIR)/$(DISCORD_SDK_LIBS):
|
||||
@$(CP) -f $(DISCORD_SDK_LIBS) $(BUILD_DIR)
|
||||
|
||||
$(BUILD_DIR)/$(BASS_LIBS):
|
||||
@$(CP) -f $(BASS_LIBS) $(BUILD_DIR)
|
||||
|
||||
$(BUILD_DIR)/$(MOD_DIR):
|
||||
@$(CP) -f -r $(MOD_DIR) $(BUILD_DIR)
|
||||
|
||||
|
@ -1504,7 +1523,7 @@ ifeq ($(TARGET_N64),1)
|
|||
$(BUILD_DIR)/$(TARGET).objdump: $(ELF)
|
||||
$(OBJDUMP) -D $< > $@
|
||||
else
|
||||
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(MOD_DIR)
|
||||
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(BASS_LIBS) $(BUILD_DIR)/$(MOD_DIR)
|
||||
@$(PRINT) "$(GREEN)Linking executable: $(BLUE)$@ $(NO_COL)\n"
|
||||
$(V)$(LD) $(PROF_FLAGS) -L $(BUILD_DIR) -o $@ $(O_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS) $(EXTRA_INCLUDES)
|
||||
endif
|
||||
|
|
|
@ -7138,6 +7138,24 @@ function deref_s32_pointer(pointer)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param audio_stream integer
|
||||
--- @return nil
|
||||
function destroy_audio(audio_stream)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param audio_stream integer
|
||||
--- @return nil
|
||||
function destroy_sample(audio_stream)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param sample integer
|
||||
--- @return integer
|
||||
function get_audio_from_sample(sample)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return integer
|
||||
function get_current_save_file_num()
|
||||
-- ...
|
||||
|
@ -7149,6 +7167,12 @@ function get_environment_region(index)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param audio_stream integer
|
||||
--- @return number
|
||||
function get_frequency_audio(audio_stream)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
--- @param index integer
|
||||
--- @return number
|
||||
|
@ -7170,11 +7194,23 @@ function get_hand_foot_pos_z(m, index)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param audio_stream integer
|
||||
--- @return boolean
|
||||
function get_looping_audio(audio_stream)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @return integer
|
||||
function get_network_area_timer()
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param audio_stream integer
|
||||
--- @return number
|
||||
function get_position_audio(audio_stream)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param initialValue integer
|
||||
--- @return Pointer_integer
|
||||
function get_temp_s32_pointer(initialValue)
|
||||
|
@ -7214,6 +7250,18 @@ function hud_show()
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param file_name string
|
||||
--- @return integer
|
||||
function load_audio(file_name)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param file_name string
|
||||
--- @return integer
|
||||
function load_sample(file_name)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param name string
|
||||
--- @param level integer
|
||||
--- @param area integer
|
||||
|
|
|
@ -1577,4 +1577,3 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
|||
---
|
||||
|
||||
1 | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [next >](functions-2.md)]
|
||||
|
||||
|
|
1131
include/bass/bass.h
Normal file
1131
include/bass/bass.h
Normal file
File diff suppressed because it is too large
Load diff
443
include/bass/bass_fx.h
Normal file
443
include/bass/bass_fx.h
Normal file
|
@ -0,0 +1,443 @@
|
|||
/*===========================================================================
|
||||
BASS_FX 2.4 - Copyright (c) 2002-2018 (: JOBnik! :) [Arthur Aminov, ISRAEL]
|
||||
[http://www.jobnik.org]
|
||||
|
||||
bugs/suggestions/questions:
|
||||
forum : http://www.un4seen.com/forum/?board=1
|
||||
http://www.jobnik.org/forums
|
||||
e-mail : bass_fx@jobnik.org
|
||||
--------------------------------------------------
|
||||
|
||||
NOTE: This header will work only with BASS_FX version 2.4.12
|
||||
Check www.un4seen.com or www.jobnik.org for any later versions.
|
||||
|
||||
* Requires BASS 2.4 (available at http://www.un4seen.com)
|
||||
===========================================================================*/
|
||||
|
||||
#ifndef BASS_FX_H
|
||||
#define BASS_FX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BASS_FXDEF
|
||||
#define BASS_FXDEF(f) WINAPI f
|
||||
#endif
|
||||
|
||||
// BASS_CHANNELINFO types
|
||||
#define BASS_CTYPE_STREAM_TEMPO 0x1f200
|
||||
#define BASS_CTYPE_STREAM_REVERSE 0x1f201
|
||||
|
||||
// Tempo / Reverse / BPM / Beat flag
|
||||
#define BASS_FX_FREESOURCE 0x10000 // Free the source handle as well?
|
||||
|
||||
// BASS_FX Version
|
||||
DWORD BASS_FXDEF(BASS_FX_GetVersion)();
|
||||
|
||||
/*===========================================================================
|
||||
DSP (Digital Signal Processing)
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
Multi-channel order of each channel is as follows:
|
||||
3 channels left-front, right-front, center.
|
||||
4 channels left-front, right-front, left-rear/side, right-rear/side.
|
||||
5 channels left-front, right-front, center, left-rear/side, right-rear/side.
|
||||
6 channels (5.1) left-front, right-front, center, LFE, left-rear/side, right-rear/side.
|
||||
8 channels (7.1) left-front, right-front, center, LFE, left-rear/side, right-rear/side, left-rear center, right-rear center.
|
||||
*/
|
||||
|
||||
// DSP channels flags
|
||||
#define BASS_BFX_CHANALL -1 // all channels at once (as by default)
|
||||
#define BASS_BFX_CHANNONE 0 // disable an effect for all channels
|
||||
#define BASS_BFX_CHAN1 1 // left-front channel
|
||||
#define BASS_BFX_CHAN2 2 // right-front channel
|
||||
#define BASS_BFX_CHAN3 4 // see above info
|
||||
#define BASS_BFX_CHAN4 8 // see above info
|
||||
#define BASS_BFX_CHAN5 16 // see above info
|
||||
#define BASS_BFX_CHAN6 32 // see above info
|
||||
#define BASS_BFX_CHAN7 64 // see above info
|
||||
#define BASS_BFX_CHAN8 128 // see above info
|
||||
|
||||
// if you have more than 8 channels (7.1), use this macro
|
||||
#define BASS_BFX_CHANNEL_N(n) (1<<((n)-1))
|
||||
|
||||
// DSP effects
|
||||
enum {
|
||||
BASS_FX_BFX_ROTATE = 0x10000, // A channels volume ping-pong / multi channel
|
||||
BASS_FX_BFX_ECHO, // Echo / 2 channels max (deprecated)
|
||||
BASS_FX_BFX_FLANGER, // Flanger / multi channel (deprecated)
|
||||
BASS_FX_BFX_VOLUME, // Volume / multi channel
|
||||
BASS_FX_BFX_PEAKEQ, // Peaking Equalizer / multi channel
|
||||
BASS_FX_BFX_REVERB, // Reverb / 2 channels max (deprecated)
|
||||
BASS_FX_BFX_LPF, // Low Pass Filter 24dB / multi channel (deprecated)
|
||||
BASS_FX_BFX_MIX, // Swap, remap and mix channels / multi channel
|
||||
BASS_FX_BFX_DAMP, // Dynamic Amplification / multi channel
|
||||
BASS_FX_BFX_AUTOWAH, // Auto Wah / multi channel
|
||||
BASS_FX_BFX_ECHO2, // Echo 2 / multi channel (deprecated)
|
||||
BASS_FX_BFX_PHASER, // Phaser / multi channel
|
||||
BASS_FX_BFX_ECHO3, // Echo 3 / multi channel (deprecated)
|
||||
BASS_FX_BFX_CHORUS, // Chorus/Flanger / multi channel
|
||||
BASS_FX_BFX_APF, // All Pass Filter / multi channel (deprecated)
|
||||
BASS_FX_BFX_COMPRESSOR, // Compressor / multi channel (deprecated)
|
||||
BASS_FX_BFX_DISTORTION, // Distortion / multi channel
|
||||
BASS_FX_BFX_COMPRESSOR2, // Compressor 2 / multi channel
|
||||
BASS_FX_BFX_VOLUME_ENV, // Volume envelope / multi channel
|
||||
BASS_FX_BFX_BQF, // BiQuad filters / multi channel
|
||||
BASS_FX_BFX_ECHO4, // Echo 4 / multi channel
|
||||
BASS_FX_BFX_PITCHSHIFT, // Pitch shift using FFT / multi channel (not available on mobile)
|
||||
BASS_FX_BFX_FREEVERB // Reverb using "Freeverb" algo / multi channel
|
||||
};
|
||||
|
||||
/*
|
||||
Deprecated effects in 2.4.10 version:
|
||||
------------------------------------
|
||||
BASS_FX_BFX_ECHO -> use BASS_FX_BFX_ECHO4
|
||||
BASS_FX_BFX_ECHO2 -> use BASS_FX_BFX_ECHO4
|
||||
BASS_FX_BFX_ECHO3 -> use BASS_FX_BFX_ECHO4
|
||||
BASS_FX_BFX_REVERB -> use BASS_FX_BFX_FREEVERB
|
||||
BASS_FX_BFX_FLANGER -> use BASS_FX_BFX_CHORUS
|
||||
BASS_FX_BFX_COMPRESSOR -> use BASS_FX_BFX_COMPRESSOR2
|
||||
BASS_FX_BFX_APF -> use BASS_FX_BFX_BQF with BASS_BFX_BQF_ALLPASS filter
|
||||
BASS_FX_BFX_LPF -> use 2x BASS_FX_BFX_BQF with BASS_BFX_BQF_LOWPASS filter and appropriate fQ values
|
||||
*/
|
||||
|
||||
// Rotate
|
||||
typedef struct {
|
||||
float fRate; // rotation rate/speed in Hz (A negative rate can be used for reverse direction)
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s (supported only even number of channels)
|
||||
} BASS_BFX_ROTATE;
|
||||
|
||||
// Echo (deprecated)
|
||||
typedef struct {
|
||||
float fLevel; // [0....1....n] linear
|
||||
int lDelay; // [1200..30000]
|
||||
} BASS_BFX_ECHO;
|
||||
|
||||
// Flanger (deprecated)
|
||||
typedef struct {
|
||||
float fWetDry; // [0....1....n] linear
|
||||
float fSpeed; // [0......0.09]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_FLANGER;
|
||||
|
||||
// Volume
|
||||
typedef struct {
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s or 0 for global volume control
|
||||
float fVolume; // [0....1....n] linear
|
||||
} BASS_BFX_VOLUME;
|
||||
|
||||
// Peaking Equalizer
|
||||
typedef struct {
|
||||
int lBand; // [0...............n] more bands means more memory & cpu usage
|
||||
float fBandwidth; // [0.1...........<10] in octaves - fQ is not in use (Bandwidth has a priority over fQ)
|
||||
float fQ; // [0...............1] the EE kinda definition (linear) (if Bandwidth is not in use)
|
||||
float fCenter; // [1Hz..<info.freq/2] in Hz
|
||||
float fGain; // [-15dB...0...+15dB] in dB (can be above/below these limits)
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_PEAKEQ;
|
||||
|
||||
// Reverb (deprecated)
|
||||
typedef struct {
|
||||
float fLevel; // [0....1....n] linear
|
||||
int lDelay; // [1200..10000]
|
||||
} BASS_BFX_REVERB;
|
||||
|
||||
// Low Pass Filter (deprecated)
|
||||
typedef struct {
|
||||
float fResonance; // [0.01...........10]
|
||||
float fCutOffFreq; // [1Hz...info.freq/2] cutoff frequency
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_LPF;
|
||||
|
||||
// Swap, remap and mix
|
||||
typedef struct {
|
||||
const int *lChannel; // an array of channels to mix using BASS_BFX_CHANxxx flag/s (lChannel[0] is left channel...)
|
||||
} BASS_BFX_MIX;
|
||||
|
||||
// Dynamic Amplification
|
||||
typedef struct {
|
||||
float fTarget; // target volume level [0<......1] linear
|
||||
float fQuiet; // quiet volume level [0.......1] linear
|
||||
float fRate; // amp adjustment rate [0.......1] linear
|
||||
float fGain; // amplification level [0...1...n] linear
|
||||
float fDelay; // delay in seconds before increasing level [0.......n] linear
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_DAMP;
|
||||
|
||||
// Auto Wah
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [-2......2]
|
||||
float fWetMix; // wet (affected) signal mix [-2......2]
|
||||
float fFeedback; // output signal to feed back into input [-1......1]
|
||||
float fRate; // rate of sweep in cycles per second [0<....<10]
|
||||
float fRange; // sweep range in octaves [0<....<10]
|
||||
float fFreq; // base frequency of sweep Hz [0<...1000]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_AUTOWAH;
|
||||
|
||||
// Echo 2 (deprecated)
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [-2......2]
|
||||
float fWetMix; // wet (affected) signal mix [-2......2]
|
||||
float fFeedback; // output signal to feed back into input [-1......1]
|
||||
float fDelay; // delay sec [0<......n]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_ECHO2;
|
||||
|
||||
// Phaser
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [-2......2]
|
||||
float fWetMix; // wet (affected) signal mix [-2......2]
|
||||
float fFeedback; // output signal to feed back into input [-1......1]
|
||||
float fRate; // rate of sweep in cycles per second [0<....<10]
|
||||
float fRange; // sweep range in octaves [0<....<10]
|
||||
float fFreq; // base frequency of sweep [0<...1000]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_PHASER;
|
||||
|
||||
// Echo 3 (deprecated)
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [-2......2]
|
||||
float fWetMix; // wet (affected) signal mix [-2......2]
|
||||
float fDelay; // delay sec [0<......n]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_ECHO3;
|
||||
|
||||
// Chorus/Flanger
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [-2......2]
|
||||
float fWetMix; // wet (affected) signal mix [-2......2]
|
||||
float fFeedback; // output signal to feed back into input [-1......1]
|
||||
float fMinSweep; // minimal delay ms [0<...6000]
|
||||
float fMaxSweep; // maximum delay ms [0<...6000]
|
||||
float fRate; // rate ms/s [0<...1000]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_CHORUS;
|
||||
|
||||
// All Pass Filter (deprecated)
|
||||
typedef struct {
|
||||
float fGain; // reverberation time [-1=<..<=1]
|
||||
float fDelay; // delay sec [0<....<=n]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_APF;
|
||||
|
||||
// Compressor (deprecated)
|
||||
typedef struct {
|
||||
float fThreshold; // compressor threshold [0<=...<=1]
|
||||
float fAttacktime; // attack time ms [0<.<=1000]
|
||||
float fReleasetime; // release time ms [0<.<=5000]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_COMPRESSOR;
|
||||
|
||||
// Distortion
|
||||
typedef struct {
|
||||
float fDrive; // distortion drive [0<=...<=5]
|
||||
float fDryMix; // dry (unaffected) signal mix [-5<=..<=5]
|
||||
float fWetMix; // wet (affected) signal mix [-5<=..<=5]
|
||||
float fFeedback; // output signal to feed back into input [-1<=..<=1]
|
||||
float fVolume; // distortion volume [0=<...<=2]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_DISTORTION;
|
||||
|
||||
// Compressor 2
|
||||
typedef struct {
|
||||
float fGain; // output gain of signal after compression [-60....60] in dB
|
||||
float fThreshold; // point at which compression begins [-60.....0] in dB
|
||||
float fRatio; // compression ratio [1.......n]
|
||||
float fAttack; // attack time in ms [0.01.1000]
|
||||
float fRelease; // release time in ms [0.01.5000]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_COMPRESSOR2;
|
||||
|
||||
// Volume envelope
|
||||
typedef struct {
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
int lNodeCount; // number of nodes
|
||||
const struct BASS_BFX_ENV_NODE *pNodes; // the nodes
|
||||
BOOL bFollow; // follow source position
|
||||
} BASS_BFX_VOLUME_ENV;
|
||||
|
||||
#pragma pack(push,4)
|
||||
typedef struct BASS_BFX_ENV_NODE {
|
||||
double pos; // node position in seconds (1st envelope node must be at position 0)
|
||||
float val; // node value
|
||||
} BASS_BFX_ENV_NODE;
|
||||
#pragma pack(pop)
|
||||
|
||||
// BiQuad Filters
|
||||
enum {
|
||||
BASS_BFX_BQF_LOWPASS,
|
||||
BASS_BFX_BQF_HIGHPASS,
|
||||
BASS_BFX_BQF_BANDPASS, // constant 0 dB peak gain
|
||||
BASS_BFX_BQF_BANDPASS_Q, // constant skirt gain, peak gain = Q
|
||||
BASS_BFX_BQF_NOTCH,
|
||||
BASS_BFX_BQF_ALLPASS,
|
||||
BASS_BFX_BQF_PEAKINGEQ,
|
||||
BASS_BFX_BQF_LOWSHELF,
|
||||
BASS_BFX_BQF_HIGHSHELF
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int lFilter; // BASS_BFX_BQF_xxx filter types
|
||||
float fCenter; // [1Hz..<info.freq/2] Cutoff (central) frequency in Hz
|
||||
float fGain; // [-15dB...0...+15dB] Used only for PEAKINGEQ and Shelving filters in dB (can be above/below these limits)
|
||||
float fBandwidth; // [0.1...........<10] Bandwidth in octaves (fQ is not in use (fBandwidth has a priority over fQ))
|
||||
// (between -3 dB frequencies for BANDPASS and NOTCH or between midpoint
|
||||
// (fGgain/2) gain frequencies for PEAKINGEQ)
|
||||
float fQ; // [0.1.............1] The EE kinda definition (linear) (if fBandwidth is not in use)
|
||||
float fS; // [0.1.............1] A "shelf slope" parameter (linear) (used only with Shelving filters)
|
||||
// when fS = 1, the shelf slope is as steep as you can get it and remain monotonically
|
||||
// increasing or decreasing gain with frequency.
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_BQF;
|
||||
|
||||
// Echo 4
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [-2.......2]
|
||||
float fWetMix; // wet (affected) signal mix [-2.......2]
|
||||
float fFeedback; // output signal to feed back into input [-1.......1]
|
||||
float fDelay; // delay sec [0<.......n]
|
||||
BOOL bStereo; // echo adjoining channels to each other [TRUE/FALSE]
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_ECHO4;
|
||||
|
||||
// Pitch shift (not available on mobile)
|
||||
typedef struct {
|
||||
float fPitchShift; // A factor value which is between 0.5 (one octave down) and 2 (one octave up) (1 won't change the pitch) [1 default]
|
||||
// (fSemitones is not in use, fPitchShift has a priority over fSemitones)
|
||||
float fSemitones; // Semitones (0 won't change the pitch) [0 default]
|
||||
long lFFTsize; // Defines the FFT frame size used for the processing. Typical values are 1024, 2048 and 4096 [2048 default]
|
||||
// It may be any value <= 8192 but it MUST be a power of 2
|
||||
long lOsamp; // Is the STFT oversampling factor which also determines the overlap between adjacent STFT frames [8 default]
|
||||
// It should at least be 4 for moderate scaling ratios. A value of 32 is recommended for best quality (better quality = higher CPU usage)
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_PITCHSHIFT;
|
||||
|
||||
// Freeverb
|
||||
#define BASS_BFX_FREEVERB_MODE_FREEZE 1
|
||||
|
||||
typedef struct {
|
||||
float fDryMix; // dry (unaffected) signal mix [0........1], def. 0
|
||||
float fWetMix; // wet (affected) signal mix [0........3], def. 1.0f
|
||||
float fRoomSize; // room size [0........1], def. 0.5f
|
||||
float fDamp; // damping [0........1], def. 0.5f
|
||||
float fWidth; // stereo width [0........1], def. 1
|
||||
DWORD lMode; // 0 or BASS_BFX_FREEVERB_MODE_FREEZE, def. 0 (no freeze)
|
||||
int lChannel; // BASS_BFX_CHANxxx flag/s
|
||||
} BASS_BFX_FREEVERB;
|
||||
|
||||
/*===========================================================================
|
||||
set dsp fx - BASS_ChannelSetFX
|
||||
remove dsp fx - BASS_ChannelRemoveFX
|
||||
set parameters - BASS_FXSetParameters
|
||||
retrieve parameters - BASS_FXGetParameters
|
||||
reset the state - BASS_FXReset
|
||||
===========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
Tempo, Pitch scaling and Sample rate changers
|
||||
===========================================================================*/
|
||||
|
||||
// NOTE: Enable Tempo supported flags in BASS_FX_TempoCreate and the others to source handle.
|
||||
|
||||
// tempo attributes (BASS_ChannelSet/GetAttribute)
|
||||
enum {
|
||||
BASS_ATTRIB_TEMPO = 0x10000,
|
||||
BASS_ATTRIB_TEMPO_PITCH,
|
||||
BASS_ATTRIB_TEMPO_FREQ
|
||||
};
|
||||
|
||||
// tempo attributes options
|
||||
enum {
|
||||
BASS_ATTRIB_TEMPO_OPTION_USE_AA_FILTER = 0x10010, // TRUE (default) / FALSE (default for multi-channel on mobile devices for lower CPU usage)
|
||||
BASS_ATTRIB_TEMPO_OPTION_AA_FILTER_LENGTH, // 32 default (8 .. 128 taps)
|
||||
BASS_ATTRIB_TEMPO_OPTION_USE_QUICKALGO, // TRUE (default on mobile devices for lower CPU usage) / FALSE (default)
|
||||
BASS_ATTRIB_TEMPO_OPTION_SEQUENCE_MS, // 82 default, 0 = automatic
|
||||
BASS_ATTRIB_TEMPO_OPTION_SEEKWINDOW_MS, // 28 default, 0 = automatic
|
||||
BASS_ATTRIB_TEMPO_OPTION_OVERLAP_MS, // 8 default
|
||||
BASS_ATTRIB_TEMPO_OPTION_PREVENT_CLICK // TRUE / FALSE (default)
|
||||
};
|
||||
|
||||
// tempo algorithm flags
|
||||
#define BASS_FX_TEMPO_ALGO_LINEAR 0x200
|
||||
#define BASS_FX_TEMPO_ALGO_CUBIC 0x400 // default
|
||||
#define BASS_FX_TEMPO_ALGO_SHANNON 0x800
|
||||
|
||||
HSTREAM BASS_FXDEF(BASS_FX_TempoCreate)(DWORD chan, DWORD flags);
|
||||
DWORD BASS_FXDEF(BASS_FX_TempoGetSource)(HSTREAM chan);
|
||||
float BASS_FXDEF(BASS_FX_TempoGetRateRatio)(HSTREAM chan);
|
||||
|
||||
/*===========================================================================
|
||||
Reverse playback
|
||||
===========================================================================*/
|
||||
|
||||
// NOTES: 1. MODs won't load without BASS_MUSIC_PRESCAN flag.
|
||||
// 2. Enable Reverse supported flags in BASS_FX_ReverseCreate and the others to source handle.
|
||||
|
||||
// reverse attribute (BASS_ChannelSet/GetAttribute)
|
||||
#define BASS_ATTRIB_REVERSE_DIR 0x11000
|
||||
|
||||
// playback directions
|
||||
#define BASS_FX_RVS_REVERSE -1
|
||||
#define BASS_FX_RVS_FORWARD 1
|
||||
|
||||
HSTREAM BASS_FXDEF(BASS_FX_ReverseCreate)(DWORD chan, float dec_block, DWORD flags);
|
||||
DWORD BASS_FXDEF(BASS_FX_ReverseGetSource)(HSTREAM chan);
|
||||
|
||||
/*===========================================================================
|
||||
BPM (Beats Per Minute)
|
||||
===========================================================================*/
|
||||
|
||||
// bpm flags
|
||||
#define BASS_FX_BPM_BKGRND 1 // if in use, then you can do other processing while detection's in progress. Available only in Windows platforms (BPM/Beat)
|
||||
#define BASS_FX_BPM_MULT2 2 // if in use, then will auto multiply bpm by 2 (if BPM < minBPM*2)
|
||||
|
||||
// translation options (deprecated)
|
||||
enum {
|
||||
BASS_FX_BPM_TRAN_X2, // multiply the original BPM value by 2 (may be called only once & will change the original BPM as well!)
|
||||
BASS_FX_BPM_TRAN_2FREQ, // BPM value to Frequency
|
||||
BASS_FX_BPM_TRAN_FREQ2, // Frequency to BPM value
|
||||
BASS_FX_BPM_TRAN_2PERCENT, // BPM value to Percents
|
||||
BASS_FX_BPM_TRAN_PERCENT2 // Percents to BPM value
|
||||
};
|
||||
|
||||
typedef void (CALLBACK BPMPROC)(DWORD chan, float bpm, void *user);
|
||||
typedef void (CALLBACK BPMPROGRESSPROC)(DWORD chan, float percent, void *user);
|
||||
typedef BPMPROGRESSPROC BPMPROCESSPROC; // back-compatibility
|
||||
|
||||
float BASS_FXDEF(BASS_FX_BPM_DecodeGet)(DWORD chan, double startSec, double endSec, DWORD minMaxBPM, DWORD flags, BPMPROGRESSPROC *proc, void *user);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_CallbackSet)(DWORD handle, BPMPROC *proc, double period, DWORD minMaxBPM, DWORD flags, void *user);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_CallbackReset)(DWORD handle);
|
||||
float BASS_FXDEF(BASS_FX_BPM_Translate)(DWORD handle, float val2tran, DWORD trans); // deprecated
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_Free)(DWORD handle);
|
||||
|
||||
/*===========================================================================
|
||||
Beat position trigger
|
||||
===========================================================================*/
|
||||
|
||||
typedef void (CALLBACK BPMBEATPROC)(DWORD chan, double beatpos, void *user);
|
||||
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_BeatCallbackSet)(DWORD handle, BPMBEATPROC *proc, void *user);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_BeatCallbackReset)(DWORD handle);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_BeatDecodeGet)(DWORD chan, double startSec, double endSec, DWORD flags, BPMBEATPROC *proc, void *user);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_BeatSetParameters)(DWORD handle, float bandwidth, float centerfreq, float beat_rtime);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_BeatGetParameters)(DWORD handle, float *bandwidth, float *centerfreq, float *beat_rtime);
|
||||
BOOL BASS_FXDEF(BASS_FX_BPM_BeatFree)(DWORD handle);
|
||||
|
||||
/*===========================================================================
|
||||
Macros
|
||||
===========================================================================*/
|
||||
|
||||
// translate linear level to logarithmic dB
|
||||
#define BASS_BFX_Linear2dB(level) (20*log10(level))
|
||||
|
||||
// translate logarithmic dB level to linear
|
||||
#define BASS_BFX_dB2Linear(dB) pow(10,(dB)/20)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
BIN
lib/bass/bass.dll
Normal file
BIN
lib/bass/bass.dll
Normal file
Binary file not shown.
BIN
lib/bass/bass.dylib
Normal file
BIN
lib/bass/bass.dylib
Normal file
Binary file not shown.
BIN
lib/bass/bass_fx.dll
Normal file
BIN
lib/bass/bass_fx.dll
Normal file
Binary file not shown.
BIN
lib/bass/bass_fx.dylib
Normal file
BIN
lib/bass/bass_fx.dylib
Normal file
Binary file not shown.
BIN
lib/bass/libbass.dylib
Normal file
BIN
lib/bass/libbass.dylib
Normal file
Binary file not shown.
BIN
lib/bass/libbass.so
Normal file
BIN
lib/bass/libbass.so
Normal file
Binary file not shown.
BIN
lib/bass/libbass_fx.dylib
Normal file
BIN
lib/bass/libbass_fx.dylib
Normal file
Binary file not shown.
BIN
lib/bass/libbass_fx.so
Normal file
BIN
lib/bass/libbass_fx.so
Normal file
Binary file not shown.
BIN
lib/bass/x86/bass.dll
Normal file
BIN
lib/bass/x86/bass.dll
Normal file
Binary file not shown.
BIN
lib/bass/x86/bass_fx.dll
Normal file
BIN
lib/bass/x86/bass_fx.dll
Normal file
Binary file not shown.
68
mods/audio-test/main.lua
Normal file
68
mods/audio-test/main.lua
Normal file
|
@ -0,0 +1,68 @@
|
|||
-- name: Audio Test
|
||||
-- description: audio shits.
|
||||
-- incompatible:
|
||||
|
||||
DEBUG = false
|
||||
UNST22 = true -- gotta work around unst 22 bugs :(
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
handle = 0;
|
||||
s_handle = 0;
|
||||
|
||||
function on_audio_play(msg)
|
||||
if(msg == "create") then
|
||||
handle = load_audio("test.mp3")
|
||||
|
||||
djui_chat_message_create("audio handle:" .. tostring(handle));
|
||||
end
|
||||
|
||||
if(msg == "play") then
|
||||
play_audio(handle, true);
|
||||
djui_chat_message_create("playing audio");
|
||||
end
|
||||
|
||||
if(msg == "resume") then
|
||||
play_audio(handle, false);
|
||||
djui_chat_message_create("resuming audio");
|
||||
end
|
||||
|
||||
if(msg == "pause") then
|
||||
pause_audio(handle);
|
||||
djui_chat_message_create("pausing audio");
|
||||
end
|
||||
|
||||
if(msg == "stop") then
|
||||
stop_audio(handle);
|
||||
djui_chat_message_create("stopping audio");
|
||||
end
|
||||
|
||||
if(msg == "destroy") then
|
||||
destroy_audio(handle);
|
||||
djui_chat_message_create("destroyed audio");
|
||||
end
|
||||
|
||||
if(msg == "getpos") then
|
||||
djui_chat_message_create("pos: " .. tostring(get_position_audio(handle)));
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
function on_sample_play(msg)
|
||||
if(msg == "create") then
|
||||
s_handle = load_sample("test.mp3");
|
||||
|
||||
djui_chat_message_create("audio handle:" .. tostring(s_handle));
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
handle2 = get_audio_from_sample(s_handle);
|
||||
|
||||
play_audio(handle2, false);
|
||||
return true;
|
||||
end
|
||||
|
||||
hook_chat_command('audio', "options and shit", on_audio_play)
|
||||
hook_chat_command('sample', "options and shit", on_sample_play)
|
BIN
mods/audio-test/sound/test.mp3
Executable file
BIN
mods/audio-test/sound/test.mp3
Executable file
Binary file not shown.
131
src/bass_audio/bass_audio_helpers.c
Normal file
131
src/bass_audio/bass_audio_helpers.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include "include/bass/bass.h"
|
||||
#include "include/bass/bass_fx.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#include "bass_audio_helpers.h"
|
||||
|
||||
HSTREAM bassh_create_fx_stream_from_file(char* data, QWORD length, QWORD offset) {
|
||||
HSTREAM raw_stream = BASS_StreamCreateFile(TRUE, data, offset, length, BASS_STREAM_PRESCAN | BASS_STREAM_DECODE);
|
||||
|
||||
HSTREAM stream = BASS_FX_TempoCreate(raw_stream, BASS_STREAM_PRESCAN);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
HSAMPLE bassh_create_sample_from_file(char* data, QWORD length, QWORD offset) {
|
||||
return BASS_SampleLoad(TRUE, data, offset, length, MAX_SAMPLE_CONCURRENT_PLAYBACKS, BASS_SAMPLE_OVER_POS);
|
||||
}
|
||||
|
||||
HSTREAM bassh_sample_get_stream(HSAMPLE sample) {
|
||||
return BASS_SampleGetChannel(sample, 0);
|
||||
}
|
||||
|
||||
void bassh_free_sample(HSAMPLE sample) {
|
||||
BASS_SampleFree(sample);
|
||||
}
|
||||
|
||||
void bassh_set_looping(HSTREAM stream, BOOL loop) {
|
||||
BASS_ChannelFlags(stream, loop == TRUE ? 0 : BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP);
|
||||
}
|
||||
|
||||
BOOL bassh_get_looping(HSTREAM stream) {
|
||||
return (BASS_ChannelFlags(stream, 0, 0) & BASS_SAMPLE_LOOP) > 0;
|
||||
}
|
||||
|
||||
void bassh_set_frequency(HSTREAM stream, float frequency) {
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_FREQ, frequency);
|
||||
}
|
||||
|
||||
float bassh_get_frequency(HSTREAM stream) {
|
||||
float val;
|
||||
BASS_ChannelGetAttribute(stream, BASS_ATTRIB_FREQ, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void bassh_set_tempo(HSTREAM stream, float tempo) {
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_TEMPO, tempo);
|
||||
}
|
||||
|
||||
float bassh_get_tempo(HSTREAM stream) {
|
||||
float val;
|
||||
BASS_ChannelGetAttribute(stream, BASS_ATTRIB_TEMPO, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
double bassh_get_stream_pos(HSTREAM stream) {
|
||||
DWORD pos_b = BASS_ChannelGetPosition(stream, BASS_POS_BYTE);
|
||||
return BASS_ChannelBytes2Seconds(stream, pos_b);
|
||||
}
|
||||
|
||||
void bassh_set_stream_pos(HSTREAM stream, double pos) {
|
||||
BASS_ChannelSetPosition(stream, BASS_ChannelSeconds2Bytes(stream, pos), BASS_POS_BYTE);
|
||||
}
|
||||
|
||||
void bassh_set_speed(HSTREAM stream, float initial_freq, float speed, BOOL pitch) {
|
||||
if (pitch) {
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_FREQ, initial_freq * speed);
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_TEMPO, 0);
|
||||
}
|
||||
else {
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_FREQ, initial_freq);
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_TEMPO, speed * 100 - 100);
|
||||
}
|
||||
}
|
||||
|
||||
void bassh_set_stream_volume(HSTREAM stream, float volume) {
|
||||
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_MUSIC_VOL_CHAN, volume);
|
||||
}
|
||||
|
||||
float bassh_get_stream_volume(HSTREAM stream) {
|
||||
float volume;
|
||||
|
||||
BASS_ChannelGetAttribute(stream, BASS_ATTRIB_MUSIC_VOL_CHAN, &volume);
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
void bassh_play_stream(HSTREAM stream, BOOL restart) {
|
||||
BASS_ChannelPlay(stream, restart);
|
||||
}
|
||||
|
||||
void bassh_pause_stream(HSTREAM stream) {
|
||||
BASS_ChannelPause(stream);
|
||||
}
|
||||
|
||||
void bassh_stop_stream(HSTREAM stream) {
|
||||
BASS_ChannelStop(stream);
|
||||
}
|
||||
|
||||
void bassh_free_stream(HSTREAM stream) {
|
||||
BASS_ChannelFree(stream);
|
||||
}
|
||||
|
||||
void bassh_init() {
|
||||
BOOL success = BASS_Init(-1, 44100, 0, 0, 0);
|
||||
|
||||
if(success == FALSE) {
|
||||
//error handling? fucking nerd shit
|
||||
LOG_ERROR("Bass init failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
BASS_DEVICEINFO info;
|
||||
BASS_GetDeviceInfo(BASS_GetDevice(), &info);
|
||||
|
||||
LOG_INFO("Bass Initialized on device: %s, with driver: %s", info.name, info.driver);
|
||||
}
|
||||
|
||||
void bassh_deinit() {
|
||||
BASS_Free();
|
||||
}
|
||||
|
||||
int bassh_device_count() {
|
||||
int count = 0;
|
||||
|
||||
BASS_DEVICEINFO info;
|
||||
for(count = 0; BASS_GetDeviceInfo(count, &info); count++) {}
|
||||
|
||||
return count;
|
||||
}
|
34
src/bass_audio/bass_audio_helpers.h
Normal file
34
src/bass_audio/bass_audio_helpers.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "include/bass/bass.h"
|
||||
|
||||
#define MAX_SAMPLE_CONCURRENT_PLAYBACKS 32
|
||||
|
||||
HSTREAM bassh_create_fx_stream_from_file(char* data, QWORD length, QWORD offset);
|
||||
HSAMPLE bassh_create_sample_from_file(char* data, QWORD length, QWORD offset);
|
||||
|
||||
HSTREAM bassh_sample_get_stream(HSAMPLE sample);
|
||||
void bassh_free_sample(HSAMPLE sample);
|
||||
void bassh_set_looping(HSTREAM stream, BOOL loop);
|
||||
|
||||
void bassh_set_stream_volume(HSTREAM stream, float volume);
|
||||
float bassh_get_stream_volume(HSTREAM stream);
|
||||
void bassh_set_looping(HSTREAM stream, BOOL loop);
|
||||
BOOL bassh_get_looping(HSTREAM stream);
|
||||
void bassh_set_frequency(HSTREAM stream, float frequency);
|
||||
float bassh_get_frequency(HSTREAM stream);
|
||||
void bassh_set_tempo(HSTREAM stream, float tempo);
|
||||
float bassh_get_tempo(HSTREAM stream);
|
||||
|
||||
void bassh_set_speed(HSTREAM stream, float initial_freq, float speed, BOOL pitch);
|
||||
|
||||
double bassh_get_stream_pos(HSTREAM stream);
|
||||
void bassh_set_stream_pos(HSTREAM stream, double pos);
|
||||
|
||||
void bassh_play_stream(HSTREAM stream, BOOL restart);
|
||||
void bassh_pause_stream(HSTREAM stream);
|
||||
void bassh_stop_stream(HSTREAM stream);
|
||||
void bassh_free_stream(HSTREAM stream);
|
||||
|
||||
int bassh_device_count();
|
||||
|
||||
void bassh_init();
|
||||
void bassh_deinit();
|
|
@ -14707,6 +14707,39 @@ int smlua_func_deref_s32_pointer(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_destroy_audio(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
u32 audio_stream = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
destroy_audio(audio_stream);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_destroy_sample(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
u32 audio_stream = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
destroy_sample(audio_stream);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_audio_from_sample(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
u32 sample = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
lua_pushinteger(L, get_audio_from_sample(sample));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_current_save_file_num(UNUSED lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
||||
|
||||
|
@ -14727,6 +14760,17 @@ int smlua_func_get_environment_region(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_frequency_audio(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
u32 audio_stream = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
lua_pushnumber(L, get_frequency_audio(audio_stream));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_hand_foot_pos_x(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||
|
||||
|
@ -14766,6 +14810,17 @@ int smlua_func_get_hand_foot_pos_z(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_looping_audio(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
u32 audio_stream = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
lua_pushboolean(L, get_looping_audio(audio_stream));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_network_area_timer(UNUSED lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
||||
|
||||
|
@ -14775,6 +14830,17 @@ int smlua_func_get_network_area_timer(UNUSED lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_position_audio(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
u32 audio_stream = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
lua_pushnumber(L, get_position_audio(audio_stream));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_temp_s32_pointer(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
|
@ -14847,6 +14913,28 @@ int smlua_func_hud_show(UNUSED lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_load_audio(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
const char* file_name = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
lua_pushinteger(L, load_audio(file_name));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_load_sample(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
const char* file_name = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
lua_pushinteger(L, load_sample(file_name));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_movtexqc_register(lua_State* L) {
|
||||
if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
|
||||
|
||||
|
@ -17164,18 +17252,26 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "camera_freeze", smlua_func_camera_freeze);
|
||||
smlua_bind_function(L, "camera_unfreeze", smlua_func_camera_unfreeze);
|
||||
smlua_bind_function(L, "deref_s32_pointer", smlua_func_deref_s32_pointer);
|
||||
smlua_bind_function(L, "destroy_audio", smlua_func_destroy_audio);
|
||||
smlua_bind_function(L, "destroy_sample", smlua_func_destroy_sample);
|
||||
smlua_bind_function(L, "get_audio_from_sample", smlua_func_get_audio_from_sample);
|
||||
smlua_bind_function(L, "get_current_save_file_num", smlua_func_get_current_save_file_num);
|
||||
smlua_bind_function(L, "get_environment_region", smlua_func_get_environment_region);
|
||||
smlua_bind_function(L, "get_frequency_audio", smlua_func_get_frequency_audio);
|
||||
smlua_bind_function(L, "get_hand_foot_pos_x", smlua_func_get_hand_foot_pos_x);
|
||||
smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y);
|
||||
smlua_bind_function(L, "get_hand_foot_pos_z", smlua_func_get_hand_foot_pos_z);
|
||||
smlua_bind_function(L, "get_looping_audio", smlua_func_get_looping_audio);
|
||||
smlua_bind_function(L, "get_network_area_timer", smlua_func_get_network_area_timer);
|
||||
smlua_bind_function(L, "get_position_audio", smlua_func_get_position_audio);
|
||||
smlua_bind_function(L, "get_temp_s32_pointer", smlua_func_get_temp_s32_pointer);
|
||||
smlua_bind_function(L, "hud_get_value", smlua_func_hud_get_value);
|
||||
smlua_bind_function(L, "hud_hide", smlua_func_hud_hide);
|
||||
smlua_bind_function(L, "hud_render_power_meter", smlua_func_hud_render_power_meter);
|
||||
smlua_bind_function(L, "hud_set_value", smlua_func_hud_set_value);
|
||||
smlua_bind_function(L, "hud_show", smlua_func_hud_show);
|
||||
smlua_bind_function(L, "load_audio", smlua_func_load_audio);
|
||||
smlua_bind_function(L, "load_sample", smlua_func_load_sample);
|
||||
smlua_bind_function(L, "movtexqc_register", smlua_func_movtexqc_register);
|
||||
smlua_bind_function(L, "play_transition", smlua_func_play_transition);
|
||||
smlua_bind_function(L, "save_file_set_using_backup_slot", smlua_func_save_file_set_using_backup_slot);
|
||||
|
|
|
@ -7,11 +7,17 @@
|
|||
#include "pc/lua/smlua.h"
|
||||
#include "smlua_misc_utils.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/mods/mod.h"
|
||||
#include "pc/mods/mods.h"
|
||||
#include "pc/mods/mods_utils.h"
|
||||
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/rendering_graph_node.h"
|
||||
#include "game/level_update.h"
|
||||
#include "pc/djui/djui_hud_utils.h"
|
||||
|
||||
#include "src/bass_audio/bass_audio_helpers.h"
|
||||
|
||||
u32 get_network_area_timer(void) {
|
||||
return gNetworkAreaTimer;
|
||||
}
|
||||
|
@ -175,12 +181,212 @@ f32 get_environment_region(u8 index) {
|
|||
return -11000;
|
||||
}
|
||||
|
||||
u32 load_audio(const char* file_name) {
|
||||
u16 fileCount = gLuaActiveMod->fileCount;
|
||||
BOOL found = FALSE;
|
||||
struct ModFile* file;
|
||||
for(u16 i = 0; i < fileCount; i++) {
|
||||
LOG_INFO("file path %s", gLuaActiveMod->files[i].relativePath);
|
||||
if(str_ends_with(gLuaActiveMod->files[i].relativePath, (char *)file_name)) {
|
||||
// char fullPath[SYS_MAX_PATH] = { 0 };
|
||||
// mod_file_full_path(fullPath, gLuaActiveMod, &(gLuaActiveMod->files[i]));
|
||||
|
||||
file = &gLuaActiveMod->files[i];
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(found == FALSE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//smh free your stuff first...
|
||||
if(file->audio_stream != 0) {
|
||||
LOG_LUA("You need to destroy your stream/sapmle!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rewind(file->fp); //seek to the start of the file
|
||||
|
||||
//Allocate a buffer to the data
|
||||
file->data_ptr = (char *)malloc(file->size * sizeof(char));
|
||||
//Read the file data into the buffer
|
||||
fread(file->data_ptr, file->size, 1, file->fp);
|
||||
|
||||
file->audio_stream = bassh_create_fx_stream_from_file(file->data_ptr, file->size, 0);
|
||||
|
||||
return file->audio_stream;
|
||||
|
||||
// return bassh_create_fx_stream_from_file();
|
||||
}
|
||||
|
||||
void destroy_audio(u32 audio_stream) {
|
||||
u16 fileCount = gLuaActiveMod->fileCount;
|
||||
BOOL found = FALSE;
|
||||
struct ModFile* file;
|
||||
for(u16 i = 0; i < fileCount; i++) {
|
||||
if(audio_stream == gLuaActiveMod->files[i].audio_stream) {
|
||||
// char fullPath[SYS_MAX_PATH] = { 0 };
|
||||
// mod_file_full_path(fullPath, gLuaActiveMod, &(gLuaActiveMod->files[i]));
|
||||
|
||||
file = &gLuaActiveMod->files[i];
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(found == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(file->audio_stream == 0) {
|
||||
LOG_LUA("You cant double destroy audio!");
|
||||
return;
|
||||
}
|
||||
|
||||
//This frees the stream
|
||||
bassh_free_stream(audio_stream);
|
||||
|
||||
file->audio_stream = 0;
|
||||
|
||||
//This frees the data the stream uses
|
||||
free(file->data_ptr);
|
||||
}
|
||||
|
||||
void play_audio(u32 audio_stream, bool restart) {
|
||||
bassh_play_stream(audio_stream, restart);
|
||||
}
|
||||
|
||||
void pause_audio(u32 audio_stream) {
|
||||
bassh_pause_stream(audio_stream);
|
||||
}
|
||||
|
||||
void stop_audio(u32 audio_stream) {
|
||||
bassh_stop_stream(audio_stream);
|
||||
}
|
||||
|
||||
f32 get_position_audio(u32 audio_stream) {
|
||||
return (f32)bassh_get_stream_pos(audio_stream);
|
||||
}
|
||||
|
||||
void set_looping_audio(u32 audio_stream, bool looping) {
|
||||
bassh_set_looping(audio_stream, looping);
|
||||
}
|
||||
|
||||
bool get_looping_audio(u32 audio_stream) {
|
||||
return bassh_get_looping(audio_stream);
|
||||
}
|
||||
|
||||
f32 get_frequency_audio(u32 audio_stream) {
|
||||
return bassh_get_frequency(audio_stream);
|
||||
}
|
||||
|
||||
void set_frequency_audio(u32 audio_stream, f32 freq) {
|
||||
bassh_set_frequency(audio_stream, freq);
|
||||
}
|
||||
|
||||
f32 get_tempo_audio(u32 audio_stream) {
|
||||
return bassh_get_tempo(audio_stream);
|
||||
}
|
||||
|
||||
void set_tempo_audio(u32 audio_stream, f32 tempo) {
|
||||
bassh_set_tempo(audio_stream, tempo);
|
||||
}
|
||||
|
||||
void set_speed_audio(u32 audio_stream, f32 initial_freq, f32 speed, bool pitch) {
|
||||
bassh_set_speed(audio_stream, initial_freq, speed, pitch);
|
||||
}
|
||||
|
||||
void set_volume_audio(u32 audio_stream, f32 volume) {
|
||||
bassh_set_stream_volume(audio_stream, volume);
|
||||
}
|
||||
|
||||
f32 get_volume_audio(u32 audio_stream) {
|
||||
return bassh_get_stream_volume(audio_stream);
|
||||
}
|
||||
|
||||
void set_position_audio(u32 audio_stream, f32 pos) {
|
||||
bassh_set_stream_pos(audio_stream, (double)pos);
|
||||
}
|
||||
|
||||
void set_environment_region(u8 index, s32 value) {
|
||||
if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) {
|
||||
gEnvironmentRegions[6 * (int)index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
u32 load_sample(const char* file_name) {
|
||||
u16 fileCount = gLuaActiveMod->fileCount;
|
||||
BOOL found = FALSE;
|
||||
struct ModFile* file;
|
||||
for(u16 i = 0; i < fileCount; i++) {
|
||||
LOG_INFO("file path %s", gLuaActiveMod->files[i].relativePath);
|
||||
if(str_ends_with(gLuaActiveMod->files[i].relativePath, (char *)file_name)) {
|
||||
// char fullPath[SYS_MAX_PATH] = { 0 };
|
||||
// mod_file_full_path(fullPath, gLuaActiveMod, &(gLuaActiveMod->files[i]));
|
||||
|
||||
file = &gLuaActiveMod->files[i];
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(found == FALSE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//smh free your stuff first...
|
||||
if(file->audio_stream != 0) {
|
||||
LOG_LUA("You need to destroy your stream/sapmle!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rewind(file->fp); //seek to the start of the file
|
||||
|
||||
//Allocate a buffer to the data
|
||||
file->data_ptr = (char *)malloc(file->size * sizeof(char));
|
||||
//Read the file data into the buffer
|
||||
fread(file->data_ptr, file->size, 1, file->fp);
|
||||
|
||||
file->audio_stream = bassh_create_sample_from_file(file->data_ptr, file->size, 0);
|
||||
|
||||
return file->audio_stream;
|
||||
}
|
||||
|
||||
void destroy_sample(u32 audio_stream) {
|
||||
u16 fileCount = gLuaActiveMod->fileCount;
|
||||
BOOL found = FALSE;
|
||||
struct ModFile* file;
|
||||
for(u16 i = 0; i < fileCount; i++) {
|
||||
if(audio_stream == gLuaActiveMod->files[i].audio_stream) {
|
||||
// char fullPath[SYS_MAX_PATH] = { 0 };
|
||||
// mod_file_full_path(fullPath, gLuaActiveMod, &(gLuaActiveMod->files[i]));
|
||||
|
||||
file = &gLuaActiveMod->files[i];
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(found == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(file->audio_stream == 0) {
|
||||
LOG_LUA("You cant double destroy audio!");
|
||||
return;
|
||||
}
|
||||
|
||||
//This frees the stream
|
||||
bassh_free_sample(audio_stream);
|
||||
|
||||
file->audio_stream = 0;
|
||||
|
||||
//This frees the data the stream uses
|
||||
free(file->data_ptr);
|
||||
}
|
||||
|
||||
u32 get_audio_from_sample(u32 sample) {
|
||||
return bassh_sample_get_stream(sample);
|
||||
}
|
||||
|
||||
f32 set_override_fov(f32 fov) {
|
||||
gOverrideFOV = fov;
|
||||
}
|
||||
|
@ -191,4 +397,4 @@ f32 set_override_near(f32 near) {
|
|||
|
||||
f32 set_override_far(f32 far) {
|
||||
gOverrideFar = far;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,33 @@ void movtexqc_register(const char* name, s16 level, s16 area, s16 type);
|
|||
f32 get_environment_region(u8 index);
|
||||
void set_environment_region(u8 index, s32 value);
|
||||
|
||||
u32 load_audio(const char* file_name);
|
||||
u32 load_sample(const char* file_name);
|
||||
void destroy_audio(u32 audio_stream);
|
||||
void destroy_sample(u32 audio_stream);
|
||||
|
||||
u32 get_audio_from_sample(u32 sample);
|
||||
|
||||
void play_audio(u32 audio_stream, bool restart);
|
||||
void pause_audio(u32 audio_stream);
|
||||
void stop_audio(u32 audio_stream);
|
||||
|
||||
f32 get_position_audio(u32 audio_stream);
|
||||
void set_position_audio(u32 audio_stream, f32 pos);
|
||||
|
||||
bool get_looping_audio(u32 audio_stream);
|
||||
void set_looping_audio(u32 audio_stream, bool looping);
|
||||
|
||||
f32 get_frequency_audio(u32 audio_stream);
|
||||
void set_frequency_audio(u32 audio_stream, f32 freq);
|
||||
f32 get_tempo_audio(u32 audio_stream);
|
||||
void set_tempo_audio(u32 audio_stream, f32 tempo);
|
||||
|
||||
void set_volume_audio(u32 audio_stream, f32 volume);
|
||||
f32 get_volume_audio(u32 audio_stream);
|
||||
|
||||
void set_speed_audio(u32 audio_stream, f32 initial_freq, f32 speed, bool pitch);
|
||||
|
||||
f32 set_override_fov(f32 fov);
|
||||
f32 set_override_near(f32 near);
|
||||
f32 set_override_far(f32 far);
|
||||
|
|
|
@ -248,6 +248,7 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
|||
// open actors directory
|
||||
struct dirent* dir = NULL;
|
||||
DIR* d = opendir(actorsPath);
|
||||
|
||||
if (d) {
|
||||
// iterate mod directory
|
||||
char path[SYS_MAX_PATH] = { 0 };
|
||||
|
@ -260,14 +261,16 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// only consider bin, and col files
|
||||
// only consider bin and col files
|
||||
if (!str_ends_with(path, ".bin") && !str_ends_with(path, ".col")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate file
|
||||
struct ModFile* file = mod_allocate_file(mod, relativePath);
|
||||
if (file == NULL) { return false; }
|
||||
if (file == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
@ -374,11 +377,6 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// only consider m64 files
|
||||
if (!str_ends_with(path, ".m64")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate file
|
||||
struct ModFile* file = mod_allocate_file(mod, relativePath);
|
||||
if (file == NULL) { return false; }
|
||||
|
|
|
@ -15,6 +15,9 @@ struct ModFile {
|
|||
u64 curOffset;
|
||||
bool complete;
|
||||
|
||||
//A pointer to a char array of data with size: (ModFile.size * sizeof(char))
|
||||
char* data_ptr;
|
||||
u32 audio_stream;
|
||||
u8 dataHash[16];
|
||||
char* cachedPath;
|
||||
};
|
||||
|
|
|
@ -42,12 +42,17 @@
|
|||
#include "game/main.h"
|
||||
#include "game/rumble_init.h"
|
||||
|
||||
#include "include/bass/bass.h"
|
||||
#include "include/bass/bass_fx.h"
|
||||
#include "src/bass_audio/bass_audio_helpers.h"
|
||||
|
||||
#ifdef DISCORDRPC
|
||||
#include "pc/discord/discordrpc.h"
|
||||
#endif
|
||||
#include "pc/network/version.h"
|
||||
#include "pc/network/network_player.h"
|
||||
#include "pc/djui/djui.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
#include "pc/mods/mods.h"
|
||||
|
@ -388,6 +393,7 @@ void main_func(void) {
|
|||
|
||||
audio_init();
|
||||
sound_init();
|
||||
bassh_init();
|
||||
network_player_init();
|
||||
|
||||
thread5_game_loop(NULL);
|
||||
|
@ -422,6 +428,8 @@ void main_func(void) {
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
bassh_deinit();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
|
BIN
test.mp3
Executable file
BIN
test.mp3
Executable file
Binary file not shown.
BIN
test_echo.mp3
Normal file
BIN
test_echo.mp3
Normal file
Binary file not shown.
Loading…
Reference in a new issue