OSDN Git Service

* [BugFix] Replace usleep() func to My MicroSleep() Func. ( for usleep() func precis...
authorkoinec(Koine Yuusuke) <koinec@users.sourceforge.jp>
Sat, 1 Feb 2014 13:21:41 +0000 (22:21 +0900)
committerkoinec(Koine Yuusuke) <koinec@users.sourceforge.jp>
Sat, 1 Feb 2014 13:21:41 +0000 (22:21 +0900)
src/Makefile
src/main.c
src/micro_sleep.c [new file with mode: 0644]
src/play_event.c
src/playumidi.h

index 2f91cd6..9fe5e94 100644 (file)
@@ -2,14 +2,18 @@
 MAKE = make
 CC = gcc
 
-WITH_VERIFY    = yes
+WITH_VERIFY    = no
 
 FLAGS_DEBUG = -g
 CC_FLAGS = -Wall
 LD_FLAGS = -lpthread
 TARGET = playumidi
 HEADERS = playumidi.h
-OBJS = main.o smf.o midievent.o play_event.o
+OBJS = main.o \
+               smf.o \
+               midievent.o \
+               play_event.o \
+               micro_sleep.o
 
 .if $(WITH_VERIFY) == "yes"
 VERIFY_OBJS = verify_event.o
@@ -30,6 +34,8 @@ verify_event.o: verify_event.c $(HEADERS)
        $(CC) -c -o verify_event.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) verify_event.c
 .endif
 
+micro_sleep.o: micro_sleep.c $(HEADERS)
+       $(CC) -c -o micro_sleep.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) micro_sleep.c
 play_event.o: play_event.c $(HEADERS)
        $(CC) -c -o play_event.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) play_event.c
 midievent.o: midievent.c $(HEADERS)
index 2d56a61..1d7504a 100644 (file)
@@ -110,6 +110,8 @@ int main(
                return 0x00;
        }
 
