OSDN Git Service

* Support for Japanese-MetaText output by libiconv
authorkoinec(Koine Yuusuke) <koinec@users.sourceforge.jp>
Tue, 11 Feb 2014 12:31:19 +0000 (21:31 +0900)
committerkoinec(Koine Yuusuke) <koinec@users.sourceforge.jp>
Tue, 11 Feb 2014 12:31:19 +0000 (21:31 +0900)
  (but Not Support LanguageCode Option Setting & Get Terminal Support LanguageCode yet.)
  (Merge from branch TCK33122)

src/Makefile
src/main.c
src/midievent.c
src/play_event.c
src/playumidi.h
src/read_smf.c
src/verify_event.c

index 36f4910..544f117 100644 (file)
@@ -32,6 +32,7 @@ MAKE = make
 CC = gcc
 
 WITH_VERIFY    = no
+WITH_JAPANESE = yes
 
 FLAGS_DEBUG = -g
 CC_FLAGS = -Wall
@@ -46,36 +47,35 @@ OBJS = main.o \
                midi_device.o
 
 .if $(WITH_VERIFY) == "yes"
-VERIFY_OBJS = verify_event.o
-FLAGS_VERIFY = -DVERIFY_EVENT
-.else
-VERIFY_OBJS =
-FLAGS_VERIFY = 
+OBJS += verify_event.o
+CC_FLAGS += -DVERIFY_EVENT
+.endif
+
+.if $(WITH_JAPANESE) == "yes"
+CC_FLAGS += -DSUPPORT_JAPANESE -I/usr/local/include
+LD_FLAGS += -liconv -L/usr/local/lib
 .endif
 
 
 all: $(TARGET)
 
-$(TARGET): $(OBJS) $(VERIFY_OBJS)
-       gcc -o $(TARGET) $(LD_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) $(OBJS) $(VERIFY_OBJS)
+$(TARGET): $(OBJS)
+       gcc -o $(TARGET) $(LD_FLAGS) $(FLAGS_DEBUG) $(OBJS)
 
-.if $(WITH_VERIFY) == "yes"
 verify_event.o: verify_event.c $(HEADERS)
-       $(CC) -c -o verify_event.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) verify_event.c
-.endif
-
+       $(CC) -c -o verify_event.o $(CC_FLAGS) $(FLAGS_DEBUG) verify_event.c
 midi_device.o: midi_device.c $(HEADERS)
-       $(CC) -c -o midi_device.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) midi_device.c
+       $(CC) -c -o midi_device.o $(CC_FLAGS) $(FLAGS_DEBUG) midi_device.c
 micro_sleep.o: micro_sleep.c $(HEADERS)
-       $(CC) -c -o micro_sleep.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) micro_sleep.c
+       $(CC) -c -o micro_sleep.o $(CC_FLAGS) $(FLAGS_DEBUG) 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
+       $(CC) -c -o play_event.o $(CC_FLAGS) $(FLAGS_DEBUG) play_event.c
 midievent.o: midievent.c $(HEADERS)
-       $(CC) -c -o midievent.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) midievent.c
+       $(CC) -c -o midievent.o $(CC_FLAGS) $(FLAGS_DEBUG) midievent.c
 read_smf.o: read_smf.c $(HEADERS)
-       $(CC) -c -o read_smf.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) read_smf.c
+       $(CC) -c -o read_smf.o $(CC_FLAGS) $(FLAGS_DEBUG) read_smf.c
 main.o: main.c $(HEADERS)
-       $(CC) -c -o main.o $(CC_FLAGS) $(FLAGS_DEBUG) $(FLAGS_VERIFY) main.c
+       $(CC) -c -o main.o $(CC_FLAGS) $(FLAGS_DEBUG) main.c
 
 clean:
        rm *.o
index 5a4059a..d07ce31 100644 (file)
@@ -43,6 +43,8 @@ MIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDI*/
 char   *gpstr_smfname;
 char   *gpstr_devname;
 char   *gpstr_mididev[MAX_UMIDI_PORT];
