Added usage examples in C; Added asm include file with track info to sointu-compile.

This commit is contained in:
Alexander Kraus 2023-08-28 22:19:40 +02:00 committed by Veikko Sariola
parent dff484739c
commit d0efcc3001
11 changed files with 407 additions and 11 deletions

View File

@ -99,11 +99,11 @@ add_library(${STATICLIB} ${sointuasm})
set_target_properties(${STATICLIB} PROPERTIES LINKER_LANGUAGE C) set_target_properties(${STATICLIB} PROPERTIES LINKER_LANGUAGE C)
target_include_directories(${STATICLIB} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(${STATICLIB} INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
# We should put examples here # Examples are now available.
# add_subdirectory(examples) add_subdirectory(examples)
# Testing only available if this is the main app # Testing only available if this is the main app
# Emergency override 4KLANG_CMAKE_BUILD_TESTING provided as well # Emergency override 4KLANG_CMAKE_BUILD_TESTING provided as well
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SOINTU_CMAKE_BUILD_TESTING) AND BUILD_TESTING) if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SOINTU_CMAKE_BUILD_TESTING) AND BUILD_TESTING)
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()

View File

@ -165,6 +165,11 @@ sointu-compile -o . -arch=wasm tests/test_chords.yml
wat2wasm --enable-bulk-memory test_chords.wat wat2wasm --enable-bulk-memory test_chords.wat
``` ```
#### Examples
The folder `examples/code` contains usage examples in C. If you want to target smaller executable sizes, using a compressing linker
like [Crinkler](https://github.com/runestubbe/Crinkler) on Windows is recommended.
### Native virtual machine ### Native virtual machine
The native bridge allows Go to call the sointu compiled x86 native The native bridge allows Go to call the sointu compiled x86 native

1
examples/CMakeLists.txt Normal file
View File

@ -0,0 +1 @@
add_subdirectory(code)

View File

@ -0,0 +1,34 @@
add_custom_command(
COMMAND
${compilecmd} -arch=${arch} -o physics_girl_st.asm "${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml"
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
"${PROJECT_SOURCE_DIR}/examples/patches/physics_girl_st.yml"
OUTPUT
physics_girl_st.asm
physics_girl_st.h
physics_girl_st.inc
COMMENT
"Compiling ${PROJECT_SOURCE_DIR}/examples/patches/physics-girl-st.yml..."
)
add_library(physics_girl_st physics_girl_st.asm)
add_dependencies(physics_girl_st sointu-compiler)
if(WIN32)
add_executable(cplay
cplay.windows.c
physics_girl_st.h
)
target_link_libraries(cplay PRIVATE winmm)
elseif(UNIX)
add_executable(cplay
cplay.unix.c
physics_girl_st.h
)
target_link_libraries(cplay PRIVATE asound pthread)
target_link_options(cplay PRIVATE -z noexecstack -no-pie)
endif()
target_link_libraries(cplay PRIVATE physics_girl_st)
target_include_directories(cplay PRIVATE ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -0,0 +1,27 @@
#include <alsa/asoundlib.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include "physics_girl_st.h"
static SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
static snd_pcm_t *pcm_handle;
static pthread_t render_thread;
static uint32_t render_thread_handle;
int main(int argc, char **args) {
// Unix does not have gm.dls, no need to ifdef and setup here.
// We render in the background while playing already.
render_thread_handle = pthread_create(&render_thread, 0, (void * (*)(void *))su_render_song, sound_buffer);
// We can't start playing too early or the missing samples will be audible.
sleep(2.);
// Play the track.
snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
snd_pcm_set_params(pcm_handle, SND_PCM_FORMAT_FLOAT, SND_PCM_ACCESS_RW_INTERLEAVED, SU_CHANNEL_COUNT, SU_SAMPLE_RATE, 0, SU_LENGTH_IN_SAMPLES);
snd_pcm_writei(pcm_handle, sound_buffer, SU_LENGTH_IN_SAMPLES);
return 0;
}

View File

@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdint.h>
#include "physics_girl_st.h"
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <Windows.h>
#include "mmsystem.h"
#include "mmreg.h"
SUsample sound_buffer[SU_LENGTH_IN_SAMPLES * SU_CHANNEL_COUNT];
HWAVEOUT wave_out_handle;
WAVEFORMATEX WaveFMT = {
#ifdef SU_SAMPLE_FLOAT
WAVE_FORMAT_IEEE_FLOAT,
#else
WAVE_FORMAT_PCM,
#endif
SU_CHANNEL_COUNT,
SU_SAMPLE_RATE,
SU_SAMPLE_RATE * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
SU_SAMPLE_SIZE*8,
0
};
WAVEHDR WaveHDR = {
(LPSTR)sound_buffer,
SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT,
0,
0,
WHDR_PREPARED,
0,
0,
0
};
MMTIME MMTime = {
TIME_SAMPLES,
0
};
int main(int argc, char **args) {
// Load gm.dls if necessary.
#ifdef SU_LOAD_GMDLS
su_load_gmdls();
#endif // SU_LOAD_GMDLS
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)su_render_song, sound_buffer, 0, 0);
// We render in the background while playing already. Fortunately,
// Windows is slow with the calls below, so we're not worried that
// we don't have enough samples ready before the track starts.
waveOutOpen(&wave_out_handle, WAVE_MAPPER, &WaveFMT, 0, 0, CALLBACK_NULL);
waveOutWrite(wave_out_handle, &WaveHDR, sizeof(WaveHDR));
// We need to handle windows messages properly while playing, as waveOutWrite is async.
for(MSG msg = {0}; MMTime.u.sample != SU_LENGTH_IN_SAMPLES; waveOutGetPosition(wave_out_handle, &MMTime, sizeof(MMTIME))) {
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
}
return 0;
}