+       MSleep_Ajust();
+
        i_err   = pthread_create( &t_thread, NULL,
                                                (void *)PlayEvent_Play, (void *)NULL );
        if( 0x00 != i_err )     {
diff --git a/src/micro_sleep.c b/src/micro_sleep.c
new file mode 100644 (file)
index 0000000..a381ddc
--- /dev/null
@@ -0,0 +1,79 @@
+
+#define        PLAYUMIDI_SRC_MSLEEP
+
+#include<stdio.h>
+#include<unistd.h>
+#include<sys/time.h>
+#include"playumidi.h"
+
+
+long   gl_min_usleep   = DEFAULT_MIN_SLEEP;
+
+
+/* ===================================================================*/
+EXTERN_FUNC_MSLEEP
+long   MSleep_Ajust(
+                       void )          {
+
+       int                                     i_cnt;
+       long                            l_times;
+       long                            l_value;
+       struct  timeval         tv_start;
+       struct  timeval         tv_end;
+
+       l_times         = 0;
+       for( i_cnt = 0; i_cnt < MSLEEP_AJUST_COUNT; i_cnt++ )   {
+
+               gettimeofday( &tv_start, NULL );
+               usleep( MSLEEP_USLEEP_TIME );
+               gettimeofday( &tv_end, NULL );
+
+               if( tv_start.tv_sec == tv_end.tv_sec )  {
+                       l_value = tv_end.tv_usec - tv_start.tv_usec;
+               } else  {
+                       l_value = (tv_end.tv_sec - tv_start.tv_sec) * 1000000;
+                       l_value += (tv_end.tv_usec + (1000000 - tv_start.tv_usec));
+               }
+
+               l_times         += l_value;
+       }
+       
+       l_times         /= MSLEEP_AJUST_COUNT; 
+       
+       gl_min_usleep   = l_times + (l_times / 12); 
+
+       return gl_min_usleep;
+}
+
+
+/* ===================================================================*/
+EXTERN_FUNC_MSLEEP
+int            MSleep_MicroSleep(
+                       long    l_usleep )      {
+       
+       long    l_diff;
+       struct  timeval         tv_start;
+       struct  timeval         tv_end;
+
+       gettimeofday( &tv_start, NULL );
+       l_diff  = 0;
+       do      {
+               if( gl_min_usleep < (l_usleep-l_diff) )
+                       { usleep( MSLEEP_USLEEP_TIME ); }
+
+               gettimeofday( &tv_end, NULL );
+
+               if( tv_start.tv_sec == tv_end.tv_sec )  {
+                       l_diff  = tv_end.tv_usec - tv_start.tv_usec;
+               } else if( tv_start.tv_sec + 1 == tv_end.tv_sec )       {
+                       l_diff  = (tv_end.tv_usec + (1000000 - tv_start.tv_usec));
+               } else  {
+                       l_diff  = (tv_end.tv_sec - tv_start.tv_sec) * 1000000;
+                       l_diff  += (tv_end.tv_usec + (1000000 - tv_start.tv_usec));
+               }
+
+       }while( l_usleep > l_diff );
+
+       return 0x00;
+}
+
index 70239ec..fb29f61 100644 (file)
@@ -201,8 +201,6 @@ EXTERN_FUNC_PLAY_EVENT
        Byte                    b_status;
        int                             i_umidi[MAX_UMIDI_PORT];
        int                             i_len;
-       //int                           i_cnt;
-       //size_t                        sz_write;
        DWord                   dw_wait;
        MidiInfo                t_midi;
 
@@ -242,7 +240,7 @@ EXTERN_FUNC_PLAY_EVENT
 
                if( 0 < p_mevent->dw_delta )    {
                        dw_wait = (p_mevent->dw_delta * gdw_deltabase);
-                       usleep( dw_wait );
+                       MSleep_MicroSleep( (long)dw_wait );
                }
 
                if( IS_PLAYSTATUS_REQUEST( gb_status ) )        {
@@ -273,19 +271,16 @@ EXTERN_FUNC_PLAY_EVENT
                        if( SMF_EVENT_SYSEX_F0 == b_status )    {
                                pb_data = (pb_vardata + p_mevent->dw_dataptr);
                                i_len   = p_mevent->dw_length;
-                               //i_len = p_mevent->b_data[1] + 1;
                        }
                        else if( SMF_EVENT_SYSEX_F7 == b_status )       {
 
                                pb_data = (pb_vardata + p_mevent->dw_dataptr);
                                i_len   = p_mevent->dw_length;
-                               //i_len = p_mevent->b_data[1];
                        }
                        else if( SMF_EVENT_META == b_status )   {
                                
                                pb_data = (pb_vardata + p_mevent->dw_dataptr);
                                i_len   = p_mevent->dw_length;
-                               //i_len = p_mevent->b_data[2] + 3;
 
                                i_len   = Play_MetaEvent( p_mevent, pb_data, i_len );
                                
index 0252d6e..152bc21 100644 (file)
@@ -1,8 +1,12 @@
 
 
-#define        MAX_UMIDI_PORT  4
-#define        DEFAULT_TEMPO   500000  /* Default tempo = 120 */
+#define        MAX_UMIDI_PORT                  4
+#define        DEFAULT_TEMPO                   500000  /* Default tempo = 120 */
 #define        UMIDIDEV_RETRY_WRITE    3
+#define DEFAULT_MIN_SLEEP              2050    /* usec */
+#define MSLEEP_USLEEP_TIME             1000
+#define MSLEEP_AJUST_COUNT             50
+
 
 
 typedef unsigned char  Byte;
@@ -156,6 +160,16 @@ EXTERN_FUNC_PLAY_EVENT void PlayEvent_Play( void *v_arg );
 EXTERN_FUNC_PLAY_EVENT int PlayEvent_Initialize( void );
 EXTERN_FUNC_PLAY_EVENT int PlayEvent_Term( void ); 
 
+
+#ifndef PLAYUMIDI_SRC_MSLEEP
+    #define EXTERN_FUNC_MSLEEP     extern
+#else
+    #define EXTERN_FUNC_MSLEEP 
+#endif
+EXTERN_FUNC_MSLEEP long        MSleep_Ajust( void );
+EXTERN_FUNC_MSLEEP int MSleep_MicroSleep( long l_usleep );
+
+
 #ifdef VERIFY_EVENT
        #ifndef PLAYUMIDI_SRC_VERIFY_EVENT
                extern int Veryfy_Event( TrackInfo *p_track_start, Word uw_tracks );