+char   *gpstr_lang_smf[30];
+char   *gpstr_lang_terminal[30];
 
 
 /* ===================================================================*/
@@ -143,6 +145,10 @@ void
        fputs( "  -r                  Not auto-append XG/GS/GM REST code\n", stderr );
        fputs( "  -q                  Quiet mode (No output Meta-Event Text for console)\n", stderr );
        fputs( "  -v                  Verbose mode\n", stderr );
+#ifdef SUPPORT_JAPANESE
+       fputs( "  -l                  MIDI file Language-Code (sjis/euc/utf8 only)\n", stderr );
+       fputs( "  -t                  Output Text Language-Code (sjis/euc/utf8 only)\n", stderr );
+#endif
        fputs( "  -h                  Help (This Message)\n", stderr );
 
        return;
@@ -205,8 +211,20 @@ int main(
        if( IS_MSGVERBOSE )     
                { printf( "  [MIDI File ]: %s\n", gpstr_smfname ); }
 
+#ifdef SUPPORT_JAPANESE
+       gt_iconv        = iconv_open( DEFAULT_TERM_LANGCODE, DEFAULT_SMF_LANGCODE );
+       if( (iconv_t)(-1) == gt_iconv )         {
+               fprintf(stderr, "Error!!: Can't Initialize libiconv (%d)\n", errno);
+               return 0x01;
+       }
+#endif
+
        Play_SMF();
 
+#ifdef SUPPORT_JAPANESE
+       iconv_close( gt_iconv );
+#endif
+
        return 0x00;
 }
 
index 5b75f87..94346cb 100644 (file)
@@ -41,6 +41,7 @@ Byte                  *gpb_vardata    = NULL;
 
 Word                   guw_division;
 DWord                  gdw_max_events;
+DWord                  gdw_max_metasize;
 
 
 /* ===================================================================*/
@@ -50,6 +51,7 @@ EXTERN_FUNC_MIDIEVENT int
 
        p_midi->uw_division                             = guw_division;
        p_midi->dw_max_events                   = gdw_max_events;
+       p_midi->dw_max_metasize                 = gdw_max_metasize;
        p_midi->p_event                                 = gp_event;
        p_midi->pb_vardata                              = gpb_vardata;
        
@@ -98,14 +100,17 @@ EXTERN_FUNC_MIDIEVENT   Byte *
 /* ===================================================================*/
 EXTERN_FUNC_MIDIEVENT  int
        MidiEvent_AllocMidiVarData(
-                       DWord   dw_size )       {
+                       DWord   dw_varsize,
+                       DWord   dw_metasize )   {
 
        if( NULL != gpb_vardata )       { return -0x01; }
 
-       gpb_vardata = (Byte *)malloc( dw_size );
+       gpb_vardata = (Byte *)malloc( dw_varsize );
        if( NULL == gpb_vardata )       { return -0x02; }
 
-       memset( gpb_vardata, 0x00, dw_size );
+       memset( gpb_vardata, 0x00, dw_varsize );
+
+       gdw_max_metasize        = dw_metasize;
        
        return 0x00;
 }
index 6cef64b..4eab74f 100644 (file)
@@ -38,6 +38,7 @@ MIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDI*/
 #include<fcntl.h>
 #include<assert.h>
 #include<pthread.h>
+#include<errno.h>
 #include<sys/stat.h>
 #include<sys/types.h>
 #include<sys/uio.h>
@@ -50,6 +51,10 @@ int                                  gi_outport;
 int                                    gi_prefix_channel;
 Byte                           gb_status                       = PLAYSTATUS_INITIALIZE;
 pthread_mutex_t                gt_mutex_status;
+#ifdef SUPPORT_JAPANESE
+char                           *gpstr_buffer;
+size_t                         gsz_buffer;
+#endif
 
 
 /* ===================================================================*/