View File

@ -0,0 +1 @@
add_subdirectory(C)

View File

@ -0,0 +1,213 @@
bpm: 130
rowsperbeat: 4
score:
tracks:
- numvoices: 2
order: [0, 1, 2, 1, 2, 1, 3, 1, 0, 1, 2, 1, 2, 1, 3, 1, 0, 1, 2, 1, 2, 1, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 1, 3, 1, -1, -1, -1]
patterns: [[83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
- numvoices: 2
order: [0, 1, 0, 1, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 2, 1, 2, 1, -1, -1, -1]
patterns: [[79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
- numvoices: 1
order: [0, 1, 2, 1, 2, 1, 3, 1, 0, 1, 2, 1, 2, 1, 3, 1, 0, 1, 2, 1, 2, 1, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 1, 3, 1, -1, -1, -1]
patterns: [[76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
- numvoices: 2
order: [0, -1, 1, -1, 2, -1, 3, -1, 4, 5, 6, 7, 8, 9, 10, 11, 0, -1, 1, -1, 2, -1, 3, -1, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
patterns: [[47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [61, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [59, 1, 71, 1, 59, 1, 71, 1, 59, 1, 71, 1, 59, 1, 71, 1], [59, 1, 74, 1, 59, 1, 71, 1, 59, 1, 73, 1, 59, 1, 71, 1], [52, 1, 64, 1, 52, 1, 64, 1, 52, 1, 64, 1, 52, 1, 64, 1], [52, 1, 66, 1, 52, 1, 64, 1, 52, 1, 67, 1, 52, 1, 64, 1], [61, 1, 73, 1, 61, 1, 73, 1, 61, 1, 73, 1, 61, 1, 73, 1], [61, 1, 74, 1, 61, 1, 73, 1, 61, 1, 76, 1, 61, 1, 73, 1], [57, 1, 69, 1, 57, 1, 69, 1, 57, 1, 69, 1, 57, 1, 69, 1], [57, 1, 69, 1, 70, 1, 69, 1, 57, 1, 69, 1, 71, 1, 73, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
- numvoices: 2
order: [0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, -1, -1, -1, -1, 5, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
patterns: [[59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [49, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 57, 1, 0, 1, 1, 1, 1, 1, 57, 1, 0, 1]]
- numvoices: 1
order: [-1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, -1, -1]
patterns: [[52, 1, 1, 1, 0, 1, 1, 1, 52, 1, 1, 1, 0, 1, 1, 1], [52, 1, 1, 1, 0, 1, 1, 1, 1, 1, 52, 1, 53, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
- numvoices: 7
order: [-1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
patterns: [[1, 1, 1, 1, 45, 1, 1, 1, 0, 1, 1, 1, 45, 1, 1, 1], [0, 1, 1, 1, 45, 1, 1, 1, 0, 1, 1, 1, 45, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
- numvoices: 2
order: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
patterns: [[76, 79, 83, 88, 91, 88, 83, 79, 83, 79, 76, 71, 76, 79, 83, 79], [76, 71, 76, 79, 83, 79, 83, 91, 88, 91, 88, 83, 79, 76, 79, 76], [72, 76, 79, 81, 84, 81, 79, 76, 72, 71, 72, 76, 72, 76, 79, 81], [84, 88, 91, 88, 84, 88, 84, 81, 79, 76, 79, 76, 72, 76, 79, 76], [78, 76, 78, 81, 78, 76, 73, 69, 64, 69, 64, 69, 73, 76, 73, 76], [78, 81, 83, 81, 83, 85, 88, 93, 88, 85, 88, 85, 83, 81, 78, 76], [74, 78, 81, 86, 90, 86, 81, 78, 81, 78, 74, 69, 66, 62, 66, 69], [66, 69, 74, 78, 74, 78, 81, 78, 81, 86, 81, 78, 74, 69, 74, 78], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
rowsperpattern: 16
length: 43
patch:
- name: ambient_pad3
numvoices: 5
units:
- type: envelope
id: 12
parameters: {attack: 80, decay: 24, gain: 87, release: 83, stereo: 0, sustain: 128}
- type: send
id: 13
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 10, unit: 0, voice: 0}
- type: envelope
id: 1
parameters: {attack: 57, decay: 0, gain: 32, release: 88, stereo: 0, sustain: 62}
- type: oscillator
id: 2
parameters: {color: 62, detune: 68, gain: 64, phase: 14, shape: 59, stereo: 0, transpose: 64, type: 2, unison: 3}
- type: mulp
id: 3
parameters: {stereo: 0}
- type: filter
id: 10
parameters: {bandpass: 0, frequency: 0, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 58, stereo: 0}
- type: delay
id: 4
parameters: {damp: 0, dry: 128, feedback: 96, notetracking: 2, pregain: 40, stereo: 0}
varargs: [48]
- type: pan
id: 5
parameters: {panning: 64, stereo: 0}
- type: delay
id: 32
parameters: {damp: 0, dry: 37, feedback: 41, notetracking: 2, pregain: 26, stereo: 1}
varargs: [52]
- type: outaux
id: 6
parameters: {auxgain: 64, outgain: 64, stereo: 1}
- name: bass_kewl23
numvoices: 4
units:
- type: envelope
id: 29
parameters: {attack: 15, decay: 12, gain: 128, release: 87, stereo: 0, sustain: 29}
- type: send
id: 30
parameters: {amount: 128, port: 4, sendpop: 1, stereo: 0, target: 23, unit: 0, voice: 0}
- type: oscillator
id: 46
parameters: {color: 64, detune: 64, gain: 66, lfo: 1, phase: 23, shape: 67, stereo: 0, transpose: 41, type: 0, unison: 0}
- type: send
id: 47
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 31, unit: 0, voice: 0}
- type: envelope
id: 22
parameters: {attack: 27, decay: 15, gain: 14, release: 72, stereo: 0, sustain: 128}
- type: oscillator
id: 23
parameters: {color: 59, detune: 73, gain: 35, phase: 26, shape: 70, stereo: 0, transpose: 57, type: 2, unison: 3}
- type: filter
id: 31
parameters: {bandpass: 0, frequency: 37, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 60, stereo: 0}
- type: mulp
id: 24
parameters: {stereo: 0}
- type: pan
id: 28
parameters: {panning: 64, stereo: 0}
- type: distort
id: 33
parameters: {drive: 107, stereo: 1}
- type: outaux
id: 27
parameters: {auxgain: 64, outgain: 64, stereo: 1}
- name: kiq
numvoices: 1
units:
- type: envelope
id: 66
parameters: {attack: 0, decay: 64, gain: 64, release: 0, stereo: 0, sustain: 0}
- type: send
id: 67
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 35, unit: 0, voice: 0}
- type: envelope
id: 34
parameters: {attack: 36, decay: 64, gain: 128, release: 0, stereo: 0, sustain: 0}
- type: oscillator
id: 35
parameters: {color: 64, detune: 64, gain: 124, lfo: 0, phase: 0, shape: 84, stereo: 0, transpose: 10, type: 1, unison: 3}
- type: mulp
id: 36
parameters: {stereo: 0}
- type: envelope
id: 44
parameters: {attack: 33, decay: 59, gain: 128, release: 61, stereo: 0, sustain: 42}
- type: oscillator
id: 42
parameters: {color: 127, detune: 64, gain: 128, phase: 0, shape: 73, stereo: 0, transpose: 64, type: 0, unison: 3}
- type: mulp
id: 43
parameters: {stereo: 0}
- type: mulp
id: 45
parameters: {stereo: 0}
- type: pan
id: 38
parameters: {panning: 64, stereo: 0}
- type: gain
id: 41
parameters: {gain: 128, stereo: 1}
- type: outaux
id: 39
parameters: {auxgain: 64, outgain: 64, stereo: 1}
- name: Sner
numvoices: 7
units:
- type: envelope
id: 59
parameters: {attack: 4, decay: 53, gain: 64, release: 0, stereo: 0, sustain: 0}
- type: send
id: 60
parameters: {amount: 112, port: 0, sendpop: 1, stereo: 0, target: 56, unit: 0, voice: 0}
- type: envelope
id: 48
parameters: {attack: 0, decay: 62, gain: 78, release: 0, stereo: 0, sustain: 0}
- type: oscillator
id: 56
parameters: {color: 64, detune: 68, gain: 64, phase: 0, shape: 60, stereo: 0, transpose: 62, type: 0, unison: 0}
- type: mulp
id: 58
parameters: {stereo: 0}
- type: envelope
id: 64
parameters: {attack: 10, decay: 63, gain: 64, release: 0, stereo: 0, sustain: 0}
- type: noise
id: 61
parameters: {gain: 64, shape: 64, stereo: 0}
- type: mulp
id: 65
parameters: {stereo: 0}
- type: addp
id: 63
parameters: {stereo: 0}
- type: pan
id: 52
parameters: {panning: 64, stereo: 0}
- type: outaux
id: 53
parameters: {auxgain: 64, outgain: 64, stereo: 1}
- name: Arp
numvoices: 2
units:
- type: envelope
id: 74
parameters: {attack: 15, decay: 69, gain: 65, release: 29, stereo: 0, sustain: 0}
- type: send
id: 75
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 76, unit: 0, voice: 0}
- type: envelope
id: 68
parameters: {attack: 18, decay: 35, gain: 37, release: 68, stereo: 0, sustain: 128}
- type: oscillator
id: 69
parameters: {color: 128, detune: 97, gain: 57, lfo: 0, phase: 0, shape: 55, stereo: 0, transpose: 64, type: 1, unison: 3}
- type: mulp
id: 70
parameters: {stereo: 0}
- type: pan
id: 72
parameters: {panning: 64, stereo: 0}
- type: filter
id: 76
parameters: {bandpass: 0, frequency: 32, highpass: 0, lowpass: 1, negbandpass: 0, neghighpass: 0, resonance: 64, stereo: 1}
- type: outaux
id: 73
parameters: {auxgain: 64, outgain: 64, stereo: 1}
- name: Global
numvoices: 1
units:
- type: in
id: 7
parameters: {channel: 2, stereo: 1}
- type: out
id: 9
parameters: {gain: 28, stereo: 1}

View File

@ -81,7 +81,7 @@ func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) {
} }
var templates []string var templates []string
if com.Arch == "386" || com.Arch == "amd64" { if com.Arch == "386" || com.Arch == "amd64" {
templates = []string{"player.asm", "player.h"} templates = []string{"player.asm", "player.h", "player.inc"}
} else if com.Arch == "wasm" { } else if com.Arch == "wasm" {
templates = []string{"player.wat"} templates = []string{"player.wat"}
} }

View File

@ -2,8 +2,9 @@
#ifndef SU_RENDER_H #ifndef SU_RENDER_H
#define SU_RENDER_H #define SU_RENDER_H
#define SU_CHANNEL_COUNT 2
#define SU_LENGTH_IN_SAMPLES {{.MaxSamples}} #define SU_LENGTH_IN_SAMPLES {{.MaxSamples}}
#define SU_BUFFER_LENGTH (SU_LENGTH_IN_SAMPLES*2) #define SU_BUFFER_LENGTH (SU_LENGTH_IN_SAMPLES*SU_CHANNEL_COUNT)
#define SU_SAMPLE_RATE 44100 #define SU_SAMPLE_RATE 44100
#define SU_BPM {{.Song.BPM}} #define SU_BPM {{.Song.BPM}}
@ -24,23 +25,25 @@
#include <stdint.h> #include <stdint.h>
#if UINTPTR_MAX == 0xffffffff #if UINTPTR_MAX == 0xffffffff
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define SU_CALLCONV __attribute__ ((stdcall)) #define SU_CALLCONV __attribute__ ((stdcall))
#elif defined(_WIN32) #elif defined(_WIN32)
#define SU_CALLCONV __stdcall #define SU_CALLCONV __stdcall
#endif #endif
#else #else
#define SU_CALLCONV #define SU_CALLCONV
#endif #endif
{{- if .Output16Bit}} {{- if .Output16Bit}}
typedef short SUsample; typedef short SUsample;
#define SU_SAMPLE_RANGE 32767.0 #define SU_SAMPLE_RANGE 32767.0
#define SU_SAMPLE_PCM16 #define SU_SAMPLE_PCM16
#define SU_SAMPLE_SIZE 2
{{- else}} {{- else}}
typedef float SUsample; typedef float SUsample;
#define SU_SAMPLE_RANGE 1.0 #define SU_SAMPLE_RANGE 1.0
#define SU_SAMPLE_FLOAT #define SU_SAMPLE_FLOAT
#define SU_SAMPLE_SIZE 4
{{- end}} {{- end}}

View File

@ -0,0 +1,49 @@
; auto-generated by Sointu, editing not recommended
%ifndef PLAYER_INC
%define PLAYER_INC
%define SU_CHANNEL_COUNT 2
%define SU_LENGTH_IN_SAMPLES {{.MaxSamples}}
%define SU_BUFFER_LENGTH (SU_LENGTH_IN_SAMPLES*SU_CHANNEL_COUNT)
%define SU_SAMPLE_RATE 44100
%define SU_BPM {{.Song.BPM}}
%define SU_ROWS_PER_BEAT {{.Song.RowsPerBeat}}
%define SU_ROWS_PER_PATTERN {{.Song.Score.RowsPerPattern}}
%define SU_LENGTH_IN_PATTERNS {{.Song.Score.Length}}
%define SU_LENGTH_IN_ROWS (SU_LENGTH_IN_PATTERNS*SU_PATTERN_SIZE)
%define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*60/(SU_BPM*SU_ROWS_PER_BEAT))
{{- if or .RowSync (.HasOp "sync")}}
{{- if .RowSync}}
%define SU_NUMSYNCS {{add1 .Song.Patch.NumSyncs}}
{{- else}}
%define SU_NUMSYNCS {{.Song.Patch.NumSyncs}}
{{- end}}
%define SU_SYNCBUFFER_LENGTH ((SU_LENGTH_IN_SAMPLES+255)>>8)*SU_NUMSYNCS
{{- end}}
{{- if .Output16Bit}}
%define SU_SAMPLE_SIZE 2
%define SU_SAMPLE_RANGE 32767.0
%define SU_SAMPLE_PCM16
{{- else}}
%define SU_SAMPLE_SIZE 4
%define SU_SAMPLE_RANGE 1.0
%define SU_SAMPLE_FLOAT
{{- end}}
{{- if or .RowSync (.HasOp "sync")}}
%define SU_SYNC
{{- end}}
section _su_symbols text
_su_symbols:
extern _su_render_song@4
{{- if gt (.SampleOffsets | len) 0}}
extern _su_load_gmdls
%define SU_LOAD_GMDLS
{{- end}}
%endif ; PLAYER_INC