diff options
author | Wohlstand <admin@wohlnet.ru> | 2023-03-19 15:29:47 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2023-03-19 15:29:47 +0300 |
commit | deed64ed4732d09a92f5e286982c903101d1dafb (patch) | |
tree | d016d52e490cafd955053df45fe47701ad01c006 /examples | |
parent | 0d8ad03297bec4c8ee1f83944003265a2c765bca (diff) | |
download | libADLMIDI-deed64ed4732d09a92f5e286982c903101d1dafb.tar.gz libADLMIDI-deed64ed4732d09a92f5e286982c903101d1dafb.tar.bz2 libADLMIDI-deed64ed4732d09a92f5e286982c903101d1dafb.zip |
Added SDL2 Mixer example over Mix_HookMusic()
Diffstat (limited to 'examples')
-rw-r--r-- | examples/sdl2_mixer/CMakeLists.txt | 48 | ||||
-rw-r--r-- | examples/sdl2_mixer/sdl2_mixer_example.c | 172 |
2 files changed, 220 insertions, 0 deletions
diff --git a/examples/sdl2_mixer/CMakeLists.txt b/examples/sdl2_mixer/CMakeLists.txt new file mode 100644 index 0000000..caaa4ca --- /dev/null +++ b/examples/sdl2_mixer/CMakeLists.txt @@ -0,0 +1,48 @@ +if(POLICY CMP0111) + cmake_policy(SET CMP0111 NEW) +endif() + +find_package(SDL2 REQUIRED) +find_package(SDL2_MIXER REQUIRED) + +add_library(ADLMIDIEXAMPLE_SDL2 INTERFACE) + +if(TARGET SDL2_mixer::SDL2_mixer) + target_include_directories(ADLMIDIEXAMPLE_SDL2 INTERFACE ${SDL2_MIXER_INCLUDE_DIRS}) +else() + string(STRIP ${SDL2_MIXER_LIBRARIES} SDL2_MIXER_LIBRARIES) + target_include_directories(ADLMIDIEXAMPLE_SDL2 INTERFACE ${SDL2_MIXER_INCLUDE_DIRS}) + target_link_libraries(ADLMIDIEXAMPLE_SDL2 INTERFACE ${SDL2_MIXER_LIBRARIES}) +endif() + +if(TARGET SDL2::SDL2) + if(MINGW) + target_link_libraries(ADLMIDIEXAMPLE_SDL2 INTERFACE mingw32 SDL2::SDL2main SDL2::SDL2) + else() + target_link_libraries(ADLMIDIEXAMPLE_SDL2 INTERFACE SDL2::SDL2) + endif() + target_include_directories(ADLMIDIEXAMPLE_SDL2 INTERFACE ${SDL2_INCLUDE_DIRS}) +else() + string(STRIP ${SDL2_LIBRARIES} SDL2_LIBRARIES) + target_include_directories(ADLMIDIEXAMPLE_SDL2 INTERFACE ${SDL2_INCLUDE_DIRS}) + target_link_libraries(ADLMIDIEXAMPLE_SDL2 INTERFACE ${SDL2_LIBRARIES}) +endif() + +add_executable(adlmidi_sdl2_mixer_demo sdl2_mixer_example.c) +target_link_libraries(adlmidi_sdl2_mixer_demo PRIVATE ADLMIDI ADLMIDIEXAMPLE_SDL2) + +set_nopie(adlmidi_sdl2_mixer_demo) + +if(NOT MSVC) + target_link_libraries(adlmidi_sdl2_mixer_demo PRIVATE pthread) +endif() +if(NOT WIN32) + target_link_libraries(adlmidi_sdl2_mixer_demo PRIVATE dl m) +endif() + +if(TARGET ADLMIDI_shared) + set_target_properties(adlmidi_sdl2_mixer_demo PROPERTIES INSTALL_RPATH "$ORIGIN/../lib") +endif() + +install(TARGETS adlmidi_sdl2_mixer_demo + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") diff --git a/examples/sdl2_mixer/sdl2_mixer_example.c b/examples/sdl2_mixer/sdl2_mixer_example.c new file mode 100644 index 0000000..4a57307 --- /dev/null +++ b/examples/sdl2_mixer/sdl2_mixer_example.c @@ -0,0 +1,172 @@ +#include <stdio.h> +#include <signal.h> +#include <SDL2/SDL.h> +#include <SDL2/SDL_mixer.h> + +#include <adlmidi.h> + +/* prototype for our audio callback */ +/* see the implementation for more information */ +void my_audio_callback(void *midi_player, Uint8 *stream, int len); + +/* variable declarations */ +static Uint32 is_playing = 0; /* remaining length of the sample we have to play */ + +static struct ADLMIDI_AudioFormat s_audioFormat; + +static void stop_playing(int sig) +{ + (void)sig; + is_playing = 0; +} + +int main(int argc, char *argv[]) +{ + /* local variables */ + static Uint16 obtained_format; /* Format of the audio device */ + static struct ADL_MIDIPlayer *midi_player = NULL; /* Instance of ADLMIDI player */ + static const char *music_path = NULL; /* Path to music file */ + + signal(SIGINT, stop_playing); + signal(SIGTERM, stop_playing); + + if (argc < 2) + { + fprintf(stderr, "\n" + "\n" + "No given files to play!\n" + "\n" + "Syntax: %s <path-to-MIDI-file>\n" + "\n", argv[0]); + return 2; + } + + music_path = argv[1]; + + /* Initialize SDL.*/ + if(SDL_Init(SDL_INIT_AUDIO) < 0) + return 1; + + /* Initialize ADLMIDI */ + midi_player = adl_init(44100); + if (!midi_player) + { + fprintf(stderr, "Couldn't initialize ADLMIDI: %s\n", adl_errorString()); + return 1; + } + + adl_switchEmulator(midi_player, ADLMIDI_EMU_NUKED); + + /* Open the audio device */ + if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048) < 0) + { + fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); + return 1; + } + + /* set the callback function */ + /* set ADLMIDI's descriptor as userdata to use it for sound generation */ + Mix_HookMusic(my_audio_callback, midi_player); + + Mix_QuerySpec(NULL, &obtained_format, NULL); + + switch(obtained_format) + { + case AUDIO_S8: + s_audioFormat.type = ADLMIDI_SampleType_S8; + s_audioFormat.containerSize = sizeof(int8_t); + s_audioFormat.sampleOffset = sizeof(int8_t) * 2; + break; + case AUDIO_U8: + s_audioFormat.type = ADLMIDI_SampleType_U8; + s_audioFormat.containerSize = sizeof(uint8_t); + s_audioFormat.sampleOffset = sizeof(uint8_t) * 2; + break; + case AUDIO_S16: + s_audioFormat.type = ADLMIDI_SampleType_S16; + s_audioFormat.containerSize = sizeof(int16_t); + s_audioFormat.sampleOffset = sizeof(int16_t) * 2; + break; + case AUDIO_U16: + s_audioFormat.type = ADLMIDI_SampleType_U16; + s_audioFormat.containerSize = sizeof(uint16_t); + s_audioFormat.sampleOffset = sizeof(uint16_t) * 2; + break; + case AUDIO_S32: + s_audioFormat.type = ADLMIDI_SampleType_S32; + s_audioFormat.containerSize = sizeof(int32_t); + s_audioFormat.sampleOffset = sizeof(int32_t) * 2; + break; + case AUDIO_F32: + s_audioFormat.type = ADLMIDI_SampleType_F32; + s_audioFormat.containerSize = sizeof(float); + s_audioFormat.sampleOffset = sizeof(float) * 2; + break; + } + + /* Optionally Setup ADLMIDI as you want */ + + adl_setNumChips(midi_player, 1); + + /* Set using of embedded bank by ID */ + /*adl_setBank(midi_player, 68);*/ + + /* Set using of custom bank (WOPL format) loaded from a file */ + /*adl_openBankFile(midi_player, "/home/vitaly/Yandex.Disk/Музыка/Wolfinstein.wopl");*/ + + /* Open the MIDI (or MUS, IMF or CMF) file to play */ + if (adl_openFile(midi_player, music_path) < 0) + { + fprintf(stderr, "Couldn't open music file: %s\n", adl_errorInfo(midi_player)); + SDL_CloseAudio(); + adl_close(midi_player); + return 1; + } + + is_playing = 1; + /* Start playing */ + SDL_PauseAudio(0); + + printf("Playing... Hit Ctrl+C to quit!\n"); + + /* wait until we're don't playing */ + while (is_playing) + { + SDL_Delay(100); + } + + /* shut everything down */ + SDL_CloseAudio(); + adl_close(midi_player); + + return 0; +} + +/* + audio callback function + here you have to copy the data of your audio buffer into the + requesting audio buffer (stream) + you should only copy as much as the requested length (len) +*/ +void my_audio_callback(void *midi_player, Uint8 *stream, int len) +{ + if (!is_playing) + return; + + struct ADL_MIDIPlayer* p = (struct ADL_MIDIPlayer*)midi_player; + + /* Convert bytes length into total count of samples in all channels */ + int samples_count = len / s_audioFormat.containerSize; + + /* Take some samples from the ADLMIDI */ + samples_count = adl_playFormat(p, samples_count, + stream, + stream + s_audioFormat.containerSize, + &s_audioFormat); + + if(samples_count <= 0) + { + is_playing = 0; + SDL_memset(stream, 0, len); + } +} |