@@ -86,22 +91,67 @@ int PlayEvent_StopVoiceOut(
 }
                
 
+#ifdef SUPPORT_JAPANESE
+/* ===================================================================*/
+int    PlayEvent_ConvLanguage_toTerminal(
+               char    *pstr_dest, 
+               size_t  sz_dest,
+               char    *pstr_src, 
+               size_t  sz_src )        {
+
+       int             i_errcount      = 0;
+       size_t          sz_result;
+
+       while(( 0 < sz_src ) && ( ICONV_PERMIT_ERRCOUNT > i_errcount ))         {
+               sz_result       = iconv( gt_iconv,
+                               (const char **)&pstr_src, &sz_src,
+                               &pstr_dest, &sz_dest );
+               if( -1 == sz_result )   {
+                       if( 0 < sz_src )        {
+                               *pstr_dest++    = *pstr_src++;
+                               sz_src--;
+                               sz_dest--;
+                       }
+                       i_errcount++;
+               }
+       }
+
+       *pstr_dest      = '\0';
+
+       return i_errcount;
+}
+#endif
+
 /* ===================================================================*/
 int    Play_OutputText_fromMetaEvent(
                Byte    *pb_str,
                int             i_len,
                char    *pstr_title )           {
 
-       Byte    b_save;
+       Byte            b_save;
+       char            *pstr_dest;
+       int                     i_err;
 
        if( IS_MSGQUIET )       { return 0x00; }
 
+       i_err   = 0;
        b_save  = *(pb_str + i_len);
        *(pb_str + i_len)       = '\0';
+#ifdef SUPPORT_JAPANESE
+       i_err   = PlayEvent_ConvLanguage_toTerminal( gpstr_buffer,
+                                       (size_t)(gsz_buffer - 1), (char *)pb_str, (size_t)i_len );
+       if( ICONV_PERMIT_ERRCOUNT <= i_err )
+               { fprintf( stderr, "Error!!: iconv function error (%d)\n", errno ); }
+       pstr_dest       = gpstr_buffer;
+#else
+       pstr_dest       = (char *)pb_str;
+#endif
+
        if( -1 == gi_prefix_channel )
-               { printf("  [%-10s]: %s\n", pstr_title, pb_str ); }
+               { printf("  [%-10s]: %s\n", pstr_title, pstr_dest ); }
        else
-               { printf("  [%-10s]: (Channel:%01d) %s\n", pstr_title, gi_prefix_channel, pb_str ); }
+               { printf("  [%-10s]: (Channel:%01d) %s\n", pstr_title, gi_prefix_channel, pstr_dest ); }
+
        *(pb_str + i_len)       = b_save;
 
        return 0x00;
@@ -304,6 +354,16 @@ EXTERN_FUNC_PLAY_EVENT
        pb_vardata      = t_midi.pb_vardata;
        assert( NULL != pb_vardata );
 
+#ifdef SUPPORT_JAPANESE
+       gsz_buffer      = ((t_midi.dw_max_metasize * 3) / 2) + 1;
+       gpstr_buffer = (char *)malloc( gsz_buffer );
+       if( NULL == gpstr_buffer )      {
+               fprintf( stderr,
+                       "Error!!: Can't Alloc LangCode Convert Buffer Memory (%d)\n", errno );
+               return;
+       } 
+#endif
+
        guw_division    = t_midi.uw_division;
 
        gdw_tempo       = DEFAULT_TEMPO;                /* Default tempo = 120 */
@@ -372,6 +432,10 @@ EXTERN_FUNC_PLAY_EVENT
                p_mevent++;
        }
 
+#ifdef SUPPORT_JAPANESE
+       if( NULL != gpstr_buffer )      { free( gpstr_buffer ); }
+#endif
+
        return;
 }
 
index e82defd..962b1a2 100644 (file)
@@ -28,15 +28,24 @@ OF THE POSSIBILITY OF SUCH DAMAGE.
 
 MIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDIMIDI*/
 
