OSDN Git Service

* [BugFix] Replace usleep() func to My MicroSleep() Func. ( for usleep() func precis...
[playumidi/playumidi.git] / src / play_event.c
index 1672556..fb29f61 100644 (file)
@@ -7,26 +7,73 @@
 #include<string.h>
 #include<fcntl.h>
 #include<assert.h>
+#include<pthread.h>
 #include<sys/stat.h>
 #include<sys/types.h>
 #include<sys/uio.h>
 #include"playumidi.h"
 
-DWord  gdw_tempo;
-DWord  gdw_deltabase;
-Word   guw_division;
-int            gi_outport;
+DWord                          gdw_tempo;
+DWord                          gdw_deltabase;
+Word                           guw_division;
+int                                    gi_outport;
+Byte                           gb_status                       = PLAYSTATUS_INITIALIZE;
+pthread_mutex_t                gt_mutex_status;
 
 
 /* ===================================================================*/
+EXTERN_FUNC_PLAY_EVENT void
+       Play_RequestStop(
+                       void )          {
+
+       if( PLAYSTATUS_PREPARE != gb_status )   {
+               gb_status       = PLAYSTATUS_REQ_STOP;
+       }
+
+       return;
+}
+
+
+/* ===================================================================*/
+int    PlayEvent_StopVoiceOut_MidiPort(
+               int                             i_umidi )               {
+       
+       int             i_cnt;
+       int             i_len;
+       int             i_channel;
+       size_t  sz_write;
+       Byte    *pb_value;
+       Byte    b_value[3];
+       
+       b_value[1]      = 0x78;
+       b_value[2]      = 0x00;
+
+       for( i_channel = 0; i_channel < 16; i_channel++)        {
+               b_value[0]      = 0xb0 + (Byte)i_channel;
+               i_len           = 3;
+               pb_value        = b_value;
+
+               i_cnt   = UMIDIDEV_RETRY_WRITE;
+               for( ; (i_len >0) && (i_cnt > 0); i_cnt-- )             {
+                       sz_write        = write( i_umidi, pb_value, (size_t)i_len );
+                       i_len           -= (int)sz_write;
+                       pb_value        += (int)sz_write;
+               }
+       }
+
+       return 0x00;
+}
+               
+
+/* ===================================================================*/
 int    Play_MetaEvent(
                MidiEventInfo   *p_mevent,
                Byte                    *pb_var,
                int                             i_len )         {
 
        int             i_ret;
-       //DWord dw_value;
        Byte    b_meta;
+       Byte    b_save;
 
        assert( NULL != p_mevent );
 
@@ -45,11 +92,14 @@ int Play_MetaEvent(
                i_ret   = 0x00;
        }
        else if( SMF_META_PORT == b_meta )      {
+               
+               puts("port!!");
 
                i_ret   = 0x00;
        }
        else if( SMF_META_SMPTEOFFSET == b_meta )       {
 
+               puts("smtpe!!");
                i_ret   = 0x00;
        }
        /* Output Text for PC-Console */
@@ -59,6 +109,14 @@ int Play_MetaEvent(
                        ( SMF_META_QUEPOINT == b_meta ) || ( SMF_META_PROGRAM == b_meta ) ||
                        ( SMF_META_DEVICE == b_meta ) )         {
 
+               b_save  = *(pb_var + i_len + 3);
+               *(pb_var + i_len + 3)   = '\0';
+               printf("%s\n", (pb_var + 3) );
+               *(pb_var + i_len + 3)   = b_save;
+               i_ret   = 0x00;
+       }
+       else    {
+               i_ret   = 0x00;
        }
 
 //SMF_META_SEQUENCENO  /* Ignore for SMF0/1 */
@@ -71,52 +129,126 @@ int       Play_MetaEvent(
        return i_ret;
 }
 
+
+/* ===================================================================*/
+int MidiDevice_Write(
+               int             i_port,
+               Byte    *pb_data,
+               size_t  sz_len  )       {
+
+       int             i_cnt;
+       size_t  sz_write;
+
+       if( 0 == sz_len )       { return 0x00; }
+
+       i_cnt   = UMIDIDEV_RETRY_WRITE;
+       for( ; (sz_len >0) && (i_cnt > 0); i_cnt-- )            {
+               sz_write        = write( i_port, pb_data, sz_len );
+               sz_len  -= sz_write;
+               pb_data += (int)sz_write;
+       }
+       if( 0 < sz_len )        { return -0x01; }
+
+       return 0x00;
+}
+
+
 /* ===================================================================*/
 EXTERN_FUNC_PLAY_EVENT
-       int     Play_Event(
-                       void )          {
+       int     PlayEvent_Initialize(
+                       void  )         {
+
+       int             i_result;
+
+       i_result        = pthread_mutex_init( &gt_mutex_status, NULL);
+       if( 0x00 != i_result )          {
+               puts("Error!!: Cannot Init. pthread-mutex");
+               return i_result;
+       }
+
+       return  i_result;
+}
+
+
+/* ===================================================================*/
+EXTERN_FUNC_PLAY_EVENT
+       int     PlayEvent_Term(
+                       void  )         {
+
+       int             i_result;
+
+       i_result        = pthread_mutex_destroy( &gt_mutex_status );
+       if( 0x00 != i_result )          {
+               puts("Error!!: Cannot Destroy pthread-mutex");
+               return i_result;
+       }
+       gb_status       = PLAYSTATUS_INITIALIZE;
+
+       return  i_result;
+}
+
+
+/* ===================================================================*/
+EXTERN_FUNC_PLAY_EVENT
+       void    PlayEvent_Play(
+                       void *v_arg )           {
 
        MidiEventInfo   *p_mevent;
        Byte                    *pb_vardata;
+       DWord                   dw_events;
+
        Byte                    *pb_data;
        Byte                    b_status;
-       //int                           i_outdev;
        int                             i_umidi[MAX_UMIDI_PORT];
        int                             i_len;
-       //int                           i_result;
-       size_t                  sz_write;
-       DWord                   dw_events;
-       DWord                   dw_max_events;
        DWord                   dw_wait;
-       //Word                  uw_division;
+       MidiInfo                t_midi;
+
+       
+       /* *** MUTEX LOCK!!: gt_mutex_status *** */
+       //pthread_mutex_lock( &gt_mutex_status );
+
+       gb_status       = PLAYSTATUS_PREPARE;
 
-       p_mevent        = MidiEvent_GetMidiEventPointer();
+       MidiEvent_GetMidiInfo( &t_midi );
+       p_mevent        = t_midi.p_event;
        assert( NULL != p_mevent );
 
-       pb_vardata      = MidiEvent_GetVarDataPointer();
+       pb_vardata      = t_midi.pb_vardata;
        assert( NULL != pb_vardata );
 
-       dw_max_events   = MidiEvent_GetMidiEvents();
-       guw_division    = MidiEvent_GetMidiDivision();
+       guw_division    = t_midi.uw_division;
 
        gdw_tempo       = DEFAULT_TEMPO;                /* Default tempo = 120 */
        gdw_deltabase   = gdw_tempo / (DWord)guw_division;
 
+
        i_umidi[0]      = open("/dev/umidi1.0", O_RDWR );
        if( 0 > i_umidi[0] )    {
                puts("Error!!");
-               return 0x00;
+               return;
        }
 
-       for( dw_events = 0; dw_events < dw_max_events; dw_events++ )    {
+       gb_status       = PLAYSTATUS_PLAYING;
+
+       //pthread_mutex_unlock( &gt_mutex_status );
+       /* *** MUTEX UNLOCK!!: gt_mutex_status *** */
+
+       for( dw_events = 0; dw_events < t_midi.dw_max_events; dw_events++ )     {
 
                assert( NULL != p_mevent );
 
-               dw_wait = (p_mevent->dw_delta * gdw_deltabase);
-               /* wait for delta */
-               /*printf( "Wait: %08d -> %x %x %x\n", dw_wait, p_mevent->b_data[0],
-                                       p_mevent->b_data[1], p_mevent->b_data[2] );*/
-               usleep( dw_wait );
+               if( 0 < p_mevent->dw_delta )    {
+                       dw_wait = (p_mevent->dw_delta * gdw_deltabase);
+                       MSleep_MicroSleep( (long)dw_wait );
+               }
+
+               if( IS_PLAYSTATUS_REQUEST( gb_status ) )        {
+                       if( PLAYSTATUS_REQ_STOP == gb_status )  {
+                               PlayEvent_StopVoiceOut_MidiPort( i_umidi[0] );
+                               break;
+                       }
+               }
 
                b_status        = p_mevent->b_data[0] & 0xf0;   
                if( (SMF_EVENT_NOTEOFF == b_status ) || ( SMF_EVENT_NOTEON == b_status ) ||
@@ -138,17 +270,17 @@ EXTERN_FUNC_PLAY_EVENT
                        
                        if( SMF_EVENT_SYSEX_F0 == b_status )    {
                                pb_data = (pb_vardata + p_mevent->dw_dataptr);
-                               i_len   = p_mevent->b_data[1] + 1;
+                               i_len   = p_mevent->dw_length;
                        }
                        else if( SMF_EVENT_SYSEX_F7 == b_status )       {
 
                                pb_data = (pb_vardata + p_mevent->dw_dataptr);
-                               i_len   = p_mevent->b_data[1];
+                               i_len   = p_mevent->dw_length;
                        }
                        else if( SMF_EVENT_META == b_status )   {
                                
                                pb_data = (pb_vardata + p_mevent->dw_dataptr);
-                               i_len   = p_mevent->b_data[2] + 3;
+                               i_len   = p_mevent->dw_length;
 
                                i_len   = Play_MetaEvent( p_mevent, pb_data, i_len );
                                
@@ -156,15 +288,13 @@ EXTERN_FUNC_PLAY_EVENT
                }
 
 
-               if( 0 < i_len )         {
-                       sz_write        = write( i_umidi[0], pb_data, (size_t)i_len );
-               }               
+               MidiDevice_Write( i_umidi[0], pb_data, (size_t)i_len );
 
                p_mevent++;
        }
 
        close( i_umidi[0] );
 
-       return 0x00;
+       return;
 }