From d0efcc3001aac0f893736f4f418a31e1accef787 Mon Sep 17 00:00:00 2001 From: Alexander Kraus Date: Mon, 28 Aug 2023 22:19:40 +0200 Subject: [PATCH] Added usage examples in C; Added asm include file with track info to sointu-compile. --- CMakeLists.txt | 6 +- README.md | 5 + examples/CMakeLists.txt | 1 + examples/code/C/CMakeLists.txt | 34 ++++ examples/code/C/cplay.unix.c | 27 +++ examples/code/C/cplay.windows.c | 63 ++++++ examples/code/CMakeLists.txt | 1 + examples/patches/physics_girl_st.yml | 213 +++++++++++++++++++++ vm/compiler/compiler.go | 2 +- vm/compiler/templates/amd64-386/player.h | 17 +- vm/compiler/templates/amd64-386/player.inc | 49 +++++ 11 files changed, 407 insertions(+), 11 deletions(-) create mode 100644 examples/CMakeLists.txt create mode 100644 examples/code/C/CMakeLists.txt create mode 100644 examples/code/C/cplay.unix.c create mode 100644 examples/code/C/cplay.windows.c create mode 100644 examples/code/CMakeLists.txt create mode 100644 examples/patches/physics_girl_st.yml create mode 100644 vm/compiler/templates/amd64-386/player.inc diff --git a/CMakeLists.txt b/CMakeLists.txt index 89e094d..7426528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,11 +99,11 @@ add_library(${STATICLIB} ${sointuasm}) set_target_properties(${STATICLIB} PROPERTIES LINKER_LANGUAGE C) target_include_directories(${STATICLIB} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) -# We should put examples here -# add_subdirectory(examples) +# Examples are now available. +add_subdirectory(examples) # Testing only available if this is the main app # Emergency override 4KLANG_CMAKE_BUILD_TESTING provided as well if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SOINTU_CMAKE_BUILD_TESTING) AND BUILD_TESTING) add_subdirectory(tests) -endif() \ No newline at end of file +endif() diff --git a/README.md b/README.md index 2da549c..bb023dc 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,11 @@ sointu-compile -o . -arch=wasm tests/test_chords.yml 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 The native bridge allows Go to call the sointu compiled x86 native diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..9c71105 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(code) diff --git a/examples/code/C/CMakeLists.txt b/examples/code/C/CMakeLists.txt new file mode 100644 index 0000000..812815b --- /dev/null +++ b/examples/code/C/CMakeLists.txt @@ -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}) diff --git a/examples/code/C/cplay.unix.c b/examples/code/C/cplay.unix.c new file mode 100644 index 0000000..a181fe3 --- /dev/null +++ b/examples/code/C/cplay.unix.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#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; +} diff --git a/examples/code/C/cplay.windows.c b/examples/code/C/cplay.windows.c new file mode 100644 index 0000000..1a59fa8 --- /dev/null +++ b/examples/code/C/cplay.windows.c @@ -0,0 +1,63 @@ +#include +#include +#include "physics_girl_st.h" +#define WIN32_LEAN_AND_MEAN +#define WIN32_EXTRA_LEAN +#include +#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; +} diff --git a/examples/code/CMakeLists.txt b/examples/code/CMakeLists.txt new file mode 100644 index 0000000..5446ca3 --- /dev/null +++ b/examples/code/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(C) diff --git a/examples/patches/physics_girl_st.yml b/examples/patches/physics_girl_st.yml new file mode 100644 index 0000000..b5d4d66 --- /dev/null +++ b/examples/patches/physics_girl_st.yml @@ -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} \ No newline at end of file diff --git a/vm/compiler/compiler.go b/vm/compiler/compiler.go index 87bf3a9..93c4b3e 100644 --- a/vm/compiler/compiler.go +++ b/vm/compiler/compiler.go @@ -81,7 +81,7 @@ func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) { } var templates []string 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" { templates = []string{"player.wat"} } diff --git a/vm/compiler/templates/amd64-386/player.h b/vm/compiler/templates/amd64-386/player.h index c1b2c16..35de63f 100644 --- a/vm/compiler/templates/amd64-386/player.h +++ b/vm/compiler/templates/amd64-386/player.h @@ -2,8 +2,9 @@ #ifndef SU_RENDER_H #define SU_RENDER_H +#define SU_CHANNEL_COUNT 2 #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_BPM {{.Song.BPM}} @@ -24,23 +25,25 @@ #include #if UINTPTR_MAX == 0xffffffff - #if defined(__clang__) || defined(__GNUC__) - #define SU_CALLCONV __attribute__ ((stdcall)) - #elif defined(_WIN32) - #define SU_CALLCONV __stdcall - #endif + #if defined(__clang__) || defined(__GNUC__) + #define SU_CALLCONV __attribute__ ((stdcall)) + #elif defined(_WIN32) + #define SU_CALLCONV __stdcall + #endif #else - #define SU_CALLCONV + #define SU_CALLCONV #endif {{- if .Output16Bit}} typedef short SUsample; #define SU_SAMPLE_RANGE 32767.0 #define SU_SAMPLE_PCM16 +#define SU_SAMPLE_SIZE 2 {{- else}} typedef float SUsample; #define SU_SAMPLE_RANGE 1.0 #define SU_SAMPLE_FLOAT +#define SU_SAMPLE_SIZE 4 {{- end}} diff --git a/vm/compiler/templates/amd64-386/player.inc b/vm/compiler/templates/amd64-386/player.inc new file mode 100644 index 0000000..7d52bdd --- /dev/null +++ b/vm/compiler/templates/amd64-386/player.inc @@ -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