+#ifdef SUPPORT_JAPANESE
+#include<iconv.h>
+#endif
+
 #define        STRING_VERSION                  "Version 0.80 (2014/02/09)"
 
 #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_USLEEP_TIME             1000    /* This value is depended on OS */
 #define MSLEEP_AJUST_COUNT             50
 #define        DEFAULT_DEV_NAME                "umidi"
+#define        ICONV_PERMIT_ERRCOUNT   5
+
+/* Follow defines is Enable "SUPPORT_JAPANESE" mode when building playumidi */
+#define        DEFAULT_SMF_LANGCODE    "SHIFT_JISX0213"
+#define        DEFAULT_TERM_LANGCODE   "EUC-JP"
 
 
 typedef unsigned char  Byte;
@@ -83,7 +92,8 @@ typedef       struct  {
 typedef struct {
        Word                    uw_division;
        DWord                   dw_max_events;
-
+       DWord                   dw_max_metasize;
+       
        MidiEventInfo   *p_event;
        Byte                    *pb_vardata;
 } MidiInfo;
@@ -241,6 +251,9 @@ typedef struct      {
        #define EXTERN_PARAM_MAIN
 #endif
 EXTERN_PARAM_MAIN      Byte    gb_mode;
+#ifdef SUPPORT_JAPANESE
+       EXTERN_PARAM_MAIN       iconv_t         gt_iconv;
+#endif
 
 
 #ifndef        PLAYUMIDI_SRC_READ_SMF
@@ -263,7 +276,7 @@ EXTERN_FUNC_MIDIEVENT void MidiEvent_SetMidiDivision( Word uw_division ) ;
 EXTERN_FUNC_MIDIEVENT DWord MidiEvent_GetMidiEvents( void );
 EXTERN_FUNC_MIDIEVENT MidiEventInfo *MidiEvent_GetMidiEventPointer( void );
 EXTERN_FUNC_MIDIEVENT Byte *MidiEvent_GetVarDataPointer( void );
-EXTERN_FUNC_MIDIEVENT int MidiEvent_AllocMidiVarData( DWord dw_size );
+EXTERN_FUNC_MIDIEVENT int MidiEvent_AllocMidiVarData( DWord dw_varsize, DWord dw_metasize );
 EXTERN_FUNC_MIDIEVENT int MidiEvent_FreeMidiVarData( void );
 EXTERN_FUNC_MIDIEVENT int MidiEvent_AllocMidiEventInfo( DWord dw_events );
 EXTERN_FUNC_MIDIEVENT int MidiEvent_FreeMidiEvnetInfo( void );
index 4577eb3..2403cef 100644 (file)
@@ -224,8 +224,9 @@ Word CheckSMF_Vendor(
 
 /* ===================================================================*/
 int    CheckSMFTrack(
-               DWord   *dw_maxevents,
-               DWord   *dw_maxvarsize,
+               DWord   *dw_max_events,
+               DWord   *dw_max_varsize,
+               DWord   *dw_max_metasize,
                Word    *w_dataflag )
 {
        int             i_result;
@@ -238,12 +239,14 @@ int       CheckSMFTrack(
        DWord   dw_trksize;
        DWord   dw_events;
        DWord   dw_varsize;
+       DWord   dw_metasize;
        DWord   dw_delta;
        DWord   dw_temp;
        TrackInfo       *p_track;
 
        dw_events               = 0;
        dw_varsize              = 0;
+       dw_metasize             = 0;
 
        w_flag                  = 0x0000;
 
@@ -328,6 +331,9 @@ int CheckSMFTrack(
                                        dw_varsize      += (dw_temp + i_temp + 2);
                                        pb_now          += (dw_temp + i_temp + 2);
                                        dw_trksize      -= (dw_temp + i_temp + 2);
+                                       
+                                       if( dw_metasize < dw_temp )
+                                               { dw_metasize   = dw_temp; }
 
                                        if( SMF_META_TRACKEND == *(pb_now - (dw_temp + i_temp + 1)) )   {
                                                if( 0 != dw_trksize )   {
@@ -363,8 +369,9 @@ int CheckSMFTrack(
                }
        }
 
-       *dw_maxevents                   = dw_events;
-       *dw_maxvarsize                  = dw_varsize;
+       *dw_max_events                  = dw_events;
+       *dw_max_varsize                 = dw_varsize;
+       *dw_max_metasize                = dw_metasize;
        *w_dataflag                             = w_flag;
 
        return  0x00;
@@ -430,7 +437,8 @@ int SMF_SetMidiResetEvent(
                        dw_varsize              += MIDI_RESETSIZE_XG;
 
                        if( IS_MSGVERBOSE )
-                               { fputs( " Auto Append XG-RESET Event before first MIDI Event.\n", stderr ); }
+                               { fputs( "  [playumidi ]: Auto Append XG-RESET Event before first MIDI Event.\n",
+                                               stderr ); }
                }
                else if( w_dataflag & DATAFLAG_GS )     {
                        /* GS Reset ------------------------------*/
@@ -445,7 +453,8 @@ int SMF_SetMidiResetEvent(
                        dw_varsize              += MIDI_RESETSIZE_GS;
 
                        if( IS_MSGVERBOSE )
-                               { fputs( " Auto Append GS-RESET Event before first MIDI Event.\n", stderr ); }
+                               { fputs( "  [playumidi ]: Auto Append GS-RESET Event before first MIDI Event.\n",
+                                               stderr ); }
                }
                else    {
                        /* GM Reset ------------------------------*/
@@ -460,7 +469,8 @@ int SMF_SetMidiResetEvent(
                        dw_varsize              += MIDI_RESETSIZE_GM;
 
                        if( IS_MSGVERBOSE )
-                               { fputs( " Auto Append GM-RESET Event before first MIDI Event.\n", stderr ); }
+                               { fputs( "  [playumidi ]: Auto Append GM-RESET Event before first MIDI Event.\n",
+                                               stderr ); }
                }
 
                p_mevent++;
@@ -700,6 +710,7 @@ EXTERN_FUNC_READ_SMF int
        Word                    w_dataflag;
        DWord                   dw_max_events           = 0;
        DWord                   dw_max_varsize          = 0;
+       DWord                   dw_max_metasize         = 0;
        
        pb_now  = pb_fbuf;
        
@@ -717,14 +728,16 @@ EXTERN_FUNC_READ_SMF int
        /* i_result is already 0 */
 
        /* Check & GetMemorySize from SMF ------------------------*/
-       i_result        = CheckSMFTrack( &dw_max_events, &dw_max_varsize, &w_dataflag );
+       i_result        = CheckSMFTrack( &dw_max_events, &dw_max_varsize,
+                                                                       &dw_max_metasize, &w_dataflag );
        if( 0 != i_result )             { goto goto_ReadMidiData_post; }
 
        /* Alloc MidiEventInfo ---------------------------------- */
        i_result        = MidiEvent_AllocMidiEventInfo( dw_max_events );
        if( 0x00 != i_result )  { goto goto_ReadMidiData_post; }
 
-       i_result        = MidiEvent_AllocMidiVarData( dw_max_varsize + 1 );
+       i_result        = MidiEvent_AllocMidiVarData(
+                                               dw_max_varsize + 1, dw_max_metasize );
        if( 0x00 != i_result )  {
                MidiEvent_FreeMidiEvnetInfo();
                goto goto_ReadMidiData_post;
index 669589c..dc5cbb2 100644 (file)
@@ -342,7 +342,7 @@ int Veryfy_Event(
                p_mevent++;
        }
        
-       fputs( stderr, "Verify MidiEvent is Completed!!\n");
+       fputs( "Verify MidiEvent is Completed!!\n", stderr );
 
        return 0x00;
 }