support some format.
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_format_midi.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21  
22 #include <string.h>     /*memcmp*/
23 #include <stdio.h>
24 #include <stdlib.h>     /*malloc*/
25 #include <mm_error.h>
26
27 #include "mm_debug.h"
28 #include "mm_file_utils.h"
29 #include "mm_file_format_private.h"
30 #include "mm_file_format_midi.h"
31
32 /**
33  * internal defines
34  */
35 enum {
36         AV_DEC_AUDIO_MIDI,
37         AV_DEC_AUDIO_XMF,
38         AV_DEC_AUDIO_RMF,
39 };
40
41 #define MMFILE_XMF_100          "XMF_1.00"
42 #define MMFILE_XMF_101          "XMF_1.01"
43 #define MMFILE_MXMF_200         "XMF_2.00"
44 #define MMFILE_RMF                      "IREZ"
45
46 #define AvSMW_CNVID_MMF                         (1)             /* SMAF/MA-1/MA-2/MA-3/MA-5 */
47 #define AvSMW_CNVID_PHR                         (2)             /* SMAF/Phrase L1/L2 */
48 #define AvSMW_CNVID_RMD                         (3)             /* Realtime MIDI */
49 #define AvSMW_CNVID_AUD                         (4)             /* SMAF/Audio */
50 #define AvSMW_CNVID_MID                         (5)             /* SMF */
51 #define AvSMW_CNVID_HVS                         (9)             /* HV Script */
52 #define AvSMW_CNVID_WAV                         (11)    /* WAVE */
53
54 #define AvSMW_SUCCESS                           (0)             /* success                                                              */
55 #define AvSMW_ERROR                                     (-1)    /* error                                                                */
56 #define AvSMW_ERROR_ARGUMENT            (-2)    /* error of arguments                                   */
57 #define AvSMW_ERROR_RESOURCE_OVER       (-3)    /* over specified resources                             */
58 #define AvSMW_ERROR_ID                          (-4)    /* error id number                                              */
59 #define AvSMW_ERROR_TIMEOUT                     (-5)    /* timeout                                                              */
60 #define AvSMW_ERROR_SOFTRESET           (-6)    /* error of soft reset for MA-5                 */
61
62 #define AvSMW_ERROR_FILE                        (-16)   /* file error                                                   */
63 #define AvSMW_ERROR_CONTENTS_CLASS      (-17)   /* SMAF Contents Class shows can't play */
64 #define AvSMW_ERROR_CONTENTS_TYPE       (-18)   /* SMAF Contents Type shows can't play  */
65 #define AvSMW_ERROR_CHUNK_SIZE          (-19)   /* illegal SAvF Chunk Size value                */
66 #define AvSMW_ERROR_CHUNK                       (-20)   /* illegal SAvF Track Chunk value               */
67 #define AvSMW_ERROR_UNMATCHED_TAG       (-21)   /* unmathced specified TAG                              */
68 #define AvSMW_ERROR_SHORT_LENGTH        (-22)   /* short sequence                                               */
69 #define AvSMW_ERROR_LONG_LENGTH         (-23)   /* long sequence                                                */
70 #define AvSMW_ERROR_UNSUPPORTED         (-24)   /* unsupported format                                   */
71 #define AvSMW_ERROR_NO_INFORMATION      (-25)   /* no specified information                             */
72 #define AvSMW_ERROR_HV_CONFLICT         (-26)   /* conflict about HV resource                   */
73
74 #define AvSMW_ERROR_SMF_FORMAT          (-50)   /* invalid format type != 0/1                   */
75 #define AvSMW_ERROR_SMF_TRACKNUM        (-51)   /* invalid number of tracks                             */
76 #define AvSMW_ERROR_SMF_TIMEUNIT        (-52)   /* invalid time unit                                    */
77 #define AvSMW_ERROR_SMF_CMD                     (-53)   /* invalid command byte                                 */
78
79
80 #define SINT    signed int
81 #define SINT8   signed char
82 #define SINT16  signed short
83 #define SINT32  signed long
84 #define UINT    unsigned int
85 #define UINT8   unsigned char
86 #define UINT16  unsigned short
87 #define UINT32  unsigned long
88 #define ULONG   unsigned long
89
90 /*--------------------------------------------------------------------------*/
91 /*   Defines                                                                */
92 /*--------------------------------------------------------------------------*/
93 #define SMF_TIMEBASE_SHIFT                      2                                                       /*                         */
94 #define SMF_TIMEBASE                            (1L<<SMF_TIMEBASE_SHIFT)        /* [ms]                    */
95
96 #define MAX_SMF_MESSAGES                        256                                                     /*                          */
97 #define MAX_SMF_TRACKS                          32                                                      /* Should be <= 32          */
98 #define SMF_MAX_GAIN                            76                                                      /* - 6[dB] : 90             */
99                                                                                                                                 /* -18[dB] : 45             */
100 #define MINIMUM_LENGTH                          (20)
101
102 #define MELODY_MAP                                      (0)
103 #define DRUM_MAP                                        (1)
104 #define NUM_OF_MAPS                                     (2)
105
106
107 /*--------------------------------------------------------------------------*/
108 /*   Types                                                                  */
109 /*--------------------------------------------------------------------------*/
110 typedef struct _tagMidChInfo
111 {
112         UINT32                                  dBank;                                          /* BankH&L (0x00:00..0x7F7F)       */
113         UINT32                                  dCurrBank;                                      /* BankH&L (0x00:00..0x7F7F)       */
114         UINT32                                  dProg;                                          /* ProgramChange (0..127)          */
115         UINT32                                  dVolume;                                        /* ChannelVolume (0..127)          */
116         UINT32                                  dExpression;                            /* Expression (0..127)             */
117         UINT32                                  dModulation;                            /* Modulation (0..127)             */
118         UINT32                                  dPitchBend;                                     /* PitchBendH (0..127)             */
119         UINT32                                  dBendRange;                                     /* CurrentBendRange (0..24)        */
120         UINT32                                  dPreBendRange;                          /* LatestBendRange (0..24)         */
121         UINT32                                  dPanpot;                                        /* Panpot (0..127)                 */
122         UINT32                                  dHold1;                                         /* Hold1 (0..127)                  */
123         UINT32                                  dMode;                                          /* 0:MONO, 1:POLY                  */
124         UINT32                                  dRPN;                                           /* RPN (0x00:00..0xFF7F)           */
125         UINT32                                  dMipMute;                                       /* Mute switch (1:mute)            */
126         UINT32                                  dKeyCon;                                        /* 0:Melady, 1:OFF, 2:ON           */
127         UINT32                                  dLedSync;                                       /* 0:OFF, 1:ON                     */
128         UINT32                                  dVibSync;                                       /* 0:OFF, 1:ON                     */
129         UINT32                                  dFineTune;                                      /* 0..0x3FFF                       */
130         UINT32                                  dCoaseTune;                                     /* 0..0x7F                         */
131 } MIDCHINFO, *PMIDCHINFO;
132
133 typedef struct _tagMIDPACKET
134 {
135         SINT32                                  sdDeltaTime;
136         UINT32                                  dMsgID;                                         
137         UINT32                                  dP1;                                            
138         UINT32                                  dP2;                                            
139         UINT32                                  dP3;                                            
140 } MIDPACKET, *PMIDPACKET;
141
142 typedef struct _tagTrack
143 {
144         UINT32                                  dSmfCmd;                                        /* CMD @ now                      */
145         UINT32                                  dSize;                                          /* [byte] 0 measns nothing in it. */
146         UINT8*                                  pbBase;                                         /* NULL measns nothing in it.     */
147         UINT32                                  dOffset;                                        /* offset byte                    */
148         SINT32                                  sdTicks;                                        /*                                */
149 } TRACKINFO, *PTRACKINFO;
150
151 typedef struct _tagOrderList
152 {
153         struct _tagOrderList*   pPrev;
154         struct _tagOrderList*   pNext;
155         UINT32                                  dTrack;
156         UINT32                                  dTicks;
157 } ORDERLIST, *PORDERLIST;
158
159 typedef struct _tagMidInfo
160 {
161         UINT32                                  dTimeResolution;                        /* 0..0x7fff                       */
162         UINT8*                                  pbText;                                         /*                                 */
163         UINT32                                  dSizeText;                                      /*                                 */
164         UINT8*                                  pbTitle;                                        /*                                 */
165         UINT32                                  dSizeTitle;                                     /*                                 */
166         UINT8*                                  pbCopyright;                            /*                                 */
167         UINT32                                  dSizeCopyright;                         /*                                 */
168         UINT32                                  dNumOfTracks;                           /* 1..32                           */
169         UINT32                                  dSmfFormat;                                     /* 0..1                            */
170         UINT32                                  dSetupBar;                                      /* 0:No, 1:Yes                     */
171         UINT32                                  dStart;                                         /* Index after SetupBar            */
172         UINT32                                  dVibNoteVoice;                          /* 0:No, 1:Yes                     */
173
174         SINT32                                  sdTotalTicks;                           /* Total ticks                     */
175         SINT32                                  sdDataEndTime;                          /* (22.10)[ms]                     */
176         SINT32                                  sdDelta;                                        /* (22.10)[ms]                     */
177
178         UINT32                                  dEndFlag;                                       /*                                 */
179         TRACKINFO                               TrackInfo[MAX_SMF_TRACKS];      
180         
181         struct _tagOrderList*   pTopOrderList;                          
182         struct _tagOrderList*   pDoneOrderList;                         
183         struct _tagOrderList*   pBottomOrderList;                       
184         ORDERLIST                               OrderList[MAX_SMF_TRACKS + 3];
185
186         MIDCHINFO                               ChInfo[16];                                     /*                                 */
187         UINT32                                  dValid;                                         /* 0:none, 1:Valid                 */
188
189         UINT8                                   bVoiceMap[NUM_OF_MAPS][128];/* 0:Empty, 1:Valid                */
190 } MIDINFO, *PMIDINFO;
191
192 typedef struct _tagMidGlobals
193 {
194         SINT32          sdSeqID;                                                /* Sequence ID             */
195         SINT32          sdFileID;                                               /* File ID                 */
196         UINT32          dEnable;                                                /* 0:disable               */
197         UINT32          dSetup;                                                 /* 1: Just after seek      */
198
199         UINT32          dRamBase;                                               /*                         */
200         UINT32          dRamOffset;                                             /*                         */
201         UINT32          dRamSize;                                               /*                         */
202
203         MIDINFO         DataInfo[2];                                    /*                         */
204
205         SINT32          sdSeekTime;                                             /* [ms]                    */
206         SINT32          sdLastMsgTime;                                  /* (22.10)[ms]             */
207         SINT32          sdSmfCurrentTicks;                              /* Ticks @ now             */
208         SINT32          sdSmfCurrentTime;                               /* (22.10)[ms]             */
209         SINT32          sdSmfDataEndTime;                               /* (22.10)[ms]             */
210         SINT32          sdSmfEndTime;                                   /* (22.10)[ms]             */
211         SINT32          sdSmfDelta;                                             /* (22.10)[ms]             */
212
213         UINT32          dMaxGain;                                               /* MaxGain (0..127)        */
214         UINT32          dMasterVolume;                                  /* MsaterVolume (0..127)   */
215
216         UINT32          dHoldMsgs;                                              /* Number of messages in Q */
217         UINT32          dHoldPtrR;                                              /* Pointer for Read        */
218         MIDPACKET       MsgBuffer[MAX_SMF_MESSAGES];    /* Message Q               */
219
220         UINT32          dMuteFlag;                                              /* 0:Normal, 1:MUTE        */
221
222         UINT32          dSyncNoteCh;                                    /* 0..15                   */
223         UINT32          dSyncNoteKey;                                   /* 0..127, 255:OFF         */
224         UINT32                                  dVibNote;                       /* 0:No VibiNote, 1:Yes,VibNote    */
225
226 } MIDGLOBAL, *PMIDGLOBAL;
227
228
229 /*---------------------------------------------------------------------------*/
230 /*   Globals                                                                 */
231 /*---------------------------------------------------------------------------*/
232 static PMIDGLOBAL                       gpMidInfo;
233 static PMIDINFO                         gPi;
234
235
236 static SINT32   __AvMidFile_Initialize          (void);
237 static void             __AvMidFile_Deinitialize        (void);
238 static void             __AvMidInitializeOrderList      (PMIDINFO pI);
239 static void             __AvMidSortOrderList            (PMIDINFO pI);
240 static void             __AvMidInsertOrderList          (PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks);
241 static void             __AvMidRemoveFromOrderList      (PMIDINFO pI);
242 static SINT32   __AvMidGetTrackTime                     (PMIDINFO pI, UINT32 dTrack);
243 static SINT32   __AvMidUpdateTrackTime          (PMIDINFO pI, UINT32 dTrack);
244 static void             __AvMidResetTimeInfo            (PMIDINFO pI);
245 static SINT32   __AvMidGetLeastTimeTrack        (PMIDINFO pI);
246 static SINT32   __AvGetSizeOfFileInfo           (PMIDINFO pI);
247 static SINT32   __AvCheckSizeOfMidFile          (UINT8* fp, UINT32 dFsize);
248 static int              __AvParseSkipXmf2Mid            (UINT8* pbFile, UINT32 dFSize);
249 static int              __AvGetMidiDuration                     (char* szFileName, MIDI_INFO_SIMPLE *info);
250
251
252 /* mm plugin interface */
253 int mmfile_format_read_stream_mid (MMFileFormatContext *formatContext);
254 int mmfile_format_read_frame_mid  (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
255 int mmfile_format_read_tag_mid    (MMFileFormatContext *formatContext);
256 int mmfile_format_close_mid       (MMFileFormatContext *formatContext);
257
258 EXPORT_API
259 int mmfile_format_open_mid (MMFileFormatContext *formatContext)
260 {
261         int res = MMFILE_FORMAT_FAIL;
262
263         if (NULL == formatContext || NULL == formatContext->uriFileName) {
264                 debug_error ("error: mmfile_format_open_mid\n");
265                 return MMFILE_FORMAT_FAIL;
266         }
267
268         if (formatContext->pre_checked == 0) {
269                 res = MMFileFormatIsValidMID (NULL, formatContext->uriFileName);
270                 if ( res == 0 ) {
271                         debug_error("It is not MIDI file\n");
272                         return MMFILE_FORMAT_FAIL;
273                 }
274         }
275
276         formatContext->ReadStream   = mmfile_format_read_stream_mid;
277         formatContext->ReadFrame    = mmfile_format_read_frame_mid;
278         formatContext->ReadTag      = mmfile_format_read_tag_mid;
279         formatContext->Close        = mmfile_format_close_mid;
280
281         formatContext->videoTotalTrackNum = 0;
282         formatContext->audioTotalTrackNum = 1;
283
284         formatContext->privateFormatData = NULL;
285
286         return MMFILE_FORMAT_SUCCESS;
287 }
288
289 EXPORT_API
290 int mmfile_format_read_stream_mid (MMFileFormatContext *formatContext)
291 {
292         MMFileFormatStream  *audioStream = NULL;
293         int ret = MMFILE_FORMAT_FAIL;
294         MIDI_INFO_SIMPLE *info = NULL;
295
296         if (NULL == formatContext) {
297                 debug_error ("error: invalid params\n");
298                 ret = MMFILE_FORMAT_FAIL;
299                 goto exception;
300         }
301
302         /*get infomation*/
303         info = mmfile_format_get_midi_infomation (formatContext->uriFileName);
304         if (!info) {
305                 debug_error ("failed to get infomation");
306                 goto exception;
307         }
308
309         formatContext->duration = info->duration;
310         formatContext->videoStreamId = -1;
311         formatContext->videoTotalTrackNum = 0;
312         formatContext->audioTotalTrackNum = info->track_num;
313         formatContext->nbStreams = 1;
314
315         audioStream = mmfile_malloc (sizeof(MMFileFormatStream));
316         if (NULL == audioStream) {
317                 debug_error ("error: mmfile_malloc audiostream\n");
318                 ret = MMFILE_FORMAT_FAIL;
319                 goto exception;
320         }
321
322         audioStream->streamType = MMFILE_AUDIO_STREAM;
323         audioStream->codecId = (info->is_xmf == 1) ? MM_AUDIO_CODEC_MXMF : MM_AUDIO_CODEC_MIDI;
324         audioStream->bitRate = 0;
325         audioStream->framePerSec = 0;
326         audioStream->width = 0;
327         audioStream->height = 0;
328         audioStream->nbChannel = 1; 
329         audioStream->samplePerSec = 0;
330         formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
331
332         #ifdef  __MMFILE_TEST_MODE__
333         mmfile_format_print_contents (formatContext);
334         #endif
335
336         mmfile_format_free_midi_infomation (info);
337         return MMFILE_FORMAT_SUCCESS;
338
339 exception:
340         mmfile_format_free_midi_infomation (info);
341         mmfile_free (audioStream);
342
343         return ret;
344 }
345
346 EXPORT_API
347 int mmfile_format_read_tag_mid (MMFileFormatContext *formatContext)
348 {
349         int ret= MMFILE_FORMAT_FAIL;
350         MIDI_INFO_SIMPLE *info = NULL;
351         const char *locale = MMFileUtilGetLocale (NULL);
352         unsigned int tag_len;
353         unsigned int cnv_len;
354
355         if (NULL == formatContext) {
356                 debug_error ("error: invalid params\n");
357                 ret = MMFILE_FORMAT_FAIL;
358                 goto exception;
359         }
360
361         /*get infomation*/
362         info = mmfile_format_get_midi_infomation (formatContext->uriFileName);
363         if (!info) {
364                 debug_error ("failed to get infomation");
365                 ret = MMFILE_FORMAT_FAIL;
366                 goto exception;
367         }
368
369         /**
370          * UTF8 converting.
371          */
372         if (info->title) {
373                 tag_len = strlen (info->title);
374                 cnv_len = 0;
375                 formatContext->title = mmfile_string_convert ((const char*)info->title,
376                                                                                                                 tag_len,
377                                                                                                                 "UTF-8",
378                                                                                                                 locale,
379                                                                                                                 NULL,
380                                                                                                                 (unsigned int*)&cnv_len);
381                 if (formatContext->title == NULL) {
382                         debug_warning ("failed to UTF8 convert.\n");
383                         formatContext->title = mmfile_strdup (info->title);
384                 }
385         }
386
387         if (info->copyright) {
388                 tag_len = strlen (info->copyright);
389                 cnv_len = 0;
390                 formatContext->copyright = mmfile_string_convert ((const char*)info->copyright,
391                                                                                                                 tag_len,
392                                                                                                                 "UTF-8",
393                                                                                                                 locale,
394                                                                                                                 NULL,
395                                                                                                                 (unsigned int*)&cnv_len);
396                 if (formatContext->copyright == NULL) {
397                         debug_warning ("failed to UTF8 convert.\n");
398                         formatContext->copyright = mmfile_strdup (info->copyright);
399                 }
400         }
401
402         if (info->comment) {
403                 tag_len = strlen (info->comment);
404                 cnv_len = 0;
405                 formatContext->comment = mmfile_string_convert ((const char*)info->comment,
406                                                                                                                 tag_len,
407                                                                                                                 "UTF-8",
408                                                                                                                 locale,
409                                                                                                                 NULL,
410                                                                                                                 (unsigned int*)&cnv_len);
411                 if (formatContext->comment == NULL) {
412                         debug_warning ("failed to UTF8 convert.\n");
413                         formatContext->comment = mmfile_strdup (info->comment);
414                 }
415         }
416
417 #ifdef  __MMFILE_TEST_MODE__
418         mmfile_format_print_contents (formatContext);
419 #endif
420
421         mmfile_format_free_midi_infomation (info);
422         return MMFILE_FORMAT_SUCCESS;
423
424 exception:
425         mmfile_format_free_midi_infomation (info);
426         return ret;
427 }
428
429 EXPORT_API
430 int mmfile_format_read_frame_mid (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
431 {
432   debug_error ("error: mmfile_format_read_frame_midi, no handling\n");
433
434   return MMFILE_FORMAT_FAIL;
435 }
436
437 EXPORT_API
438 int mmfile_format_close_mid (MMFileFormatContext *formatContext)
439 {
440         if (NULL == formatContext ) {
441                 debug_error ("error: invalid params\n");
442                 return MMFILE_FORMAT_FAIL;
443         }
444
445         if(formatContext->streams[MMFILE_AUDIO_STREAM]) {
446                 mmfile_free(formatContext->streams[MMFILE_AUDIO_STREAM]);
447                 formatContext->streams[MMFILE_AUDIO_STREAM] = NULL;
448         }
449
450         formatContext->ReadStream   = NULL;
451         formatContext->ReadFrame    = NULL;
452         formatContext->ReadTag      = NULL;
453         formatContext->Close        = NULL;
454
455         return MMFILE_FORMAT_SUCCESS;
456 }
457
458 static char * _lc_strdup (const char *str, unsigned int size)
459 {
460         char *t = NULL;
461         t = mmfile_malloc (size+1);
462         if (t) {
463                 memset (t, 0x00, size+1);
464                 memcpy (t, str, size);
465         }
466         return t;
467 }
468
469 MIDI_INFO_SIMPLE *
470 mmfile_format_get_midi_infomation (char* szFileName)
471 {
472         int duration = -1;
473         MIDI_INFO_SIMPLE *info = NULL;
474
475         info = mmfile_malloc (sizeof (MIDI_INFO_SIMPLE));
476         if (!info)
477                 return NULL;
478
479         /*get infomation*/
480         duration = __AvGetMidiDuration (szFileName, info);
481
482         return info;
483 }
484
485 void
486 mmfile_format_free_midi_infomation (MIDI_INFO_SIMPLE *info)
487 {
488         if (info) {
489                 if (info->title) mmfile_free (info->title);
490                 if (info->copyright) mmfile_free (info->copyright);
491                 if (info->comment) mmfile_free (info->comment);
492                 mmfile_free (info);
493         }
494 }
495
496
497
498 /**
499  * internal midi parsing functions
500  */
501
502 /****************************************************************************
503  *      __AvGetMidiDuration(char* szFileName)
504  *
505  *      Desc.
506  *              Load SMF data
507  *      Param
508  *              pbFile                  pointer to the data
509  *              dFileSize               size fo the data
510  *              dMode                   error check (0:No, 1:Yes, 2:Check, 3:OnlyInfo)
511  *              pfnFunc                 pointer of rhe callback function
512  *              pvExtArgs               Reserved
513  *      Return
514  *              >= 0 : FileID, < 0 : Error code
515  ****************************************************************************/
516 static int 
517 __AvGetMidiDuration(char* szFileName, MIDI_INFO_SIMPLE *info)
518 {
519
520         int xmfheaderSkip=0;
521         MMFileIOHandle * hFile = NULL;
522         UINT8 * pbFile= NULL;
523         UINT8 * pIMYbuf= NULL;
524         SINT32 dFileSize;
525         int     sdCurrentTime = 0;
526         // void* pvExtArgs = "mid";
527         int readed =0;
528         int ret;
529         int codecType = AV_DEC_AUDIO_MIDI;
530         int is_xmf = 0;
531
532         if ( szFileName == NULL ||  info == NULL)
533                 return -1;
534
535         // debug_msg ("URI: %s\n", szFileName);
536         /*open*/
537         ret = mmfile_open (&hFile, szFileName, MMFILE_RDONLY);
538         if (ret == MMFILE_UTIL_FAIL) {
539                 debug_error ( "open failed.\n");
540                 return -1;
541         }
542
543         /*get file size*/
544         mmfile_seek (hFile, 0L, MMFILE_SEEK_END);
545         dFileSize = mmfile_tell (hFile);
546         mmfile_seek (hFile, 0L, MMFILE_SEEK_SET);
547
548         if (dFileSize <= 0) {
549                 debug_error ("failed to get file size.\n");
550                 goto _RELEASE_RESOURCE;
551         }
552
553         /*alloc read buffer*/
554         pbFile = (UINT8 *) mmfile_malloc (sizeof(UINT8) * (dFileSize + 1));
555         if (!pbFile) {
556                 debug_error ( "memory allocation failed.\n");
557                 goto _RELEASE_RESOURCE;
558         }
559
560         /*read data*/
561         if ((readed = mmfile_read (hFile, pbFile, dFileSize) ) != dFileSize) {
562                 debug_error ( "read error. size = %d\n", readed);
563                 goto _RELEASE_RESOURCE;
564         }
565
566         /*init global workspace*/
567         if(__AvMidFile_Initialize())
568                 goto _RELEASE_RESOURCE;
569
570         /*check format*/
571         if (!(memcmp (pbFile, MMFILE_XMF_100, 8)) ||
572                 !(memcmp (pbFile, MMFILE_XMF_101, 8)) ||
573                 !(memcmp (pbFile, MMFILE_MXMF_200, 8))) {
574
575                 is_xmf = 1;
576                 codecType = AV_DEC_AUDIO_XMF;
577         } else if (!(memcmp (pbFile, MMFILE_RMF, 4))) {
578                 is_xmf = 0;
579                 codecType = AV_DEC_AUDIO_RMF;
580         } else {
581                 is_xmf = 0;
582                 codecType = AV_DEC_AUDIO_MIDI;
583         }
584
585         /*set output param*/
586         if (codecType == AV_DEC_AUDIO_RMF) {
587
588                 info->duration = sdCurrentTime = 0;             /*not yet implemented.*/
589                 info->track_num = 1;                                    /*not yet implemented.*/
590                 info->is_xmf = is_xmf;
591
592         } else {
593
594                 /*get duration. XMF/MIDI*/
595                 if(codecType ==  AV_DEC_AUDIO_XMF) {
596                         xmfheaderSkip = __AvParseSkipXmf2Mid(pbFile, dFileSize);
597                         if(xmfheaderSkip == -1)
598                                 goto _RELEASE_RESOURCE;
599
600                         sdCurrentTime = __AvCheckSizeOfMidFile(pbFile+xmfheaderSkip, dFileSize);
601                 } else {
602                         sdCurrentTime = __AvCheckSizeOfMidFile(pbFile, dFileSize);
603                 }
604
605                 if(sdCurrentTime < 0) {
606                         debug_error ("__AvGetMidiDuration: sdResult's error Code!(%d)\n", sdCurrentTime);
607                         goto _RELEASE_RESOURCE;
608                 }
609
610                 if(sdCurrentTime > 0)
611                         sdCurrentTime /= 1000;
612
613                 info->duration = sdCurrentTime;
614                 info->track_num = gPi->dNumOfTracks;
615                 info->is_xmf = is_xmf;
616
617                 info->title = _lc_strdup ((const char *)gPi->pbTitle, gPi->dSizeTitle);
618                 info->copyright = _lc_strdup ((const char *)gPi->pbCopyright, gPi->dSizeCopyright);
619                 info->comment =  _lc_strdup ((const char *)gPi->pbText, gPi->dSizeText);
620         }
621
622 _RELEASE_RESOURCE:
623
624         /*resource release*/
625         __AvMidFile_Deinitialize ();
626         mmfile_close (hFile);
627         mmfile_free (pbFile);
628         mmfile_free (pIMYbuf);
629
630         return sdCurrentTime;
631 }
632
633 static SINT32
634 __AvMidFile_Initialize(void)
635 {
636         gpMidInfo = mmfile_malloc (sizeof (MIDGLOBAL));
637
638         if (!gpMidInfo)
639                 return (AvSMW_ERROR);
640
641         memset (gpMidInfo, 0x00, sizeof (MIDGLOBAL));
642
643         gpMidInfo->sdSeqID = -1;                                        /* Sequence ID      */
644         gpMidInfo->sdFileID = -1;                                       /* File ID          */
645         gpMidInfo->dEnable = 0;                                         /* 0:disabel        */
646         gpMidInfo->DataInfo[0].dValid = 0;
647         gpMidInfo->DataInfo[1].dValid = 0;
648
649         return (AvSMW_SUCCESS);
650 }
651
652 static void
653 __AvMidFile_Deinitialize(void)
654 {
655         mmfile_free (gpMidInfo);
656 }
657
658
659 /*---------------------------------------------------------------------------*/
660 /*   Functions (internal use only)                                           */
661 /*---------------------------------------------------------------------------*/
662
663 /****************************************************************************
664  *      __AvMidInitializeOrderList(PMIDINFO pI)
665  *
666  *      Description:
667  *                      Initialize OrderList.
668  *      Param:
669  *              pI                      ... pointer to the data info
670  *      Return:
671  *                      none
672  ****************************************************************************/
673 static void 
674 __AvMidInitializeOrderList(PMIDINFO pI)
675 {
676         int ix2;
677
678         for (ix2 = 1; ix2 <= MAX_SMF_TRACKS + 1; ix2++)
679         {
680                 pI->OrderList[ix2].pPrev = &pI->OrderList[ix2 - 1];
681                 pI->OrderList[ix2].pNext = &pI->OrderList[ix2 + 1];
682                 pI->OrderList[ix2].dTrack = 0xFF;
683                 pI->OrderList[ix2].dTicks = 0xFFFFFFFFL;
684         }
685         pI->OrderList[0].pPrev = NULL;
686         pI->OrderList[0].pNext = &pI->OrderList[1];
687         pI->OrderList[MAX_SMF_TRACKS + 2].pPrev = &pI->OrderList[MAX_SMF_TRACKS + 1];
688         pI->OrderList[MAX_SMF_TRACKS + 2].pNext = NULL;
689         pI->pTopOrderList = &pI->OrderList[0];
690         pI->pDoneOrderList = &pI->OrderList[1];
691         pI->pBottomOrderList = &pI->OrderList[MAX_SMF_TRACKS + 2];
692 }
693
694
695 /****************************************************************************
696  *      __AvMidSortOrderList(PMIDINFO pI)
697  *
698  *      Description:
699  *                      Sort OrderList. (Ascending order)
700  *      Param:
701  *              pI                      ... pointer to the data info
702  *      Return:
703  *                      none
704  ****************************************************************************/
705 static void 
706 __AvMidSortOrderList(PMIDINFO pI)
707 {
708         PORDERLIST pSlot;
709         PORDERLIST pTerget;
710
711         pSlot = (pI->pTopOrderList)->pNext;
712         (pSlot->pPrev)->pNext = pSlot->pNext;
713         (pSlot->pNext)->pPrev = pSlot->pPrev;
714         pSlot->dTicks = ((UINT32)pI->TrackInfo[pSlot->dTrack].sdTicks << 5) + pSlot->dTrack;
715
716         pTerget = pSlot->pNext;
717         while (pTerget != pI->pDoneOrderList)
718         {
719                 if (pSlot->dTicks <= pTerget->dTicks) break;
720                 pTerget = pTerget->pNext;
721         }
722
723         (pTerget->pPrev)->pNext = pSlot;
724         pSlot->pPrev = pTerget->pPrev;
725         pTerget->pPrev = pSlot;
726         pSlot->pNext = pTerget;
727 }
728
729
730 /****************************************************************************
731  *      __AvMidInsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
732  *
733  *      Description:
734  *                      Add item to the top of the list.
735  *      Param:
736  *              pI                      ... pointer to the data info
737  *      Return:
738  *                      none
739  ****************************************************************************/
740 static void
741 __AvMidInsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
742 {
743         PORDERLIST pTerget;
744
745         if (pI->dNumOfTracks == 1) return;
746         if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return;
747
748         pTerget = pI->pDoneOrderList->pNext;
749         if (pTerget == pI->pBottomOrderList) return;
750         
751         pI->pDoneOrderList->pNext = pTerget->pNext;
752         (pTerget->pNext)->pPrev = pI->pDoneOrderList;
753
754         pTerget->dTrack = dTrack;
755         pTerget->dTicks = ((UINT32)sdTicks << 5) + dTrack;
756         pTerget->pPrev = pI->pTopOrderList;
757         pTerget->pNext = (pI->pTopOrderList)->pNext;
758         ((pI->pTopOrderList)->pNext)->pPrev = pTerget;
759         (pI->pTopOrderList)->pNext = pTerget;
760         
761         __AvMidSortOrderList(pI);
762 }
763
764
765 /****************************************************************************
766  *      __AvMidRemoveFromOrderList(PMIDINFO pI)
767  *
768  *      Description:
769  *                      delete Item from the top of the list.
770  *      Param:
771  *              pI                      ... pointer to the data info
772  *      Return:
773  *                      none
774  ****************************************************************************/
775 static void 
776 __AvMidRemoveFromOrderList(PMIDINFO pI)
777 {
778         PORDERLIST pSlot;
779         PORDERLIST pTerget;
780
781         pSlot = (pI->pTopOrderList)->pNext;
782         (pSlot->pPrev)->pNext = pSlot->pNext;
783         (pSlot->pNext)->pPrev = pSlot->pPrev;
784         
785         pTerget = pI->pBottomOrderList;
786         (pTerget->pPrev)->pNext = pSlot;
787         pSlot->pPrev = pTerget->pPrev;
788         pTerget->pPrev = pSlot;
789         pSlot->pNext = pTerget;
790 }
791
792
793 /****************************************************************************
794  *      __AvMidGetTrackTime(PMIDINFO pI, UINT32 dTrack)
795  *
796  *      Description:
797  *              Get the 1st DT from the list.
798  *      Param:
799  *              pI                      ... pointer to the data info
800  *              bTrack          ... #Track
801  *      Return:
802  *              0 : NoError, < 0 : Error code
803  ****************************************************************************/
804 static SINT32
805 __AvMidGetTrackTime(PMIDINFO pI, UINT32 dTrack)
806 {
807         UINT32          dTemp;
808         SINT32          dTime;
809         PTRACKINFO      pMt;
810
811         if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return (-1);
812
813         pMt = &(pI->TrackInfo[dTrack]);
814
815         dTime = 0;
816         do
817         {
818                 if (pMt->dOffset >= pMt->dSize)
819                 {
820                         pI->dEndFlag &= ~(1L << dTrack);
821                         return (-1);
822                 }
823                 dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
824                 dTime = (dTime << 7) + (dTemp & 0x7f);
825         } while (dTemp >= 0x80);
826         //debug_msg("dTime is %d\n", dTime);
827         pMt->sdTicks += dTime;
828
829         return (0);
830 }
831
832
833 /****************************************************************************
834  *      __AvMidUpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
835  *
836  *      Description:
837  *              Update the 1st DT on the Track and OrderList
838  *      Param:
839  *              pI                      ... pointer to the data info
840  *              bTrack          ... #Track
841  *      Return:
842  *              0 : NoError, < 0 : Error code
843  ****************************************************************************/
844 static SINT32
845 __AvMidUpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
846 {
847         UINT32          dTemp;
848         SINT32          dTime;
849         PTRACKINFO      pMt;
850
851         if (pI->dNumOfTracks == 1)
852         {
853                 /* Single track */
854                 if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
855                 {
856                         return (-1);
857                 }
858
859                 pMt = &(pI->TrackInfo[dTrack]);
860
861                 dTime = 0;
862                 do
863                 {
864                         if (pMt->dOffset >= pMt->dSize)
865                         {
866                                 pI->dEndFlag &= ~(1L << dTrack);
867                                 return (-1);
868                         }
869                         dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
870                         dTime = (dTime << 7) + (dTemp & 0x7f);
871                 } while (dTemp >= 0x80);
872
873                 pMt->sdTicks += dTime;
874         }
875         else
876         {
877                 /* Multi track */
878                 if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
879                 {
880                         __AvMidRemoveFromOrderList(pI);
881                         return (-1);
882                 }
883
884                 pMt = &(pI->TrackInfo[dTrack]);
885
886                 dTime = 0;
887                 do
888                 {
889                         if (pMt->dOffset >= pMt->dSize)
890                         {
891                                 pI->dEndFlag &= ~(1L << dTrack);
892                                 __AvMidRemoveFromOrderList(pI);
893                                 return (-1);
894                         }
895                         dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
896                         dTime = (dTime << 7) + (dTemp & 0x7f);
897                 } while (dTemp >= 0x80);
898
899                 pMt->sdTicks += dTime;
900                 __AvMidSortOrderList(pI);
901         }
902
903         return (0);
904 }
905
906
907 /****************************************************************************
908  *      __AvMidResetTimeInfo(PMIDINFO pI)
909  *
910  *      Description:
911  *              Reset time info
912  *      Param:
913  *              pI                      ... pointer to the data info
914  *      Return:
915  *              none
916  ****************************************************************************/
917 static void
918 __AvMidResetTimeInfo(PMIDINFO pI)
919 {
920         SINT32          sdTrack;
921         PTRACKINFO      pMt;
922
923         pI->dEndFlag = 0;
924
925         for (sdTrack = 0; sdTrack < (UINT32)pI->dNumOfTracks; sdTrack++)
926         {
927                 pMt = &(pI->TrackInfo[sdTrack]);
928
929                 pMt->dSmfCmd = 0;
930                 pMt->dOffset = 0;
931                 pMt->sdTicks = 0;
932                 if (pMt->dSize > 0) pI->dEndFlag |= (1L << sdTrack);
933         }
934         
935         __AvMidInitializeOrderList(pI);
936
937         if((UINT32)pI->dNumOfTracks > MAX_SMF_TRACKS)
938         {
939                 debug_error ("__AvMidResetTimeInfo:  Num of tracks is over MAX track number. !!\n");
940                 return;
941         }
942
943         for (sdTrack = 0; sdTrack < (UINT32)pI->dNumOfTracks; sdTrack++)
944         {
945                 __AvMidGetTrackTime(pI, (UINT32)sdTrack);
946                 pMt = &(pI->TrackInfo[sdTrack]);
947                 __AvMidInsertOrderList(pI,  (UINT32)sdTrack, pMt->sdTicks);
948         }
949 }
950
951
952 /****************************************************************************
953  *      __AvMidGetLeastTimeTrack(PMIDINFO pI)
954  *
955  *      Description:
956  *              Get the track@LeasetTime
957  *      Param:
958  *              pI                      ... pointer to the setup storage
959  *      Return:
960  *              0 : NoError, < 0 : Error
961  ****************************************************************************/
962 static SINT32
963 __AvMidGetLeastTimeTrack(PMIDINFO pI)
964 {
965         PORDERLIST      pTerget;
966
967         pTerget = (pI->pTopOrderList)->pNext;
968         if (pTerget == pI->pBottomOrderList) return (-1);
969
970         return ((UINT32)pTerget->dTrack);
971 }
972
973
974 /****************************************************************************
975  *      __AvGetSizeOfFileInfo(PMIDINFO pI)
976  *
977  *      Description:
978  *              Get SMF info from the file
979  *      Param:
980  *              pI                                      ... pointer to the setup storage
981  *      Return:
982  *              0 : NoError, < 0 : Error
983  ****************************************************************************/
984 static SINT32
985 __AvGetSizeOfFileInfo(PMIDINFO pI)
986 {
987         UINT32          dCmd;
988         UINT32          dCmd2;
989         UINT32          dSize;
990         
991         UINT32          dTemp;
992         UINT32          dTime;
993         SINT32          sdTotalTicks;
994         SINT32          sdCurrentTime;
995         SINT32          sdDelta;
996         PMIDCHINFO      pCh;
997         UINT32          dCh;
998
999         UINT32          dSetup;                 /* bit0:beat@0, bit1:tempo@0, bit2:GmOn@0, bit3:tempo@1 */
1000         PTRACKINFO      pMt;
1001         SINT32          sdTr;
1002
1003         static UINT32   dBank[16];
1004         static UINT32   dCurrBank[16];
1005         
1006         SINT32          sdNonConductorTime;
1007         SINT32          sdNonConductorTicks;
1008         UINT32          dConductorNote;
1009         dSetup = 0;
1010         sdTotalTicks = 0;
1011         sdCurrentTime = 0;
1012         sdNonConductorTime = 0x7FFFFFFF;
1013         sdNonConductorTicks = 0;
1014         dConductorNote = 0;
1015         sdDelta = (UINT32)(500 << 10) / pI->dTimeResolution;    /* default=0.5sec */
1016
1017         pI->pbText = NULL;
1018         pI->dSizeText = 0;
1019         pI->pbTitle = NULL;
1020         pI->dSizeTitle = 0;
1021         pI->pbCopyright = NULL;
1022         pI->dSizeCopyright = 0;
1023         pI->dStart = 0;
1024         pI->dSetupBar = 0;
1025         pI->dVibNoteVoice = 0;
1026         
1027         for (dCh = 0; dCh < NUM_OF_MAPS; dCh++)
1028         {
1029                 for (dTemp = 0; dTemp < 128; dTemp++)
1030                 {
1031                         pI->bVoiceMap[dCh][dTemp] = 0;
1032                 }
1033         }
1034         pI->bVoiceMap[MELODY_MAP][0] = 1;                                               /* GM Default Piano */
1035
1036         for (dCh = 0; dCh < 16; dCh++)
1037         {
1038                 dBank[dCh] = 0;
1039                 dCurrBank[dCh] = 0;
1040                 pCh = &pI->ChInfo[dCh];
1041                 pCh->dKeyCon = 0;
1042                 pCh->dVibSync = 0;
1043                 pCh->dLedSync = 0;
1044         }
1045
1046         __AvMidResetTimeInfo(pI);
1047
1048         if (pI->dSmfFormat != 0) dSetup |= 0x20;
1049
1050         while (pI->dEndFlag != 0)
1051         {
1052                 if ((pI->dEndFlag == 1) && (sdNonConductorTime == 0x7FFFFFFF))
1053                 {
1054                         sdNonConductorTime = sdCurrentTime;
1055                         sdNonConductorTicks = sdTotalTicks;
1056                         dConductorNote |= 2;
1057                 }
1058                 
1059                 if (pI->dNumOfTracks == 1)
1060                 {
1061                         sdTr = 0;
1062                 }
1063                 else
1064                 {
1065                         sdTr = __AvMidGetLeastTimeTrack(pI);
1066                         if (sdTr < 0) break;
1067                 }
1068                 pMt = &(pI->TrackInfo[sdTr]);
1069                 
1070                 dTime = pMt->sdTicks - sdTotalTicks;
1071                 sdCurrentTime += dTime * sdDelta;
1072                 sdTotalTicks = pMt->sdTicks;
1073                 if ((sdCurrentTime < 0) || (sdTotalTicks > 0x07FFFFFFL))
1074                 {
1075                         return (AvSMW_ERROR_LONG_LENGTH);
1076                 }
1077
1078                 dCmd = (UINT32)pMt->pbBase[pMt->dOffset++];
1079
1080                 if (dCmd < 0xf0)
1081                 {
1082                         /*--- MidiMsg ---*/
1083                         if (dCmd < 0x80)
1084                         {
1085                                 dCmd = pMt->dSmfCmd;
1086                                 if (dCmd < 0x80) return (AvSMW_ERROR_SMF_CMD);
1087                                 pMt->dOffset--;
1088                         } else {
1089                                 pMt->dSmfCmd = dCmd;
1090                         }
1091                         
1092                         dCh = dCmd & 0x0f;
1093                         
1094                         switch (dCmd & 0xf0)
1095                         {
1096                         case 0x90:      /* NoteOn */
1097                                 /* Conductor Track Note Check */
1098                                 if (sdTr == 0) dConductorNote |= 1;
1099                                 switch (dCurrBank[dCh] >> 8)
1100                                 {
1101                                 case 0x79:
1102                                         /* Melody */
1103                                         break;
1104
1105                                 case 0x78:
1106                                         /* Drum */
1107                                         pI->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1108                                         break;
1109
1110                                 default:
1111                                         if (dCh == 9)
1112                                         {
1113                                                 /* Unknown: default GM Drum */
1114                                                 pI->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1115                                         }
1116                                 }
1117                                 pMt->dOffset += 2;
1118                                 break;
1119                                 
1120                         case 0xC0:      /* Program change */
1121                                 switch (dBank[dCh] >> 8)
1122                                 {
1123                                 case 0x79:
1124                                         if (dBank[dCh] != 0x7906)
1125                                         {
1126                                                 /* Melody */
1127                                                 pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1128                                         }
1129                                         else
1130                                         {
1131                                                 /* Vibration Note */
1132                                                 pI->dVibNoteVoice = 1;
1133                                         }
1134                                         break;
1135
1136                                 case 0x78:
1137                                         /* Drum */
1138                                         break;
1139
1140                                 default:
1141                                         /* default GM Melody */
1142                                         if (dCh != 9)
1143                                         {
1144                                                 pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1145                                         }
1146                                 }
1147
1148                                 dCurrBank[dCh] = dBank[dCh];
1149                                 pMt->dOffset++;
1150                                 break;
1151                         
1152                         case 0xD0:      /* Channel pressure */
1153                                 pMt->dOffset++;
1154                                 break;
1155
1156                         case 0xB0:      /* Control Change */
1157                                 switch (pMt->pbBase[pMt->dOffset])
1158                                 {
1159                                 case 0x00:      /* Bank select(MSB) */
1160                                         dBank[dCh] = (dBank[dCh] & 0x00FF) | (pMt->pbBase[pMt->dOffset + 1] << 8);
1161                                         break;
1162
1163                         case 0x20:      /* Bank select (LSB) */
1164                                         dBank[dCh] = (dBank[dCh] & 0xFF00) | pMt->pbBase[pMt->dOffset + 1];
1165                                         break;
1166                                 default :
1167                                         break;
1168                                 }
1169                                 pMt->dOffset += 2;
1170                                 break;
1171
1172                         default:
1173                                 pMt->dOffset += 2;
1174                         }
1175                 }
1176                 else
1177                 {
1178                         switch (dCmd)
1179                         {
1180                         case 0xF0:                      /* SysEx */
1181                         case 0xF7:                      /* SysEx */
1182                                 pMt->dSmfCmd = 0;
1183                                 dSize = 0;
1184                                 do
1185                                 {
1186                                         dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
1187                                         dSize = (dSize << 7) + (dTemp & 0x7f);
1188                                 } while (dTemp >= 0x80);
1189                                 
1190                                 if ((dSize == 5) &&
1191                                     (pMt->pbBase[pMt->dOffset] == 0x7e) &&
1192                                     (pMt->pbBase[pMt->dOffset + 1] == 0x7f) &&
1193                                     (pMt->pbBase[pMt->dOffset + 2] == 0x09) &&
1194                                     (pMt->pbBase[pMt->dOffset + 3] == 0x01))
1195                                 {
1196                                         /* System On */
1197                                         if (sdTotalTicks == 0)
1198                                         {
1199                                                 dSetup |= 0x04;
1200                                         }
1201                                 }
1202                                 else 
1203                                 {
1204                                         if (pI->dSetupBar == 0)
1205                                         {
1206                                                 if ((dSize == 22) &&
1207                                                     (pMt->pbBase[pMt->dOffset] == 0x43) &&
1208                                                     (pMt->pbBase[pMt->dOffset + 1] == 0x79) &&
1209                                                     (pMt->pbBase[pMt->dOffset + 2] == 0x06) &&
1210                                                     (pMt->pbBase[pMt->dOffset + 3] == 0x7C)&&
1211                                                     (pMt->pbBase[pMt->dOffset + 4] == 0x02))
1212                                                 {
1213                                                         /* Channel status */
1214                                                         for (dCh = 0; dCh < 16; dCh++)
1215                                                         {
1216                                                                 pCh = &pI->ChInfo[dCh];
1217                                                                 dTemp = pMt->pbBase[pMt->dOffset + 5 + dCh];
1218                                                                 pCh->dKeyCon = (dTemp >> 2) & 0x03;
1219                                                                 pCh->dVibSync = (dTemp >> 1) & 0x01;
1220                                                                 pCh->dLedSync = dTemp & 0x01;
1221                                                         }
1222                                                 }
1223                                         }
1224                                 }
1225
1226                                 pMt->dOffset += dSize;
1227                                 break;
1228
1229                         case 0xF1:                      /* System Msg */
1230                         case 0xF3:                      /* System Msg */
1231                                 pMt->dOffset++;
1232                                 break;
1233                         
1234                         case 0xF2:                      /* System Msg */
1235                                 pMt->dOffset += 2;
1236                                 break;
1237
1238                         case 0xFF:                                                                                      /* Meta          */
1239                                 dCmd2 = (UINT32)pMt->pbBase[pMt->dOffset++];    /* Meta Command  */
1240                                 dSize = 0;                                                                              /* Size          */
1241                                 do
1242                                 {
1243                                         dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
1244                                         dSize = (dSize << 7) + (dTemp & 0x7f);
1245                                 } while (dTemp >= 0x80);
1246
1247                                 switch (dCmd2)
1248                                 {
1249                                 case 0x01:      /* Text */
1250                                         if (pI->pbText == NULL)
1251                                         {
1252                                                 pI->pbText = &pMt->pbBase[pMt->dOffset];
1253                                                 pI->dSizeText = dSize;
1254                                         }
1255                                         break;
1256
1257                                 case 0x02:      /* Copyright */
1258                                         if (pI->pbCopyright == NULL)
1259                                         {
1260                                                 pI->pbCopyright = &pMt->pbBase[pMt->dOffset];
1261                                                 pI->dSizeCopyright = dSize;
1262                                         }
1263                                         break;
1264
1265                                 case 0x06:      /* Title */
1266                                         if (pI->pbTitle == NULL)
1267                                         {
1268                                                 pI->pbTitle = &pMt->pbBase[pMt->dOffset];
1269                                                 pI->dSizeTitle = dSize;
1270                                         }
1271                                         break;
1272
1273                                 case 0x2f:              /* End */
1274                                         pI->dEndFlag &= ~(1L << sdTr);
1275                                         break;
1276                                         
1277                                 case 0x51:              /* Set Tempo */
1278                                         switch (dSize)
1279                                         {
1280                                         case 3:
1281                                         case 4:
1282                                                 dTime = ((UINT32)pMt->pbBase[pMt->dOffset] << 16) +
1283                                                         ((UINT32)pMt->pbBase[pMt->dOffset + 1] << 8) +
1284                                                          (UINT32)pMt->pbBase[pMt->dOffset + 2];
1285                                                 if ((sdTotalTicks == 0) && (dTime == 250000)) dSetup |= 0x02;
1286                                                 if (sdTotalTicks == (UINT32)pI->dTimeResolution) dSetup |= 0x08;
1287
1288                                                 /*<== I Think that Below Code is Trash!! and Erase it! (Actually I Don Know ^^)
1289                                                 dTime = (dTime << 7) / 125; */
1290
1291                                                 sdDelta = (UINT32)(dTime / pI->dTimeResolution);
1292                                         }
1293                                         break;
1294
1295                                 case 0x58:              /* Set TimeSignature */
1296                                         if ((sdTotalTicks == 0) &&
1297                                             (pMt->pbBase[pMt->dOffset] == 1) &&
1298                                             (pMt->pbBase[pMt->dOffset + 1] == 2)) dSetup |= 0x01;
1299                                         break;
1300                                 default :
1301                                         break;
1302                                 }
1303                                 pMt->dOffset += dSize;
1304                                 break;
1305                         default :
1306                                 break;
1307                         }
1308                 }
1309
1310                 if((UINT32)sdTr >= MAX_SMF_TRACKS)
1311                 {
1312                         debug_error ("__AvGetSizeOfFileInfo:  Num of tracks is over MAX track number. !!\n");
1313                         return AvSMW_ERROR_SMF_CMD;
1314                 }
1315                 __AvMidUpdateTrackTime(pI, (UINT32)sdTr);
1316
1317                 if (dSetup == 0x0F)
1318                 {
1319                         dSetup |= 0x10;
1320                         sdCurrentTime = 0;
1321                         pI->dSetupBar = 1;
1322                         pI->dStart = pI->TrackInfo[0].dOffset;
1323                 }
1324         }
1325
1326         if ((dConductorNote != 2) || (pI->dSmfFormat == 0))
1327         {
1328                 pI->sdTotalTicks = sdTotalTicks;
1329                 pI->sdDataEndTime = sdCurrentTime;
1330         }
1331         else
1332         {
1333                 pI->sdTotalTicks = sdNonConductorTicks;
1334                 pI->sdDataEndTime = sdNonConductorTime;
1335         }
1336         
1337         if (pI->dSetupBar == 0)
1338         {
1339                 for (dCh = 0; dCh < 16; dCh++)
1340                 {
1341                         pCh = &pI->ChInfo[dCh];
1342                         pCh->dKeyCon = 0;
1343                         pCh->dVibSync = 0;
1344                         pCh->dLedSync = 0;
1345                 }
1346         }
1347         if ((pI->sdDataEndTime >> 10) <= MINIMUM_LENGTH) return (AvSMW_ERROR_SHORT_LENGTH);
1348
1349         // debug_msg("__AvGetSizeOfFileInfo/Done\n");
1350
1351         return pI->sdDataEndTime;
1352 }
1353
1354
1355 /****************************************************************************
1356  *      __AvCheckSizeOfMidFile(UINT8* fp, UINT32 dFsize)
1357  *
1358  *      Description:
1359  *              Check SMF structure
1360  *      Param:
1361  *              fp                      ... pointer to the data
1362  *              dFsize          ... size fo the data
1363  *              dMode           ... error check (0:No, 1:Yes, 2:ErrorCheck, 3:CNTI)
1364  *      Return:
1365  *              0 : NoError, < 0 : Error
1366  ****************************************************************************/
1367 static SINT32
1368 __AvCheckSizeOfMidFile(UINT8* src_fp, UINT32 dFsize)
1369 {
1370         UINT32  dTemp;
1371         UINT32  dSize;
1372         PMIDINFO pI = NULL;
1373         UINT32  dFormat;
1374         UINT32  dNumOfTracks;
1375         UINT32  i;
1376         UINT8 *fp = src_fp;
1377         // debug_msg ("input param: %p, %d\n", fp , dFsize);
1378         while (dFsize >= 22)
1379         {
1380                 dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
1381                         ((UINT32)fp[2] << 8) + (UINT32)fp[3];
1382                 if (dTemp == 0x4D546864)        break;          /* 'MThd' */
1383                 fp ++;
1384                 dFsize --;
1385         }
1386
1387         // debug_msg("__AvCheckSizeOfMidFile(): MThd Position is dFsize(%d)\n", dFsize);
1388
1389         if (dFsize < 22)
1390         {
1391                 debug_error ("__AvCheckSizeOfMidFile Error / Too small size\n");
1392                 return (AvSMW_ERROR_FILE);
1393         }
1394
1395         fp += 4;
1396         dFsize -= 4;
1397
1398         /*--- Check size ----------------------------------------------------*/
1399         dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
1400                 ((UINT32)fp[2] << 8) + (UINT32)fp[3];
1401         
1402         if (dTemp != 6)
1403         {
1404                 debug_error ("__AvCheckSizeOfMidFile Error / Size != 6\n");
1405                 return (AvSMW_ERROR_CHUNK_SIZE);
1406         }
1407         
1408         fp += 4;
1409         dFsize -= 4;
1410
1411         if (gpMidInfo->DataInfo[1].dValid == 1) return (AvSMW_ERROR);
1412                 pI = &gpMidInfo->DataInfo[1];
1413         
1414         /**
1415          * set global val
1416          */
1417
1418         /*--- Check format -------------------------------------------------*/
1419         dFormat = ((UINT32)fp[0] << 8) + (UINT32)fp[1];
1420         if (dFormat > 1)
1421         {
1422                 debug_error ("__AvCheckSizeOfMidFile Error/ Not Format 0 or 1\n");
1423                 return (AvSMW_ERROR_SMF_FORMAT);
1424         }
1425         
1426         /*--- Check number of tracks ---------------------------------------*/
1427         dNumOfTracks = (SINT32)((UINT32)fp[2] << 8) + (UINT32)fp[3];
1428         if (dNumOfTracks == 0)
1429         {
1430                 debug_error ("__AvCheckSizeOfMidFile Error/ Number of Tracks = 0\n");
1431                 return (AvSMW_ERROR_SMF_TRACKNUM);
1432         }
1433         if ((dFormat == 0) && (dNumOfTracks != 1))
1434         {
1435                 debug_error ("__AvCheckSizeOfMidFile Error/ Number of Tracks > 1\n");
1436                 return (AvSMW_ERROR_SMF_TRACKNUM);
1437         }
1438         
1439         if (dNumOfTracks > MAX_SMF_TRACKS) dNumOfTracks = MAX_SMF_TRACKS;
1440         pI->dNumOfTracks = (UINT8)dNumOfTracks;
1441
1442         /*--- Check Time unit --------------------------------------------*/
1443         dTemp = ((UINT32)fp[4] << 8) + (UINT32)fp[5];
1444         pI->dTimeResolution = dTemp & 0x7fff;
1445         if (((dTemp & 0x8000) != 0) || (pI->dTimeResolution == 0))
1446         {
1447                 debug_error ("__AvCheckSizeOfMidFile Error/ Unknown TimeUnit\n");
1448                 return (AvSMW_ERROR_SMF_TIMEUNIT);
1449         }
1450         fp += 6;
1451         dFsize -= 6;
1452         
1453         for (i = 0; i < dNumOfTracks; i++)
1454         {
1455                 /*--- Check chunk name --------------------------------------------*/
1456                 while (dFsize >= 8)
1457                 {
1458                         dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
1459                                 ((UINT32)fp[2] << 8) + (UINT32)fp[3];
1460                         if (dTemp == 0x4D54726B)        break;  /* 'MTrk' */
1461                         fp ++;
1462                         dFsize --;
1463                 }
1464
1465                 if (dFsize < 8)
1466                 {
1467                         debug_error ("__AvCheckSizeOfMidFile Error/ Bad size\n");
1468                         return (AvSMW_ERROR_CHUNK_SIZE);
1469                 }
1470
1471                 /*--- Check size ----------------------------------------------------*/
1472                 dSize = ((UINT32)fp[4] << 24) + ((UINT32)fp[5] << 16) +
1473                         ((UINT32)fp[6] << 8) + (UINT32)fp[7];
1474
1475                 if (dFsize < (dSize + 8))
1476                 {
1477                         debug_error ("__AvCheckSizeOfMidFile Error/ Bad size [%ld] vs [%ld]\n", dFsize, dSize + 22);
1478                         return (AvSMW_ERROR_CHUNK_SIZE);
1479                 }
1480                 pI->TrackInfo[i].pbBase = &fp[8];
1481                 pI->TrackInfo[i].dSize = dSize;
1482                 fp += (dSize + 8);
1483                 dFsize -= (dSize + 8);
1484         }
1485         pI->dSmfFormat = dFormat;
1486
1487         /**
1488          * set global
1489          */
1490         gPi = pI;
1491  
1492         return (__AvGetSizeOfFileInfo(pI));
1493 }
1494
1495 static int
1496 __AvParseSkipXmf2Mid(UINT8* pbFile, UINT32 dFSize)
1497 {
1498         UINT32 skipVal = 0, sizeOfpbFile= dFSize;
1499         while(1)
1500         {
1501                 if(pbFile[skipVal] == 'M' && pbFile[skipVal+1] == 'T' && pbFile[skipVal+2] == 'h' && pbFile[skipVal+3] == 'd')
1502                 {
1503                         #ifdef __MMFILE_TEST_MODE__
1504                         debug_msg ("__AvParseSkipForXMF : MThd Header found!\n");
1505                         #endif
1506                         break;
1507                 }
1508                 else
1509                 {
1510                         skipVal++;
1511                         if(skipVal >= sizeOfpbFile)
1512                         {
1513                                 debug_error ("__AvParseSkipForXMF : MThd Header is not found!\n");
1514                                 debug_error ("__AvParseSkipForXMF :skipVal(%d) sizeOfpbFile(%d) \n", skipVal, sizeOfpbFile);
1515                                 return -1;
1516                         }
1517                 }
1518         }
1519
1520         // debug_msg("__AvParseSkipForXMF : skip value(%d)\n", skipVal);
1521
1522         return skipVal;
1523 }
1524