mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-04-07 16:21:18 +00:00
Merge branch '2.0.x' into master
This commit is contained in:
commit
1e7a5f594d
8 changed files with 153 additions and 167 deletions
|
@ -29,7 +29,7 @@ set ( PACKAGE "fluidsynth" )
|
|||
# FluidSynth package version
|
||||
set ( FLUIDSYNTH_VERSION_MAJOR 2 )
|
||||
set ( FLUIDSYNTH_VERSION_MINOR 0 )
|
||||
set ( FLUIDSYNTH_VERSION_MICRO 5 )
|
||||
set ( FLUIDSYNTH_VERSION_MICRO 6 )
|
||||
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
|
||||
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
|
||||
|
||||
|
@ -44,7 +44,7 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
|
|||
# This is not exactly the same algorithm as the libtool one, but the results are the same.
|
||||
set ( LIB_VERSION_CURRENT 2 )
|
||||
set ( LIB_VERSION_AGE 1 )
|
||||
set ( LIB_VERSION_REVISION 2 )
|
||||
set ( LIB_VERSION_REVISION 3 )
|
||||
set ( LIB_VERSION_INFO
|
||||
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = libfluidsynth
|
||||
PROJECT_NUMBER = 2.0.5
|
||||
PROJECT_NUMBER = 2.0.6
|
||||
OUTPUT_DIRECTORY = api
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
\author David Henningsson
|
||||
\author Tom Moebert
|
||||
\author Copyright © 2003-2019 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert
|
||||
\version Revision 2.0.5
|
||||
\date 2019-04-17
|
||||
\version Revision 2.0.6
|
||||
\date 2019-08-17
|
||||
|
||||
All the source code examples in this document are in the public domain; you can use them as you please. This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ . The FluidSynth library is distributed under the GNU Lesser General Public License. A copy of the GNU Lesser General Public License is contained in the FluidSynth package; if not, visit http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
|
@ -21,6 +21,7 @@ All the source code examples in this document are in the public domain; you can
|
|||
|
||||
- \ref Disclaimer
|
||||
- \ref Introduction
|
||||
- \ref NewIn2_0_6
|
||||
- \ref NewIn2_0_5
|
||||
- \ref NewIn2_0_3
|
||||
- \ref NewIn2_0_2
|
||||
|
@ -63,6 +64,10 @@ What is FluidSynth?
|
|||
|
||||
- FluidSynth is open source, in active development. For more details, take a look at http://www.fluidsynth.org
|
||||
|
||||
\section NewIn2_0_6 Whats new in 2.0.6?
|
||||
|
||||
- the MIDI player did not emit any audio when calling fluid_player_play() after fluid_player_stop()
|
||||
|
||||
\section NewIn2_0_5 Whats new in 2.0.5?
|
||||
|
||||
- fluid_synth_process() omitted audio samples when called with arbitrary sample counts that were not a multiple of fluid_synth_get_internal_bufsize()
|
||||
|
@ -75,7 +80,6 @@ What is FluidSynth?
|
|||
- fluid_midi_event_get_text()
|
||||
- fluid_midi_event_get_lyrics()
|
||||
|
||||
|
||||
\section NewIn2_0_2 Whats new in 2.0.2?
|
||||
|
||||
- fluid_synth_error() has been deprecated, use fluid_set_log_function() to interfere log messages
|
||||
|
|
|
@ -293,8 +293,14 @@ find_fluid_audio_driver(fluid_settings_t *settings)
|
|||
* @param synth Synthesizer instance for which the audio driver is created for.
|
||||
* @return The new audio driver instance.
|
||||
*
|
||||
* Creates a new audio driver for a given 'synth' instance with a defined set
|
||||
* of configuration 'settings'.
|
||||
* Creates a new audio driver for a given \p synth instance with a defined set
|
||||
* of configuration \p settings.
|
||||
*
|
||||
* @note As soon as an audio driver is created, the \p synth starts rendering audio.
|
||||
* This means that all necessary sound-setup should be completed after this point,
|
||||
* thus of all object types in use (synth, midi player, sequencer, etc.) the audio
|
||||
* driver should always be the last one to be created and the first one to be deleted!
|
||||
* Also refer to the order of object creation in the code examples.
|
||||
*/
|
||||
fluid_audio_driver_t *
|
||||
new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
||||
|
@ -326,9 +332,15 @@ new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
*
|
||||
* Like new_fluid_audio_driver() but allows for custom audio processing before
|
||||
* audio is sent to audio driver. It is the responsibility of the callback
|
||||
* 'func' to render the audio into the buffers.
|
||||
* \p func to render the audio into the buffers.
|
||||
*
|
||||
* NOTE: Not as efficient as new_fluid_audio_driver().
|
||||
* @note Not as efficient as new_fluid_audio_driver().
|
||||
*
|
||||
* @note As soon as an audio driver is created, the \p synth starts rendering audio.
|
||||
* This means that all necessary sound-setup should be completed after this point,
|
||||
* thus of all object types in use (synth, midi player, sequencer, etc.) the audio
|
||||
* driver should always be the last one to be created and the first one to be deleted!
|
||||
* Also refer to the order of object creation in the code examples.
|
||||
*/
|
||||
fluid_audio_driver_t *
|
||||
new_fluid_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
|
||||
|
|
155
src/fluidsynth.c
155
src/fluidsynth.c
|
@ -55,7 +55,7 @@ int option_help = 0; /* set to 1 if "-o help" is specified */
|
|||
|
||||
|
||||
/* Process a command line option -o setting=value, for example: -o synth.polyhony=16 */
|
||||
void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
|
||||
int process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
|
||||
{
|
||||
char *val;
|
||||
int hints;
|
||||
|
@ -74,13 +74,13 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
|
|||
if(FLUID_STRCMP(optarg, "help") == 0)
|
||||
{
|
||||
option_help = 1;
|
||||
return;
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
if(FLUID_STRCMP(optarg, "") == 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid -o option (name part is empty)\n");
|
||||
return;
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
switch(fluid_settings_get_type(settings, optarg))
|
||||
|
@ -89,7 +89,7 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
|
|||
if(fluid_settings_setnum(settings, optarg, atof(val)) != FLUID_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set floating point parameter '%s'\n", optarg);
|
||||
exit(1);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -117,7 +117,7 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
|
|||
if(fluid_settings_setint(settings, optarg, ival) != FLUID_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set integer parameter '%s'\n", optarg);
|
||||
exit(1);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -126,15 +126,17 @@ void process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
|
|||
if(fluid_settings_setstr(settings, optarg, val) != FLUID_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to set string parameter '%s'\n", optarg);
|
||||
exit(1);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Setting parameter '%s' not found\n", optarg);
|
||||
exit(1);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -341,6 +343,7 @@ static int is_dls(const char *fname)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
fluid_settings_t *settings;
|
||||
int result = -1;
|
||||
int arg1 = 1;
|
||||
char buf[512];
|
||||
int c, i;
|
||||
|
@ -349,7 +352,6 @@ int main(int argc, char **argv)
|
|||
int midi_in = 1;
|
||||
fluid_player_t *player = NULL;
|
||||
fluid_midi_router_t *router = NULL;
|
||||
//fluid_sequencer_t* sequencer = NULL;
|
||||
fluid_midi_driver_t *mdriver = NULL;
|
||||
fluid_audio_driver_t *adriver = NULL;
|
||||
fluid_synth_t *synth = NULL;
|
||||
|
@ -458,7 +460,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
printf("Option -%c requires an argument\n", c);
|
||||
print_usage();
|
||||
exit(0);
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -468,7 +470,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
printf("Expected argument to option -%c found switch instead\n", c);
|
||||
print_usage();
|
||||
exit(0);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -500,7 +502,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
printf("-a options (audio driver):\n ");
|
||||
show_settings_str_options(settings, "audio.driver");
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -542,7 +545,8 @@ int main(int argc, char **argv)
|
|||
printf("\nNOTE: No libsndfile support!\n"
|
||||
"cpu: Use CPU native byte order\n");
|
||||
#endif
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -571,6 +575,8 @@ int main(int argc, char **argv)
|
|||
case 'h':
|
||||
print_welcome();
|
||||
print_help(settings);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
|
@ -601,7 +607,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
printf("-m options (MIDI driver):\n ");
|
||||
show_settings_str_options(settings, "midi.driver");
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -627,7 +634,8 @@ int main(int argc, char **argv)
|
|||
#else
|
||||
printf("\nNOTE: No libsndfile support!\n");
|
||||
#endif
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -637,7 +645,10 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'o':
|
||||
process_o_cmd_line_option(settings, optarg);
|
||||
if(process_o_cmd_line_option(settings, optarg) != FLUID_OK)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p' :
|
||||
|
@ -692,7 +703,8 @@ int main(int argc, char **argv)
|
|||
#else
|
||||
printf("\nNOTE: No libsndfile support!\n");
|
||||
#endif
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -704,7 +716,8 @@ int main(int argc, char **argv)
|
|||
case 'V':
|
||||
print_welcome();
|
||||
print_configure();
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
|
@ -719,7 +732,7 @@ int main(int argc, char **argv)
|
|||
case '?':
|
||||
printf("Unknown option %c\n", optopt);
|
||||
print_usage();
|
||||
exit(0);
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -730,7 +743,7 @@ int main(int argc, char **argv)
|
|||
default:
|
||||
printf("Unknown switch '%c'\n", c);
|
||||
print_usage();
|
||||
exit(0);
|
||||
goto cleanup;
|
||||
break;
|
||||
#endif
|
||||
} /* end of switch statement */
|
||||
|
@ -751,7 +764,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
printf("FluidSynth settings:\n");
|
||||
fluid_settings_foreach(settings, settings, settings_foreach_func);
|
||||
exit(0);
|
||||
result = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -801,7 +815,7 @@ int main(int argc, char **argv)
|
|||
if(synth == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create the synthesizer\n");
|
||||
exit(-1);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* load the soundfonts (check that all non options are SoundFont or MIDI files) */
|
||||
|
@ -820,18 +834,6 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* start the synthesis thread */
|
||||
if(!fast_render)
|
||||
{
|
||||
adriver = new_fluid_audio_driver(settings, synth);
|
||||
|
||||
if(adriver == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create the audio driver\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
router = new_fluid_midi_router(
|
||||
settings,
|
||||
dump ? fluid_midi_dump_postrouter : fluid_synth_handle_midi_event,
|
||||
|
@ -850,7 +852,6 @@ int main(int argc, char **argv)
|
|||
/* In dump mode, text output is generated for events going into and out of the router.
|
||||
* The example dump functions are put into the chain before and after the router..
|
||||
*/
|
||||
//sequencer = new_fluid_sequencer2(0);
|
||||
mdriver = new_fluid_midi_driver(
|
||||
settings,
|
||||
dump ? fluid_midi_dump_prerouter : fluid_midi_router_handle_midi_event,
|
||||
|
@ -869,7 +870,6 @@ int main(int argc, char **argv)
|
|||
{
|
||||
if((argv[i][0] != '-') && fluid_is_midifile(argv[i]))
|
||||
{
|
||||
|
||||
if(player == NULL)
|
||||
{
|
||||
player = new_fluid_player(synth);
|
||||
|
@ -973,21 +973,6 @@ int main(int argc, char **argv)
|
|||
|
||||
#endif
|
||||
|
||||
/* run the shell */
|
||||
if(interactive)
|
||||
{
|
||||
printf("Type 'help' for help topics.\n\n");
|
||||
|
||||
/* In dump mode we set the prompt to "". The UI cannot easily
|
||||
* handle lines, which don't end with CR. Changing the prompt
|
||||
* cannot be done through a command, because the current shell
|
||||
* does not handle empty arguments. The ordinary case is dump ==
|
||||
* 0.
|
||||
*/
|
||||
fluid_settings_setstr(settings, "shell.prompt", dump ? "" : "> ");
|
||||
fluid_usershell(settings, cmd_handler); /* this is a synchronous shell */
|
||||
}
|
||||
|
||||
/* fast rendering audio file, if requested */
|
||||
if(fast_render)
|
||||
{
|
||||
|
@ -1011,6 +996,33 @@ int main(int argc, char **argv)
|
|||
|
||||
fast_render_loop(settings, synth, player);
|
||||
}
|
||||
else /* start the synthesis thread */
|
||||
{
|
||||
adriver = new_fluid_audio_driver(settings, synth);
|
||||
|
||||
if(adriver == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create the audio driver\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* run the shell */
|
||||
if(interactive)
|
||||
{
|
||||
printf("Type 'help' for help topics.\n\n");
|
||||
|
||||
/* In dump mode we set the prompt to "". The UI cannot easily
|
||||
* handle lines, which don't end with CR. Changing the prompt
|
||||
* cannot be done through a command, because the current shell
|
||||
* does not handle empty arguments. The ordinary case is dump ==
|
||||
* 0.
|
||||
*/
|
||||
fluid_settings_setstr(settings, "shell.prompt", dump ? "" : "> ");
|
||||
fluid_usershell(settings, cmd_handler); /* this is a synchronous shell */
|
||||
}
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
|
||||
|
@ -1050,40 +1062,16 @@ cleanup:
|
|||
/* if no audio driver and sample timers are used, nothing makes the player advance */
|
||||
fluid_player_join(player);
|
||||
}
|
||||
|
||||
delete_fluid_player(player);
|
||||
}
|
||||
|
||||
if(mdriver)
|
||||
{
|
||||
delete_fluid_midi_driver(mdriver);
|
||||
}
|
||||
delete_fluid_audio_driver(adriver);
|
||||
delete_fluid_player(player);
|
||||
delete_fluid_midi_driver(mdriver);
|
||||
delete_fluid_midi_router(router);
|
||||
delete_fluid_synth(synth);
|
||||
delete_fluid_settings(settings);
|
||||
|
||||
if(router)
|
||||
{
|
||||
delete_fluid_midi_router(router);
|
||||
}
|
||||
|
||||
/*if (sequencer) {
|
||||
delete_fluid_sequencer(sequencer);
|
||||
}*/
|
||||
|
||||
if(adriver)
|
||||
{
|
||||
delete_fluid_audio_driver(adriver);
|
||||
}
|
||||
|
||||
if(synth)
|
||||
{
|
||||
delete_fluid_synth(synth);
|
||||
}
|
||||
|
||||
if(settings)
|
||||
{
|
||||
delete_fluid_settings(settings);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1094,7 +1082,6 @@ print_usage()
|
|||
{
|
||||
fprintf(stderr, "Usage: fluidsynth [options] [soundfonts]\n");
|
||||
fprintf(stderr, "Try -h for help.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1205,8 +1192,4 @@ print_help(fluid_settings_t *settings)
|
|||
{
|
||||
FLUID_FREE(midi_options);
|
||||
}
|
||||
|
||||
delete_fluid_settings(settings);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ static fluid_midi_event_t *fluid_track_next_event(fluid_track_t *track);
|
|||
static int fluid_track_get_duration(fluid_track_t *track);
|
||||
static int fluid_track_reset(fluid_track_t *track);
|
||||
|
||||
static int fluid_track_send_events(fluid_track_t *track,
|
||||
static void fluid_track_send_events(fluid_track_t *track,
|
||||
fluid_synth_t *synth,
|
||||
fluid_player_t *player,
|
||||
unsigned int ticks);
|
||||
|
@ -1552,13 +1552,12 @@ fluid_track_reset(fluid_track_t *track)
|
|||
/*
|
||||
* fluid_track_send_events
|
||||
*/
|
||||
int
|
||||
void
|
||||
fluid_track_send_events(fluid_track_t *track,
|
||||
fluid_synth_t *synth,
|
||||
fluid_player_t *player,
|
||||
unsigned int ticks)
|
||||
{
|
||||
int status = FLUID_OK;
|
||||
fluid_midi_event_t *event;
|
||||
int seeking = player->seek_ticks >= 0;
|
||||
|
||||
|
@ -1579,7 +1578,7 @@ fluid_track_send_events(fluid_track_t *track,
|
|||
|
||||
if(event == NULL)
|
||||
{
|
||||
return status;
|
||||
return;
|
||||
}
|
||||
|
||||
/* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */
|
||||
|
@ -1591,7 +1590,7 @@ fluid_track_send_events(fluid_track_t *track,
|
|||
|
||||
if(track->ticks + event->dtime > ticks)
|
||||
{
|
||||
return status;
|
||||
return;
|
||||
}
|
||||
|
||||
track->ticks += event->dtime;
|
||||
|
@ -1619,8 +1618,6 @@ fluid_track_send_events(fluid_track_t *track,
|
|||
fluid_track_next_event(track);
|
||||
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
|
@ -1678,6 +1675,26 @@ new_fluid_player(fluid_synth_t *synth)
|
|||
fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth);
|
||||
player->use_system_timer = fluid_settings_str_equal(synth->settings,
|
||||
"player.timing-source", "system");
|
||||
if(player->use_system_timer)
|
||||
{
|
||||
player->system_timer = new_fluid_timer((int) player->deltatime,
|
||||
fluid_player_callback, player, TRUE, FALSE, TRUE);
|
||||
|
||||
if(player->system_timer == NULL)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->sample_timer = new_fluid_sample_timer(player->synth,
|
||||
fluid_player_callback, player);
|
||||
|
||||
if(player->sample_timer == NULL)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
fluid_settings_getint(synth->settings, "player.reset-synth", &i);
|
||||
fluid_player_handle_reset_synth(player, NULL, i);
|
||||
|
@ -1686,11 +1703,16 @@ new_fluid_player(fluid_synth_t *synth)
|
|||
fluid_player_handle_reset_synth, player);
|
||||
|
||||
return player;
|
||||
|
||||
err:
|
||||
delete_fluid_player(player);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a MIDI player instance.
|
||||
* @param player MIDI player instance
|
||||
* @warning Do not call while the \p synth renders audio, i.e. an audio driver is running or any other synthesizer thread calls fluid_synth_process() or fluid_synth_nwrite_float() or fluid_synth_write_*() !
|
||||
*/
|
||||
void
|
||||
delete_fluid_player(fluid_player_t *player)
|
||||
|
@ -1703,6 +1725,9 @@ delete_fluid_player(fluid_player_t *player)
|
|||
fluid_player_stop(player);
|
||||
fluid_player_reset(player);
|
||||
|
||||
delete_fluid_timer(player->system_timer);
|
||||
delete_fluid_sample_timer(player->synth, player->sample_timer);
|
||||
|
||||
while(player->playlist != NULL)
|
||||
{
|
||||
q = player->playlist->next;
|
||||
|
@ -2030,6 +2055,11 @@ fluid_player_callback(void *data, unsigned int msec)
|
|||
|
||||
loadnextfile = player->currentfile == NULL ? 1 : 0;
|
||||
|
||||
if(player->status == FLUID_PLAYER_DONE)
|
||||
{
|
||||
fluid_synth_all_notes_off(synth, -1);
|
||||
return 1;
|
||||
}
|
||||
do
|
||||
{
|
||||
if(loadnextfile)
|
||||
|
@ -2058,12 +2088,7 @@ fluid_player_callback(void *data, unsigned int msec)
|
|||
if(!fluid_track_eot(player->track[i]))
|
||||
{
|
||||
status = FLUID_PLAYER_PLAYING;
|
||||
|
||||
if(fluid_track_send_events(player->track[i], synth, player,
|
||||
player->cur_ticks) != FLUID_OK)
|
||||
{
|
||||
/* */
|
||||
}
|
||||
fluid_track_send_events(player->track[i], synth, player, player->cur_ticks);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2098,63 +2123,33 @@ fluid_player_callback(void *data, unsigned int msec)
|
|||
int
|
||||
fluid_player_play(fluid_player_t *player)
|
||||
{
|
||||
if(player->status == FLUID_PLAYER_PLAYING)
|
||||
if(player->status == FLUID_PLAYER_PLAYING ||
|
||||
player->playlist == NULL)
|
||||
{
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
if(player->playlist == NULL)
|
||||
if(!player->use_system_timer)
|
||||
{
|
||||
return FLUID_OK;
|
||||
fluid_sample_timer_reset(player->synth, player->sample_timer);
|
||||
}
|
||||
|
||||
player->status = FLUID_PLAYER_PLAYING;
|
||||
|
||||
if(player->use_system_timer)
|
||||
{
|
||||
player->system_timer = new_fluid_timer((int) player->deltatime,
|
||||
fluid_player_callback, (void *) player, TRUE, FALSE, TRUE);
|
||||
|
||||
if(player->system_timer == NULL)
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->sample_timer = new_fluid_sample_timer(player->synth,
|
||||
fluid_player_callback, (void *) player);
|
||||
|
||||
if(player->sample_timer == NULL)
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops a MIDI player.
|
||||
* Pauses the MIDI playback.
|
||||
*
|
||||
* It will not rewind to the beginning of the file, use fluid_player_seek() for this purpose.
|
||||
* @param player MIDI player instance
|
||||
* @return Always returns #FLUID_OK
|
||||
*/
|
||||
int
|
||||
fluid_player_stop(fluid_player_t *player)
|
||||
{
|
||||
if(player->system_timer != NULL)
|
||||
{
|
||||
delete_fluid_timer(player->system_timer);
|
||||
}
|
||||
|
||||
if(player->sample_timer != NULL)
|
||||
{
|
||||
delete_fluid_sample_timer(player->synth, player->sample_timer);
|
||||
}
|
||||
|
||||
player->status = FLUID_PLAYER_DONE;
|
||||
player->sample_timer = NULL;
|
||||
player->system_timer = NULL;
|
||||
fluid_player_seek(player, fluid_player_get_current_tick(player));
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
|
@ -2240,26 +2235,17 @@ int fluid_player_set_bpm(fluid_player_t *player, int bpm)
|
|||
}
|
||||
|
||||
/**
|
||||
* Wait for a MIDI player to terminate (when done playing).
|
||||
* Wait for a MIDI player until the playback has been stopped.
|
||||
* @param player MIDI player instance
|
||||
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
* @return Always #FLUID_OK
|
||||
*/
|
||||
int
|
||||
fluid_player_join(fluid_player_t *player)
|
||||
{
|
||||
if(player->system_timer)
|
||||
while(player->status != FLUID_PLAYER_DONE)
|
||||
{
|
||||
return fluid_timer_join(player->system_timer);
|
||||
fluid_msleep(10);
|
||||
}
|
||||
else if(player->sample_timer)
|
||||
{
|
||||
/* Busy-wait loop, since there's no thread to wait for... */
|
||||
while(player->status != FLUID_PLAYER_DONE)
|
||||
{
|
||||
fluid_msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -500,16 +500,13 @@ struct _fluid_sample_timer_t
|
|||
*/
|
||||
static void fluid_sample_timer_process(fluid_synth_t *synth)
|
||||
{
|
||||
fluid_sample_timer_t *st, *stnext;
|
||||
fluid_sample_timer_t *st;
|
||||
long msec;
|
||||
int cont;
|
||||
unsigned int ticks = fluid_synth_get_ticks(synth);
|
||||
|
||||
for(st = synth->sample_timers; st; st = stnext)
|
||||
for(st = synth->sample_timers; st; st = st->next)
|
||||
{
|
||||
/* st may be freed in the callback below. cache it's successor now to avoid use after free */
|
||||
stnext = st->next;
|
||||
|
||||
if(st->isfinished)
|
||||
{
|
||||
continue;
|
||||
|
@ -535,7 +532,7 @@ fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
result->starttick = fluid_synth_get_ticks(synth);
|
||||
fluid_sample_timer_reset(synth, result);
|
||||
result->isfinished = 0;
|
||||
result->data = data;
|
||||
result->callback = callback;
|
||||
|
@ -565,6 +562,10 @@ void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer
|
|||
}
|
||||
}
|
||||
|
||||
void fluid_sample_timer_reset(fluid_synth_t *synth, fluid_sample_timer_t *timer)
|
||||
{
|
||||
timer->starttick = fluid_synth_get_ticks(synth);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
|
|
@ -205,7 +205,7 @@ int fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double le
|
|||
|
||||
fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_callback_t callback, void *data);
|
||||
void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer);
|
||||
|
||||
void fluid_sample_timer_reset(fluid_synth_t *synth, fluid_sample_timer_t *timer);
|
||||
|
||||
void fluid_synth_process_event_queue(fluid_synth_t *synth);
|
||||
|
||||
|
|
Loading…
Reference in a new issue