/* * ADLMIDI Player is a free MIDI player based on a libADLMIDI, * a Software MIDI synthesizer library with OPL3 emulation * * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma * ADLMIDI Library API: Copyright (c) 2015-2025 Vitaly Novichkov * * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * http://iki.fi/bisqwit/source/adlmidi.html * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "audio.h" #define SDL_MAIN_HANDLED #include int audio_init(struct AudioOutputSpec *in_spec, struct AudioOutputSpec *out_obtained, AudioOutputCallback callback) { SDL_AudioSpec spec; SDL_AudioSpec obtained; int ret; spec.format = AUDIO_S16SYS; spec.freq = (int)in_spec->freq; spec.samples = in_spec->samples; spec.channels = in_spec->channels; spec.callback = callback; switch(in_spec->format) { case ADLMIDI_SampleType_S8: spec.format = AUDIO_S8; break; case ADLMIDI_SampleType_U8: spec.format = AUDIO_U8; break; case ADLMIDI_SampleType_S16: #if SDL_BYTEORDER == SDL_LIL_ENDIAN spec.format = AUDIO_S16; #else spec.format = AUDIO_S16MSB; #endif break; case ADLMIDI_SampleType_U16: #if SDL_BYTEORDER == SDL_LIL_ENDIAN spec.format = AUDIO_U16; #else spec.format = AUDIO_U16MSB; #endif break; case ADLMIDI_SampleType_S32: #if SDL_BYTEORDER == SDL_LIL_ENDIAN spec.format = AUDIO_S32; #else spec.format = AUDIO_S32MSB; #endif break; case ADLMIDI_SampleType_F32: #if SDL_BYTEORDER == SDL_LIL_ENDIAN spec.format = AUDIO_F32; #else spec.format = AUDIO_F32MSB; #endif break; } ret = SDL_OpenAudio(&spec, &obtained); out_obtained->channels = obtained.channels; out_obtained->freq = (unsigned int)obtained.freq; out_obtained->samples = obtained.samples; out_obtained->format = in_spec->format; out_obtained->is_msb = 0; switch(obtained.format) { case AUDIO_S8: out_obtained->format = ADLMIDI_SampleType_S8; break; case AUDIO_U8: out_obtained->format = ADLMIDI_SampleType_U8; break; case AUDIO_S16MSB: out_obtained->is_msb = 1;/* fallthrough */ case AUDIO_S16: out_obtained->format = ADLMIDI_SampleType_S16; break; case AUDIO_U16MSB: out_obtained->is_msb = 1;/* fallthrough */ case AUDIO_U16: out_obtained->format = ADLMIDI_SampleType_U16; break; case AUDIO_S32MSB: out_obtained->is_msb = 1;/* fallthrough */ case AUDIO_S32: out_obtained->format = ADLMIDI_SampleType_S32; break; case AUDIO_F32MSB: out_obtained->is_msb = 1;/* fallthrough */ case AUDIO_F32: out_obtained->format = ADLMIDI_SampleType_F32; break; } return ret; } void audio_close(void) { SDL_CloseAudio(); } const char* audio_get_error(void) { return SDL_GetError(); } void audio_start(void) { SDL_PauseAudio(0); } void audio_stop(void) { SDL_PauseAudio(1); } void audio_lock(void) { SDL_LockAudio(); } void audio_unlock(void) { SDL_UnlockAudio(); } void audio_delay(unsigned int ms) { SDL_Delay(ms); } void* audio_mutex_create(void) { return SDL_CreateMutex(); } void audio_mutex_destroy(void *m) { SDL_mutex *mut = (SDL_mutex *)m; SDL_DestroyMutex(mut); } void audio_mutex_lock(void *m) { SDL_mutex *mut = (SDL_mutex *)m; SDL_mutexP(mut); } void audio_mutex_unlock(void *m) { SDL_mutex *mut = (SDL_mutex *)m; SDL_mutexV(mut); }