# HG changeset patch # User Giacomo Lozito # Date 1186401684 -7200 # Node ID 5f892afeb8e1ff5e60f32449359a59eda383f14a # Parent 4731d28ea19d8e6c96720c05b5ae46284c92e648 - amidi-plug 0.8 beta1; support for gthread and v3 plugin system; needs testing and refinements diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/amidi-plug.c --- a/src/amidi-plug/amidi-plug.c Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/amidi-plug.c Mon Aug 06 14:01:24 2007 +0200 @@ -1,6 +1,6 @@ /* * -* Author: Giacomo Lozito , (C) 2005-2006 +* Author: Giacomo Lozito , (C) 2005-2007 * * 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 @@ -88,6 +88,12 @@ static void amidiplug_init( void ) { g_log_set_handler(NULL , G_LOG_LEVEL_WARNING , g_log_default_handler , NULL); + + amidiplug_gettime_mutex = g_mutex_new(); + amidiplug_playing_mutex = g_mutex_new(); + amidiplug_pause_cond = g_cond_new(); + amidiplug_seekonpause_cond = g_cond_new(); + DEBUGMSG( "init, read configuration\n" ); /* read configuration for amidi-plug */ i_configure_cfg_ap_read(); @@ -101,6 +107,13 @@ static void amidiplug_cleanup( void ) { i_backend_unload(); /* unload currently loaded backend */ + + g_mutex_free(amidiplug_gettime_mutex); + g_mutex_free(amidiplug_playing_mutex); + g_cond_free(amidiplug_pause_cond); + g_cond_free(amidiplug_seekonpause_cond); + amidiplug_pause_cond = NULL; + amidiplug_seekonpause_cond = NULL; } @@ -126,29 +139,38 @@ static void amidiplug_stop( InputPlayback * playback ) { + gboolean is_error = FALSE; DEBUGMSG( "STOP request at tick: %i\n" , midifile.playing_tick ); - pthread_mutex_lock( &amidiplug_playing_mutex ); - if (( amidiplug_playing_status == AMIDIPLUG_PLAY ) || - ( amidiplug_playing_status == AMIDIPLUG_STOP )) + + g_mutex_lock( amidiplug_playing_mutex ); + if ( amidiplug_playing_status == AMIDIPLUG_ERR ) + is_error = TRUE; + g_mutex_unlock( amidiplug_playing_mutex ); + + if ( !is_error ) { - amidiplug_playing_status = AMIDIPLUG_STOP; - pthread_mutex_unlock( &amidiplug_playing_mutex ); - pthread_join( amidiplug_play_thread , NULL ); - if ( backend.autonomous_audio == FALSE ) - pthread_join( amidiplug_audio_thread , NULL ); - DEBUGMSG( "STOP activated (play thread joined)\n" ); + /* if stop wasn't called due to error condition, + wait until the play thread reach a 'safe state' + (that is, when amidiplug_play_thread exists) */ + while ( !amidiplug_play_thread ) + g_usleep( 20000 ); } - else if ( amidiplug_playing_status == AMIDIPLUG_PAUSE ) + + g_mutex_lock( amidiplug_playing_mutex ); + amidiplug_playing_status = AMIDIPLUG_STOP; + g_cond_signal( amidiplug_pause_cond ); + g_mutex_unlock( amidiplug_playing_mutex ); + if ( amidiplug_play_thread ) { - amidiplug_playing_status = AMIDIPLUG_STOP; - DEBUGMSG( "STOP activated (from PAUSE to STOP)\n" ); - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_thread_join( amidiplug_play_thread ); + amidiplug_play_thread = NULL; } - else /* AMIDIPLUG_ERR */ + if (( backend.autonomous_audio == FALSE ) && ( amidiplug_audio_thread )) { - DEBUGMSG( "STOP activated (in error handling, ok)\n" ); - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_thread_join( amidiplug_audio_thread ); + amidiplug_audio_thread = NULL; } + DEBUGMSG( "STOP activated (play thread joined)\n" ); /* kill the sequencer (while it may have been already killed if coming from pause, it's safe to do anyway since it checks for multiple calls) */ @@ -176,84 +198,49 @@ { if ( paused ) { + g_mutex_lock( amidiplug_playing_mutex ); + if ( amidiplug_playing_status == AMIDIPLUG_SEEK ) + { + DEBUGMSG( "handle SEEK ON PAUSE situation\n" , midifile.playing_tick ); + /* uh oh, we have a pending seek; this can happen when a seek + is requested while playback is paused; wait for that seek to + be completed before pausing the song again */ + while ( amidiplug_playing_status != AMIDIPLUG_PLAY ) + g_cond_wait( amidiplug_seekonpause_cond , amidiplug_playing_mutex ); + } + g_mutex_unlock( amidiplug_playing_mutex ); DEBUGMSG( "PAUSE request at tick: %i\n" , midifile.playing_tick ); - pthread_mutex_lock( &amidiplug_playing_mutex ); - /* this cond is used to avoid race conditions */ - while ( amidiplug_playing_status != AMIDIPLUG_PLAY ) - pthread_cond_wait( &amidiplug_playing_cond , &amidiplug_playing_mutex ); + g_mutex_lock( amidiplug_playing_mutex ); amidiplug_playing_status = AMIDIPLUG_PAUSE; - pthread_mutex_unlock( &amidiplug_playing_mutex ); - - pthread_join( amidiplug_play_thread , NULL ); - if ( backend.autonomous_audio == FALSE ) - pthread_join( amidiplug_audio_thread , NULL ); - DEBUGMSG( "PAUSE activated (play thread joined)\n" , midifile.playing_tick ); - + g_mutex_unlock( amidiplug_playing_mutex ); if ( backend.autonomous_audio == FALSE ) playback->output->pause(paused); - - /* kill the sequencer */ - backend.seq_off(); } else { - DEBUGMSG( "PAUSE deactivated, returning to tick %i\n" , midifile.playing_tick ); - /* revive the sequencer */ - backend.seq_on(); - /* re-set initial tempo */ - i_midi_setget_tempo( &midifile ); - backend.seq_queue_tempo( midifile.current_tempo , midifile.ppq ); - /* get back to the previous state */ - amidiplug_skipto( midifile.playing_tick ); - + DEBUGMSG( "PAUSE deactivated, resume playing from tick %i\n" , midifile.playing_tick ); if ( backend.autonomous_audio == FALSE ) playback->output->pause(paused); - - pthread_mutex_lock( &amidiplug_playing_mutex ); - /* play play play! */ - DEBUGMSG( "PAUSE deactivated, starting play thread again\n" ); - pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, playback); - /* this cond is used to avoid race conditions */ - while ( amidiplug_playing_status != AMIDIPLUG_PLAY ) - pthread_cond_wait( &amidiplug_playing_cond , &amidiplug_playing_mutex ); - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_lock( amidiplug_playing_mutex ); + amidiplug_playing_status = AMIDIPLUG_PLAY; + g_cond_signal( amidiplug_pause_cond ); + /* wait for unpause operation to be completed */ + g_cond_wait( amidiplug_pause_cond , amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); } } static void amidiplug_seek( InputPlayback * playback, gint time ) { - DEBUGMSG( "SEEK requested (time %i), pausing song...\n" , time ); - pthread_mutex_lock( &amidiplug_playing_mutex ); - /* this cond is used to avoid race conditions */ - while ( amidiplug_playing_status != AMIDIPLUG_PLAY ) - pthread_cond_wait( &amidiplug_playing_cond , &amidiplug_playing_mutex ); - amidiplug_playing_status = AMIDIPLUG_PAUSE; - pthread_mutex_unlock( &amidiplug_playing_mutex ); - - pthread_join( amidiplug_play_thread , NULL ); - if ( backend.autonomous_audio == FALSE ) - pthread_join( amidiplug_audio_thread , NULL ); - DEBUGMSG( "SEEK requested (time %i), song paused\n" , time ); - /* kill the sequencer */ - backend.seq_off(); - /* revive the sequencer */ - backend.seq_on(); - /* re-set initial tempo */ - i_midi_setget_tempo( &midifile ); - backend.seq_queue_tempo( midifile.current_tempo , midifile.ppq ); - /* get back to the previous state */ - DEBUGMSG( "SEEK requested (time %i), moving to tick %i of %i\n" , - time , (gint)((time * 1000000) / midifile.avg_microsec_per_tick) , midifile.max_tick ); - midifile.playing_tick = (gint)((time * 1000000) / midifile.avg_microsec_per_tick); - amidiplug_skipto( midifile.playing_tick ); + DEBUGMSG( "SEEK requested (time %i)...\n" , time ); + g_mutex_lock( amidiplug_playing_mutex ); + midifile.seeking_tick = (gint)((time * 1000000) / midifile.avg_microsec_per_tick); + amidiplug_playing_status = AMIDIPLUG_SEEK; + g_mutex_unlock( amidiplug_playing_mutex ); if ( backend.autonomous_audio == FALSE ) playback->output->flush(time * 1000); - - /* play play play! */ - DEBUGMSG( "SEEK done, starting play thread again\n" ); - pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, playback); } @@ -261,23 +248,24 @@ { if ( backend.autonomous_audio == FALSE ) { - pthread_mutex_lock( &amidiplug_playing_mutex ); + g_mutex_lock( amidiplug_playing_mutex ); if (( amidiplug_playing_status == AMIDIPLUG_PLAY ) || ( amidiplug_playing_status == AMIDIPLUG_PAUSE ) || + ( amidiplug_playing_status == AMIDIPLUG_SEEK ) || (( amidiplug_playing_status == AMIDIPLUG_STOP ) && ( playback->output->buffer_playing() ))) { - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); return playback->output->output_time(); } else if ( amidiplug_playing_status == AMIDIPLUG_STOP ) { - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); DEBUGMSG( "GETTIME on stopped song, returning -1\n" , time ); return -1; } else /* AMIDIPLUG_ERR */ { - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); DEBUGMSG( "GETTIME on halted song (an error occurred?), returning -1 and stopping the player\n" ); audacious_drct_stop(); return -1; @@ -286,25 +274,26 @@ else { gint pt; - pthread_mutex_lock( &amidiplug_playing_mutex ); + g_mutex_lock( amidiplug_playing_mutex ); if (( amidiplug_playing_status == AMIDIPLUG_PLAY ) || - ( amidiplug_playing_status == AMIDIPLUG_PAUSE )) + ( amidiplug_playing_status == AMIDIPLUG_PAUSE ) || + ( amidiplug_playing_status == AMIDIPLUG_SEEK )) { - pthread_mutex_unlock( &amidiplug_playing_mutex ); - pthread_mutex_lock(&amidiplug_gettime_mutex); + g_mutex_unlock( amidiplug_playing_mutex ); + g_mutex_lock( amidiplug_gettime_mutex ); pt = midifile.playing_tick; - pthread_mutex_unlock(&amidiplug_gettime_mutex); + g_mutex_unlock( amidiplug_gettime_mutex ); return (gint)((pt * midifile.avg_microsec_per_tick) / 1000); } else if ( amidiplug_playing_status == AMIDIPLUG_STOP ) { - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); DEBUGMSG( "GETTIME on stopped song, returning -1\n" , time ); return -1; } else /* AMIDIPLUG_ERR */ { - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); DEBUGMSG( "GETTIME on halted song (an error occurred?), returning -1 and stopping the player\n" , time ); audacious_drct_stop(); return -1; @@ -475,10 +464,17 @@ au_samplerate , au_channels ); g_free( filename ); + /* done with file */ + VFS_FCLOSE( midifile.file_pointer ); + midifile.file_pointer = NULL; + /* play play play! */ DEBUGMSG( "PLAY requested, starting play thread\n" ); + g_mutex_lock( amidiplug_playing_mutex ); amidiplug_playing_status = AMIDIPLUG_PLAY; - pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, playback); + g_mutex_unlock( amidiplug_playing_mutex ); + amidiplug_play_thread = g_thread_self(); + amidiplug_play_loop(playback); break; } @@ -490,44 +486,34 @@ } } - VFS_FCLOSE( midifile.file_pointer ); + if ( midifile.file_pointer ) + { + /* done with file */ + VFS_FCLOSE( midifile.file_pointer ); + midifile.file_pointer = NULL; + } } -void * amidiplug_play_loop( void * arg ) +gpointer amidiplug_play_loop( gpointer arg ) { InputPlayback *playback = arg; - gint i = 0; - gboolean rewind = FALSE; - - pthread_mutex_lock( &amidiplug_playing_mutex ); - if ( amidiplug_playing_status != AMIDIPLUG_PAUSE ) - { - DEBUGMSG( "PLAY thread, rewind tracks to their first event\n" ); - rewind = TRUE; - } - else - { - DEBUGMSG( "PLAY thread, do not rewind tracks to their first event (coming from a PAUSE status)\n" ); - amidiplug_playing_status = AMIDIPLUG_PLAY; - pthread_cond_signal( &amidiplug_playing_cond ); - } - pthread_mutex_unlock( &amidiplug_playing_mutex ); + gint j = 0; + gboolean rewind = TRUE; if ( rewind ) { /* initialize current position in each track */ - for (i = 0; i < midifile.num_tracks; ++i) - midifile.tracks[i].current_event = midifile.tracks[i].first_event; - backend.seq_queue_start(); + for (j = 0; j < midifile.num_tracks; ++j) + midifile.tracks[j].current_event = midifile.tracks[j].first_event; } if ( backend.autonomous_audio == FALSE ) - { - pthread_create(&amidiplug_audio_thread, NULL, amidiplug_audio_loop, playback); - } + amidiplug_audio_thread = g_thread_create(amidiplug_audio_loop, playback, TRUE, NULL); + /* queue start */ + backend.seq_queue_start(); /* common settings for all our events */ backend.seq_event_init(); @@ -537,6 +523,46 @@ midievent_t * event = NULL; midifile_track_t * event_track = NULL; gint i, min_tick = midifile.max_tick + 1; + + /* check if the song has been paused/seeked/stopped */ + g_mutex_lock( amidiplug_playing_mutex ); + if ( amidiplug_playing_status != AMIDIPLUG_PLAY ) + { + DEBUGMSG( "PLAY thread, PAUSE/SEEK/STOP requested, handle in play loop\n" ); + if ( amidiplug_playing_status == AMIDIPLUG_PAUSE ) + { + DEBUGMSG( "PLAY thread, PAUSE requested, shut notes and make the play loop wait\n" ); + backend.seq_event_allnoteoff( midifile.playing_tick ); + backend.seq_queue_stop(); + while (( amidiplug_playing_status != AMIDIPLUG_PLAY ) && + ( amidiplug_playing_status != AMIDIPLUG_STOP )) + g_cond_wait( amidiplug_pause_cond , amidiplug_playing_mutex ); + DEBUGMSG( "PLAY thread, UNPAUSE requested, resume playing\n" ); + g_mutex_lock( amidiplug_gettime_mutex ); + midifile.skip_offset = midifile.playing_tick; + g_mutex_unlock( amidiplug_gettime_mutex ); + if ( backend.autonomous_audio == FALSE ) + amidiplug_audio_thread = g_thread_create(amidiplug_audio_loop, playback, TRUE, NULL); + backend.seq_queue_start(); + g_cond_signal( amidiplug_pause_cond ); + } + if ( amidiplug_playing_status == AMIDIPLUG_SEEK ) + { + backend.seq_event_allnoteoff( midifile.playing_tick ); + backend.seq_queue_stop(); + amidiplug_skipto( midifile.seeking_tick ); + midifile.seeking_tick = -1; + amidiplug_playing_status = AMIDIPLUG_PLAY; + g_cond_signal( amidiplug_seekonpause_cond ); + } + if ( amidiplug_playing_status == AMIDIPLUG_STOP ) + { + DEBUGMSG( "PLAY thread, STOP requested, stopping...\n" ); + g_mutex_unlock( amidiplug_playing_mutex ); + break; /* exit from the for (;;) loop */ + } + } + g_mutex_unlock( amidiplug_playing_mutex ); /* search next event */ for (i = 0; i < midifile.num_tracks; ++i) @@ -551,15 +577,6 @@ } } - /* check if the song has been stopped */ - pthread_mutex_lock( &amidiplug_playing_mutex ); - if ( amidiplug_playing_status != AMIDIPLUG_PLAY ) - { - DEBUGMSG( "PLAY thread, PAUSE or STOP requested, exiting from play loop\n" ); - event = NULL; - } - pthread_mutex_unlock( &amidiplug_playing_mutex ); - if (!event) break; /* end of song reached */ @@ -599,9 +616,9 @@ backend.seq_event_tempo( event ); DEBUGMSG( "PLAY thread, processing tempo event with value %i on tick %i\n" , event->data.tempo , event->tick ); - pthread_mutex_lock(&amidiplug_gettime_mutex); + g_mutex_lock( amidiplug_gettime_mutex ); midifile.current_tempo = event->data.tempo; - pthread_mutex_unlock(&amidiplug_gettime_mutex); + g_mutex_unlock( amidiplug_gettime_mutex ); break; case SND_SEQ_EVENT_META_TEXT: /* do nothing */ @@ -614,9 +631,9 @@ break; } - pthread_mutex_lock(&amidiplug_gettime_mutex); + g_mutex_lock( amidiplug_gettime_mutex ); midifile.playing_tick = event->tick; - pthread_mutex_unlock(&amidiplug_gettime_mutex); + g_mutex_unlock( amidiplug_gettime_mutex ); if ( backend.autonomous_audio == TRUE ) { @@ -627,15 +644,14 @@ backend.seq_output_shut( midifile.max_tick , midifile.skip_offset ); - pthread_mutex_lock( &amidiplug_playing_mutex ); + g_mutex_lock( amidiplug_playing_mutex ); if ( amidiplug_playing_status != AMIDIPLUG_PAUSE ) { amidiplug_playing_status = AMIDIPLUG_STOP; DEBUGMSG( "PLAY thread, song stopped/ended\n" ); } - pthread_mutex_unlock( &amidiplug_playing_mutex ); - - pthread_exit(NULL); + g_mutex_unlock( amidiplug_playing_mutex ); + return NULL; } @@ -724,9 +740,9 @@ break; case SND_SEQ_EVENT_TEMPO: backend.seq_event_tempo( event ); - pthread_mutex_lock(&amidiplug_gettime_mutex); + g_mutex_lock( amidiplug_gettime_mutex ); midifile.current_tempo = event->data.tempo; - pthread_mutex_unlock(&amidiplug_gettime_mutex); + g_mutex_unlock( amidiplug_gettime_mutex ); break; } @@ -743,7 +759,7 @@ } -void * amidiplug_audio_loop( void * arg ) +gpointer amidiplug_audio_loop( gpointer arg ) { InputPlayback *playback = arg; gboolean going = 1; @@ -758,12 +774,13 @@ produce_audio( playback->output->written_time() , FMT_S16_NE , 2 , buffer_size , buffer , &going ); } - pthread_mutex_lock( &amidiplug_playing_mutex ); - if ( amidiplug_playing_status != AMIDIPLUG_PLAY ) + g_mutex_lock( amidiplug_playing_mutex ); + if (( amidiplug_playing_status != AMIDIPLUG_PLAY ) && + ( amidiplug_playing_status != AMIDIPLUG_SEEK )) going = FALSE; - pthread_mutex_unlock( &amidiplug_playing_mutex ); + g_mutex_unlock( amidiplug_playing_mutex ); } if ( buffer != NULL ) g_free( buffer ); - pthread_exit(NULL); + return NULL; } diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/amidi-plug.h --- a/src/amidi-plug/amidi-plug.h Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/amidi-plug.h Mon Aug 06 14:01:24 2007 +0200 @@ -24,7 +24,8 @@ #define AMIDIPLUG_STOP 0 #define AMIDIPLUG_PLAY 1 #define AMIDIPLUG_PAUSE 2 -#define AMIDIPLUG_ERR 3 +#define AMIDIPLUG_SEEK 3 +#define AMIDIPLUG_ERR 4 #include "i_common.h" #include @@ -39,11 +40,12 @@ #include "i_utils.h" -static pthread_t amidiplug_play_thread; -static pthread_t amidiplug_audio_thread; -static pthread_mutex_t amidiplug_gettime_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t amidiplug_playing_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t amidiplug_playing_cond = PTHREAD_COND_INITIALIZER; +static GThread * amidiplug_play_thread = NULL; +static GThread * amidiplug_audio_thread = NULL; +static GMutex * amidiplug_gettime_mutex = NULL; +static GMutex * amidiplug_playing_mutex = NULL; +static GCond * amidiplug_pause_cond = NULL; +static GCond * amidiplug_seekonpause_cond = NULL; gint amidiplug_playing_status = AMIDIPLUG_STOP; @@ -63,8 +65,8 @@ gchar *amidiplug_vfs_extensions[] = { "mid" , "midi" , "rmi" , "rmid" , NULL }; -void * amidiplug_play_loop( void * ); -void * amidiplug_audio_loop( void * ); +gpointer amidiplug_play_loop( gpointer ); +gpointer amidiplug_audio_loop( gpointer ); void amidiplug_skipto( gint ); static void amidiplug_init( void ); static void amidiplug_cleanup( void ); diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/backend-alsa/b-alsa.c --- a/src/amidi-plug/backend-alsa/b-alsa.c Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/backend-alsa/b-alsa.c Mon Aug 06 14:01:24 2007 +0200 @@ -179,6 +179,12 @@ } +gint sequencer_queue_stop( void ) +{ + return snd_seq_stop_queue( sc.seq , sc.queue , NULL ); +} + + gint sequencer_event_init( void ) { /* common settings for all our events */ @@ -291,6 +297,31 @@ } +gint sequencer_event_allnoteoff( gint unused ) +{ + gint i = 0 , c = 0; + /* send "ALL SOUNDS OFF" to all channels on all ports */ + sc.ev.type = SND_SEQ_EVENT_CONTROLLER; + sc.ev.time.tick = 0; + snd_seq_ev_set_fixed(&sc.ev); + sc.ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF; + sc.ev.data.control.value = 0; + for ( i = 0 ; i < sc.dest_port_num ; i++ ) + { + sc.ev.queue = sc.queue; + sc.ev.dest = sc.dest_port[i]; + + for ( c = 0 ; c < 16 ; c++ ) + { + sc.ev.data.control.channel = c; + snd_seq_event_output(sc.seq, &sc.ev); + snd_seq_drain_output(sc.seq); + } + } + return 1; +} + + gint sequencer_output( gpointer * buffer , gint * len ) { snd_seq_event_output( sc.seq , &sc.ev ); diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/backend-dummy/b-dummy.c --- a/src/amidi-plug/backend-dummy/b-dummy.c Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/backend-dummy/b-dummy.c Mon Aug 06 14:01:24 2007 +0200 @@ -178,6 +178,12 @@ } +gint sequencer_queue_stop( void ) +{ + return 1; +} + + gint sequencer_event_init( void ) { /* common settings for all our events */ @@ -277,6 +283,12 @@ } +gint sequencer_event_allnoteoff( gint unused ) +{ + return 1; +} + + gint sequencer_output( gpointer * buffer , gint * len ) { return 0; diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/backend-fluidsynth/b-fluidsynth.c --- a/src/amidi-plug/backend-fluidsynth/b-fluidsynth.c Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/backend-fluidsynth/b-fluidsynth.c Mon Aug 06 14:01:24 2007 +0200 @@ -163,12 +163,21 @@ gint sequencer_queue_start( void ) { + sc.last_sample_time = 0; g_timer_start( sc.timer_seq ); /* reset the sequencer timer */ g_timer_start( sc.timer_sample ); /* reset the sampler timer */ return 1; } +gint sequencer_queue_stop( void ) +{ + g_timer_stop( sc.timer_seq ); + g_timer_stop( sc.timer_sample ); + return 1; +} + + gint sequencer_event_init( void ) { /* common settings for all our events */ @@ -274,6 +283,17 @@ } +gint sequencer_event_allnoteoff( gint unused ) +{ + gint c = 0; + for ( c = 0 ; c < 16 ; c++ ) + { + fluid_synth_all_notes_off( sc.synth , c ); + } + return 1; +} + + gint sequencer_output( gpointer * buffer , gint * len ) { gdouble current_time = g_timer_elapsed( sc.timer_sample , NULL ); diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/i_backend.c --- a/src/amidi-plug/i_backend.c Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/i_backend.c Mon Aug 06 14:01:24 2007 +0200 @@ -122,9 +122,11 @@ g_module_symbol( backend.gmodule , "sequencer_off" , (gpointer *)&backend.seq_off ); g_module_symbol( backend.gmodule , "sequencer_queue_tempo" , (gpointer *)&backend.seq_queue_tempo ); g_module_symbol( backend.gmodule , "sequencer_queue_start" , (gpointer *)&backend.seq_queue_start ); + g_module_symbol( backend.gmodule , "sequencer_queue_stop" , (gpointer *)&backend.seq_queue_stop ); g_module_symbol( backend.gmodule , "sequencer_event_init" , (gpointer *)&backend.seq_event_init ); g_module_symbol( backend.gmodule , "sequencer_event_noteon" , (gpointer *)&backend.seq_event_noteon ); g_module_symbol( backend.gmodule , "sequencer_event_noteoff" , (gpointer *)&backend.seq_event_noteoff ); + g_module_symbol( backend.gmodule , "sequencer_event_allnoteoff" , (gpointer *)&backend.seq_event_allnoteoff ); g_module_symbol( backend.gmodule , "sequencer_event_keypress" , (gpointer *)&backend.seq_event_keypress ); g_module_symbol( backend.gmodule , "sequencer_event_controller" , (gpointer *)&backend.seq_event_controller ); g_module_symbol( backend.gmodule , "sequencer_event_pgmchange" , (gpointer *)&backend.seq_event_pgmchange ); diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/i_backend.h --- a/src/amidi-plug/i_backend.h Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/i_backend.h Mon Aug 06 14:01:24 2007 +0200 @@ -54,9 +54,11 @@ gint (*seq_off)( void ); gint (*seq_queue_tempo)( gint , gint ); gint (*seq_queue_start)( void ); + gint (*seq_queue_stop)( void ); gint (*seq_event_init)( void ); gint (*seq_event_noteon)( midievent_t * ); gint (*seq_event_noteoff)( midievent_t * ); + gint (*seq_event_allnoteoff)( gint ); gint (*seq_event_keypress)( midievent_t * ); gint (*seq_event_controller)( midievent_t * ); gint (*seq_event_pgmchange)( midievent_t * ); diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/i_common.h --- a/src/amidi-plug/i_common.h Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/i_common.h Mon Aug 06 14:01:24 2007 +0200 @@ -30,6 +30,8 @@ #include +#define DEBUG 1 + #define textdomain(Domain) #define bindtextdomain(Package, Directory) @@ -43,7 +45,7 @@ #endif /* DEBUG */ -#define AMIDIPLUG_VERSION "0.7p1" +#define AMIDIPLUG_VERSION "0.8b1" #define PLAYER_NAME "Audacious" #define PLAYER_LOCALRCDIR ".audacious" #define G_PATH_GET_BASENAME(x) g_path_get_basename(x) diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/i_midi.c --- a/src/amidi-plug/i_midi.c Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/i_midi.c Mon Aug 06 14:01:24 2007 +0200 @@ -509,6 +509,7 @@ mf->ppq = 0; mf->current_tempo = 0; mf->playing_tick = 0; + mf->seeking_tick = -1; mf->avg_microsec_per_tick = 0; mf->length = 0; mf->skip_offset = 0; diff -r 4731d28ea19d -r 5f892afeb8e1 src/amidi-plug/i_midi.h --- a/src/amidi-plug/i_midi.h Mon Aug 06 03:20:01 2007 +0200 +++ b/src/amidi-plug/i_midi.h Mon Aug 06 14:01:24 2007 +0200 @@ -251,6 +251,7 @@ gint current_tempo; gint playing_tick; + gint seeking_tick; gint avg_microsec_per_tick; gint length;