4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Haejeong Kim <backto.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <string.h> /*memcmp*/
24 #include <stdlib.h> /*malloc*/
28 #include "mm_file_utils.h"
29 #include "mm_file_format_private.h"
30 #include "mm_file_format_midi.h"
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"
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 */
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 */
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 */
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 */
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
90 /*--------------------------------------------------------------------------*/
92 /*--------------------------------------------------------------------------*/
93 #define SMF_TIMEBASE_SHIFT 2 /* */
94 #define SMF_TIMEBASE (1L<<SMF_TIMEBASE_SHIFT) /* [ms] */
96 #define MAX_SMF_MESSAGES 256 /* */
97 #define MAX_SMF_TRACKS 32 /* Should be <= 32 */
98 #define SMF_MAX_GAIN 76 /* - 6[dB] : 90 */
100 #define MINIMUM_LENGTH (20)
102 #define MELODY_MAP (0)
104 #define NUM_OF_MAPS (2)
107 /*--------------------------------------------------------------------------*/
109 /*--------------------------------------------------------------------------*/
110 typedef struct _tagMidChInfo
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;
133 typedef struct _tagMIDPACKET
140 } MIDPACKET, *PMIDPACKET;
142 typedef struct _tagTrack
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;
151 typedef struct _tagOrderList
153 struct _tagOrderList* pPrev;
154 struct _tagOrderList* pNext;
157 } ORDERLIST, *PORDERLIST;
159 typedef struct _tagMidInfo
161 UINT32 dTimeResolution; /* 0..0x7fff */
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 */
174 SINT32 sdTotalTicks; /* Total ticks */
175 SINT32 sdDataEndTime; /* (22.10)[ms] */
176 SINT32 sdDelta; /* (22.10)[ms] */
178 UINT32 dEndFlag; /* */
179 TRACKINFO TrackInfo[MAX_SMF_TRACKS];
181 struct _tagOrderList* pTopOrderList;
182 struct _tagOrderList* pDoneOrderList;
183 struct _tagOrderList* pBottomOrderList;
184 ORDERLIST OrderList[MAX_SMF_TRACKS + 3];
186 MIDCHINFO ChInfo[16]; /* */
187 UINT32 dValid; /* 0:none, 1:Valid */
189 UINT8 bVoiceMap[NUM_OF_MAPS][128];/* 0:Empty, 1:Valid */
190 } MIDINFO, *PMIDINFO;
192 typedef struct _tagMidGlobals
194 SINT32 sdSeqID; /* Sequence ID */
195 SINT32 sdFileID; /* File ID */
196 UINT32 dEnable; /* 0:disable */
197 UINT32 dSetup; /* 1: Just after seek */
199 UINT32 dRamBase; /* */
200 UINT32 dRamOffset; /* */
201 UINT32 dRamSize; /* */
203 MIDINFO DataInfo[2]; /* */
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] */
213 UINT32 dMaxGain; /* MaxGain (0..127) */
214 UINT32 dMasterVolume; /* MsaterVolume (0..127) */
216 UINT32 dHoldMsgs; /* Number of messages in Q */
217 UINT32 dHoldPtrR; /* Pointer for Read */
218 MIDPACKET MsgBuffer[MAX_SMF_MESSAGES]; /* Message Q */
220 UINT32 dMuteFlag; /* 0:Normal, 1:MUTE */
222 UINT32 dSyncNoteCh; /* 0..15 */
223 UINT32 dSyncNoteKey; /* 0..127, 255:OFF */
224 UINT32 dVibNote; /* 0:No VibiNote, 1:Yes,VibNote */
226 } MIDGLOBAL, *PMIDGLOBAL;
229 /*---------------------------------------------------------------------------*/
231 /*---------------------------------------------------------------------------*/
232 static PMIDGLOBAL gpMidInfo;
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);
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);
259 int mmfile_format_open_mid (MMFileFormatContext *formatContext)
261 int res = MMFILE_FORMAT_FAIL;
263 if (NULL == formatContext || NULL == formatContext->uriFileName) {
264 debug_error ("error: mmfile_format_open_mid\n");
265 return MMFILE_FORMAT_FAIL;
268 if (formatContext->pre_checked == 0) {
269 res = MMFileFormatIsValidMID (formatContext->uriFileName);
271 debug_error("It is not MIDI file\n");
272 return MMFILE_FORMAT_FAIL;
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;
281 formatContext->videoTotalTrackNum = 0;
282 formatContext->audioTotalTrackNum = 1;
284 formatContext->privateFormatData = NULL;
286 return MMFILE_FORMAT_SUCCESS;
290 int mmfile_format_read_stream_mid (MMFileFormatContext *formatContext)
292 MMFileFormatStream *audioStream = NULL;
293 int ret = MMFILE_FORMAT_FAIL;
294 MIDI_INFO_SIMPLE *info = NULL;
296 if (NULL == formatContext) {
297 debug_error ("error: invalid params\n");
298 ret = MMFILE_FORMAT_FAIL;
303 info = mmfile_format_get_midi_infomation (formatContext->uriFileName);
305 debug_error ("failed to get infomation");
309 formatContext->duration = info->duration;
310 formatContext->videoStreamId = -1;
311 formatContext->videoTotalTrackNum = 0;
312 formatContext->audioTotalTrackNum = info->track_num;
313 formatContext->nbStreams = 1;
315 audioStream = mmfile_malloc (sizeof(MMFileFormatStream));
316 if (NULL == audioStream) {
317 debug_error ("error: mmfile_malloc audiostream\n");
318 ret = MMFILE_FORMAT_FAIL;
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;
332 #ifdef __MMFILE_TEST_MODE__
333 mmfile_format_print_contents (formatContext);
336 mmfile_format_free_midi_infomation (info);
337 return MMFILE_FORMAT_SUCCESS;
340 mmfile_format_free_midi_infomation (info);
341 mmfile_free (audioStream);
347 int mmfile_format_read_tag_mid (MMFileFormatContext *formatContext)
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;
355 if (NULL == formatContext) {
356 debug_error ("error: invalid params\n");
357 ret = MMFILE_FORMAT_FAIL;
362 info = mmfile_format_get_midi_infomation (formatContext->uriFileName);
364 debug_error ("failed to get infomation");
365 ret = MMFILE_FORMAT_FAIL;
373 tag_len = strlen (info->title);
375 formatContext->title = mmfile_string_convert ((const char*)info->title,
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);
387 if (info->copyright) {
388 tag_len = strlen (info->copyright);
390 formatContext->copyright = mmfile_string_convert ((const char*)info->copyright,
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);
403 tag_len = strlen (info->comment);
405 formatContext->comment = mmfile_string_convert ((const char*)info->comment,
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);
417 #ifdef __MMFILE_TEST_MODE__
418 mmfile_format_print_contents (formatContext);
421 mmfile_format_free_midi_infomation (info);
422 return MMFILE_FORMAT_SUCCESS;
425 mmfile_format_free_midi_infomation (info);
430 int mmfile_format_read_frame_mid (MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
432 debug_error ("error: mmfile_format_read_frame_midi, no handling\n");
434 return MMFILE_FORMAT_FAIL;
438 int mmfile_format_close_mid (MMFileFormatContext *formatContext)
440 if (NULL == formatContext ) {
441 debug_error ("error: invalid params\n");
442 return MMFILE_FORMAT_FAIL;
445 if(formatContext->streams[MMFILE_AUDIO_STREAM]) {
446 mmfile_free(formatContext->streams[MMFILE_AUDIO_STREAM]);
447 formatContext->streams[MMFILE_AUDIO_STREAM] = NULL;
450 formatContext->ReadStream = NULL;
451 formatContext->ReadFrame = NULL;
452 formatContext->ReadTag = NULL;
453 formatContext->Close = NULL;
455 return MMFILE_FORMAT_SUCCESS;
458 static char * _lc_strdup (const char *str, unsigned int size)
461 t = mmfile_malloc (size+1);
463 memset (t, 0x00, size+1);
464 memcpy (t, str, size);
470 mmfile_format_get_midi_infomation (char* szFileName)
473 MIDI_INFO_SIMPLE *info = NULL;
475 info = mmfile_malloc (sizeof (MIDI_INFO_SIMPLE));
480 duration = __AvGetMidiDuration (szFileName, info);
486 mmfile_format_free_midi_infomation (MIDI_INFO_SIMPLE *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);
499 * internal midi parsing functions
502 /****************************************************************************
503 * __AvGetMidiDuration(char* szFileName)
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
514 * >= 0 : FileID, < 0 : Error code
515 ****************************************************************************/
517 __AvGetMidiDuration(char* szFileName, MIDI_INFO_SIMPLE *info)
521 MMFileIOHandle * hFile = NULL;
522 UINT8 * pbFile= NULL;
523 UINT8 * pIMYbuf= NULL;
525 int sdCurrentTime = 0;
526 // void* pvExtArgs = "mid";
529 int codecType = AV_DEC_AUDIO_MIDI;
532 if ( szFileName == NULL || info == NULL)
535 // printf ("URI: %s\n", szFileName);
537 ret = mmfile_open (&hFile, szFileName, MMFILE_RDONLY);
538 if (ret == MMFILE_UTIL_FAIL) {
539 debug_error ( "open failed.\n");
544 mmfile_seek (hFile, 0L, MMFILE_SEEK_END);
545 dFileSize = mmfile_tell (hFile);
546 mmfile_seek (hFile, 0L, MMFILE_SEEK_SET);
548 if (dFileSize <= 0) {
549 debug_error ("failed to get file size.\n");
550 goto _RELEASE_RESOURCE;
553 /*alloc read buffer*/
554 pbFile = (UINT8 *) mmfile_malloc (sizeof(UINT8) * (dFileSize + 1));
556 debug_error ( "memory allocation failed.\n");
557 goto _RELEASE_RESOURCE;
561 if ((readed = mmfile_read (hFile, pbFile, dFileSize) ) != dFileSize) {
562 debug_error ( "read error. size = %d\n", readed);
563 goto _RELEASE_RESOURCE;
566 /*init global workspace*/
567 if(__AvMidFile_Initialize())
568 goto _RELEASE_RESOURCE;
571 if (!(memcmp (pbFile, MMFILE_XMF_100, 8)) ||
572 !(memcmp (pbFile, MMFILE_XMF_101, 8)) ||
573 !(memcmp (pbFile, MMFILE_MXMF_200, 8))) {
576 codecType = AV_DEC_AUDIO_XMF;
577 } else if (!(memcmp (pbFile, MMFILE_RMF, 4))) {
579 codecType = AV_DEC_AUDIO_RMF;
582 codecType = AV_DEC_AUDIO_MIDI;
586 if (codecType == AV_DEC_AUDIO_RMF) {
588 info->duration = sdCurrentTime = 0; /*not yet implemented.*/
589 info->track_num = 1; /*not yet implemented.*/
590 info->is_xmf = is_xmf;
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;
600 sdCurrentTime = __AvCheckSizeOfMidFile(pbFile+xmfheaderSkip, dFileSize);
602 sdCurrentTime = __AvCheckSizeOfMidFile(pbFile, dFileSize);
605 if(sdCurrentTime < 0) {
606 debug_error ("__AvGetMidiDuration: sdResult's error Code!(%d)\n", sdCurrentTime);
607 goto _RELEASE_RESOURCE;
610 if(sdCurrentTime > 0)
611 sdCurrentTime /= 1000;
613 info->duration = sdCurrentTime;
614 info->track_num = gPi->dNumOfTracks;
615 info->is_xmf = is_xmf;
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);
625 __AvMidFile_Deinitialize ();
626 mmfile_close (hFile);
627 mmfile_free (pbFile);
628 mmfile_free (pIMYbuf);
630 return sdCurrentTime;
634 __AvMidFile_Initialize(void)
636 gpMidInfo = mmfile_malloc (sizeof (MIDGLOBAL));
639 return (AvSMW_ERROR);
641 memset (gpMidInfo, 0x00, sizeof (MIDGLOBAL));
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;
649 return (AvSMW_SUCCESS);
653 __AvMidFile_Deinitialize(void)
655 mmfile_free (gpMidInfo);
659 /*---------------------------------------------------------------------------*/
660 /* Functions (internal use only) */
661 /*---------------------------------------------------------------------------*/
663 /****************************************************************************
664 * __AvMidInitializeOrderList(PMIDINFO pI)
667 * Initialize OrderList.
669 * pI ... pointer to the data info
672 ****************************************************************************/
674 __AvMidInitializeOrderList(PMIDINFO pI)
678 for (ix2 = 1; ix2 <= MAX_SMF_TRACKS + 1; ix2++)
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;
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];
695 /****************************************************************************
696 * __AvMidSortOrderList(PMIDINFO pI)
699 * Sort OrderList. (Ascending order)
701 * pI ... pointer to the data info
704 ****************************************************************************/
706 __AvMidSortOrderList(PMIDINFO pI)
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;
716 pTerget = pSlot->pNext;
717 while (pTerget != pI->pDoneOrderList)
719 if (pSlot->dTicks <= pTerget->dTicks) break;
720 pTerget = pTerget->pNext;
723 (pTerget->pPrev)->pNext = pSlot;
724 pSlot->pPrev = pTerget->pPrev;
725 pTerget->pPrev = pSlot;
726 pSlot->pNext = pTerget;
730 /****************************************************************************
731 * __AvMidInsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
734 * Add item to the top of the list.
736 * pI ... pointer to the data info
739 ****************************************************************************/
741 __AvMidInsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
745 if (pI->dNumOfTracks == 1) return;
746 if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return;
748 pTerget = pI->pDoneOrderList->pNext;
749 if (pTerget == pI->pBottomOrderList) return;
751 pI->pDoneOrderList->pNext = pTerget->pNext;
752 (pTerget->pNext)->pPrev = pI->pDoneOrderList;
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;
761 __AvMidSortOrderList(pI);
765 /****************************************************************************
766 * __AvMidRemoveFromOrderList(PMIDINFO pI)
769 * delete Item from the top of the list.
771 * pI ... pointer to the data info
774 ****************************************************************************/
776 __AvMidRemoveFromOrderList(PMIDINFO pI)
781 pSlot = (pI->pTopOrderList)->pNext;
782 (pSlot->pPrev)->pNext = pSlot->pNext;
783 (pSlot->pNext)->pPrev = pSlot->pPrev;
785 pTerget = pI->pBottomOrderList;
786 (pTerget->pPrev)->pNext = pSlot;
787 pSlot->pPrev = pTerget->pPrev;
788 pTerget->pPrev = pSlot;
789 pSlot->pNext = pTerget;
793 /****************************************************************************
794 * __AvMidGetTrackTime(PMIDINFO pI, UINT32 dTrack)
797 * Get the 1st DT from the list.
799 * pI ... pointer to the data info
802 * 0 : NoError, < 0 : Error code
803 ****************************************************************************/
805 __AvMidGetTrackTime(PMIDINFO pI, UINT32 dTrack)
811 if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return (-1);
813 pMt = &(pI->TrackInfo[dTrack]);
818 if (pMt->dOffset >= pMt->dSize)
820 pI->dEndFlag &= ~(1L << dTrack);
823 dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
824 dTime = (dTime << 7) + (dTemp & 0x7f);
825 } while (dTemp >= 0x80);
826 //printf("dTime is %d\n", dTime);
827 pMt->sdTicks += dTime;
833 /****************************************************************************
834 * __AvMidUpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
837 * Update the 1st DT on the Track and OrderList
839 * pI ... pointer to the data info
842 * 0 : NoError, < 0 : Error code
843 ****************************************************************************/
845 __AvMidUpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
851 if (pI->dNumOfTracks == 1)
854 if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
859 pMt = &(pI->TrackInfo[dTrack]);
864 if (pMt->dOffset >= pMt->dSize)
866 pI->dEndFlag &= ~(1L << dTrack);
869 dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
870 dTime = (dTime << 7) + (dTemp & 0x7f);
871 } while (dTemp >= 0x80);
873 pMt->sdTicks += dTime;
878 if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
880 __AvMidRemoveFromOrderList(pI);
884 pMt = &(pI->TrackInfo[dTrack]);
889 if (pMt->dOffset >= pMt->dSize)
891 pI->dEndFlag &= ~(1L << dTrack);
892 __AvMidRemoveFromOrderList(pI);
895 dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
896 dTime = (dTime << 7) + (dTemp & 0x7f);
897 } while (dTemp >= 0x80);
899 pMt->sdTicks += dTime;
900 __AvMidSortOrderList(pI);
907 /****************************************************************************
908 * __AvMidResetTimeInfo(PMIDINFO pI)
913 * pI ... pointer to the data info
916 ****************************************************************************/
918 __AvMidResetTimeInfo(PMIDINFO pI)
925 for (sdTrack = 0; sdTrack < (UINT32)pI->dNumOfTracks; sdTrack++)
927 pMt = &(pI->TrackInfo[sdTrack]);
932 if (pMt->dSize > 0) pI->dEndFlag |= (1L << sdTrack);
935 __AvMidInitializeOrderList(pI);
937 if((UINT32)pI->dNumOfTracks > MAX_SMF_TRACKS)
939 debug_error ("__AvMidResetTimeInfo: Num of tracks is over MAX track number. !!\n");
943 for (sdTrack = 0; sdTrack < (UINT32)pI->dNumOfTracks; sdTrack++)
945 __AvMidGetTrackTime(pI, (UINT32)sdTrack);
946 pMt = &(pI->TrackInfo[sdTrack]);
947 __AvMidInsertOrderList(pI, (UINT32)sdTrack, pMt->sdTicks);
952 /****************************************************************************
953 * __AvMidGetLeastTimeTrack(PMIDINFO pI)
956 * Get the track@LeasetTime
958 * pI ... pointer to the setup storage
960 * 0 : NoError, < 0 : Error
961 ****************************************************************************/
963 __AvMidGetLeastTimeTrack(PMIDINFO pI)
967 pTerget = (pI->pTopOrderList)->pNext;
968 if (pTerget == pI->pBottomOrderList) return (-1);
970 return ((UINT32)pTerget->dTrack);
974 /****************************************************************************
975 * __AvGetSizeOfFileInfo(PMIDINFO pI)
978 * Get SMF info from the file
980 * pI ... pointer to the setup storage
982 * 0 : NoError, < 0 : Error
983 ****************************************************************************/
985 __AvGetSizeOfFileInfo(PMIDINFO pI)
994 SINT32 sdCurrentTime;
999 UINT32 dSetup; /* bit0:beat@0, bit1:tempo@0, bit2:GmOn@0, bit3:tempo@1 */
1003 static UINT32 dBank[16];
1004 static UINT32 dCurrBank[16];
1006 SINT32 sdNonConductorTime;
1007 SINT32 sdNonConductorTicks;
1008 UINT32 dConductorNote;
1012 sdNonConductorTime = 0x7FFFFFFF;
1013 sdNonConductorTicks = 0;
1015 sdDelta = (UINT32)(500 << 10) / pI->dTimeResolution; /* default=0.5sec */
1021 pI->pbCopyright = NULL;
1022 pI->dSizeCopyright = 0;
1025 pI->dVibNoteVoice = 0;
1027 for (dCh = 0; dCh < NUM_OF_MAPS; dCh++)
1029 for (dTemp = 0; dTemp < 128; dTemp++)
1031 pI->bVoiceMap[dCh][dTemp] = 0;
1034 pI->bVoiceMap[MELODY_MAP][0] = 1; /* GM Default Piano */
1036 for (dCh = 0; dCh < 16; dCh++)
1040 pCh = &pI->ChInfo[dCh];
1046 __AvMidResetTimeInfo(pI);
1048 if (pI->dSmfFormat != 0) dSetup |= 0x20;
1050 while (pI->dEndFlag != 0)
1052 if ((pI->dEndFlag == 1) && (sdNonConductorTime == 0x7FFFFFFF))
1054 sdNonConductorTime = sdCurrentTime;
1055 sdNonConductorTicks = sdTotalTicks;
1056 dConductorNote |= 2;
1059 if (pI->dNumOfTracks == 1)
1065 sdTr = __AvMidGetLeastTimeTrack(pI);
1066 if (sdTr < 0) break;
1068 pMt = &(pI->TrackInfo[sdTr]);
1070 dTime = pMt->sdTicks - sdTotalTicks;
1071 sdCurrentTime += dTime * sdDelta;
1072 sdTotalTicks = pMt->sdTicks;
1073 if ((sdCurrentTime < 0) || (sdTotalTicks > 0x07FFFFFFL))
1075 return (AvSMW_ERROR_LONG_LENGTH);
1078 dCmd = (UINT32)pMt->pbBase[pMt->dOffset++];
1085 dCmd = pMt->dSmfCmd;
1086 if (dCmd < 0x80) return (AvSMW_ERROR_SMF_CMD);
1089 pMt->dSmfCmd = dCmd;
1094 switch (dCmd & 0xf0)
1096 case 0x90: /* NoteOn */
1097 /* Conductor Track Note Check */
1098 if (sdTr == 0) dConductorNote |= 1;
1099 switch (dCurrBank[dCh] >> 8)
1107 pI->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1113 /* Unknown: default GM Drum */
1114 pI->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1120 case 0xC0: /* Program change */
1121 switch (dBank[dCh] >> 8)
1124 if (dBank[dCh] != 0x7906)
1127 pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1131 /* Vibration Note */
1132 pI->dVibNoteVoice = 1;
1141 /* default GM Melody */
1144 pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
1148 dCurrBank[dCh] = dBank[dCh];
1152 case 0xD0: /* Channel pressure */
1156 case 0xB0: /* Control Change */
1157 switch (pMt->pbBase[pMt->dOffset])
1159 case 0x00: /* Bank select(MSB) */
1160 dBank[dCh] = (dBank[dCh] & 0x00FF) | (pMt->pbBase[pMt->dOffset + 1] << 8);
1163 case 0x20: /* Bank select (LSB) */
1164 dBank[dCh] = (dBank[dCh] & 0xFF00) | pMt->pbBase[pMt->dOffset + 1];
1178 case 0xF0: /* SysEx */
1179 case 0xF7: /* SysEx */
1184 dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
1185 dSize = (dSize << 7) + (dTemp & 0x7f);
1186 } while (dTemp >= 0x80);
1189 (pMt->pbBase[pMt->dOffset] == 0x7e) &&
1190 (pMt->pbBase[pMt->dOffset + 1] == 0x7f) &&
1191 (pMt->pbBase[pMt->dOffset + 2] == 0x09) &&
1192 (pMt->pbBase[pMt->dOffset + 3] == 0x01))
1195 if (sdTotalTicks == 0)
1202 if (pI->dSetupBar == 0)
1204 if ((dSize == 22) &&
1205 (pMt->pbBase[pMt->dOffset] == 0x43) &&
1206 (pMt->pbBase[pMt->dOffset + 1] == 0x79) &&
1207 (pMt->pbBase[pMt->dOffset + 2] == 0x06) &&
1208 (pMt->pbBase[pMt->dOffset + 3] == 0x7C)&&
1209 (pMt->pbBase[pMt->dOffset + 4] == 0x02))
1211 /* Channel status */
1212 for (dCh = 0; dCh < 16; dCh++)
1214 pCh = &pI->ChInfo[dCh];
1215 dTemp = pMt->pbBase[pMt->dOffset + 5 + dCh];
1216 pCh->dKeyCon = (dTemp >> 2) & 0x03;
1217 pCh->dVibSync = (dTemp >> 1) & 0x01;
1218 pCh->dLedSync = dTemp & 0x01;
1224 pMt->dOffset += dSize;
1227 case 0xF1: /* System Msg */
1228 case 0xF3: /* System Msg */
1232 case 0xF2: /* System Msg */
1236 case 0xFF: /* Meta */
1237 dCmd2 = (UINT32)pMt->pbBase[pMt->dOffset++]; /* Meta Command */
1238 dSize = 0; /* Size */
1241 dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
1242 dSize = (dSize << 7) + (dTemp & 0x7f);
1243 } while (dTemp >= 0x80);
1247 case 0x01: /* Text */
1248 if (pI->pbText == NULL)
1250 pI->pbText = &pMt->pbBase[pMt->dOffset];
1251 pI->dSizeText = dSize;
1255 case 0x02: /* Copyright */
1256 if (pI->pbCopyright == NULL)
1258 pI->pbCopyright = &pMt->pbBase[pMt->dOffset];
1259 pI->dSizeCopyright = dSize;
1263 case 0x03: /* Title */
1264 if (pI->pbTitle == NULL)
1266 pI->pbTitle = &pMt->pbBase[pMt->dOffset];
1267 pI->dSizeTitle = dSize;
1271 case 0x2f: /* End */
1272 pI->dEndFlag &= ~(1L << sdTr);
1275 case 0x51: /* Set Tempo */
1280 dTime = ((UINT32)pMt->pbBase[pMt->dOffset] << 16) +
1281 ((UINT32)pMt->pbBase[pMt->dOffset + 1] << 8) +
1282 (UINT32)pMt->pbBase[pMt->dOffset + 2];
1283 if ((sdTotalTicks == 0) && (dTime == 250000)) dSetup |= 0x02;
1284 if (sdTotalTicks == (UINT32)pI->dTimeResolution) dSetup |= 0x08;
1286 /*<== I Think that Below Code is Trash!! and Erase it! (Actually I Don Know ^^)
1287 dTime = (dTime << 7) / 125; */
1289 sdDelta = (UINT32)(dTime / pI->dTimeResolution);
1293 case 0x58: /* Set TimeSignature */
1294 if ((sdTotalTicks == 0) &&
1295 (pMt->pbBase[pMt->dOffset] == 1) &&
1296 (pMt->pbBase[pMt->dOffset + 1] == 2)) dSetup |= 0x01;
1299 pMt->dOffset += dSize;
1304 if((UINT32)sdTr >= MAX_SMF_TRACKS)
1306 debug_error ("__AvGetSizeOfFileInfo: Num of tracks is over MAX track number. !!\n");
1307 return AvSMW_ERROR_SMF_CMD;
1309 __AvMidUpdateTrackTime(pI, (UINT32)sdTr);
1316 pI->dStart = pI->TrackInfo[0].dOffset;
1320 if ((dConductorNote != 2) || (pI->dSmfFormat == 0))
1322 pI->sdTotalTicks = sdTotalTicks;
1323 pI->sdDataEndTime = sdCurrentTime;
1327 pI->sdTotalTicks = sdNonConductorTicks;
1328 pI->sdDataEndTime = sdNonConductorTime;
1331 if (pI->dSetupBar == 0)
1333 for (dCh = 0; dCh < 16; dCh++)
1335 pCh = &pI->ChInfo[dCh];
1341 if ((pI->sdDataEndTime >> 10) <= MINIMUM_LENGTH) return (AvSMW_ERROR_SHORT_LENGTH);
1343 // printf("__AvGetSizeOfFileInfo/Done\n");
1345 return pI->sdDataEndTime;
1349 /****************************************************************************
1350 * __AvCheckSizeOfMidFile(UINT8* fp, UINT32 dFsize)
1353 * Check SMF structure
1355 * fp ... pointer to the data
1356 * dFsize ... size fo the data
1357 * dMode ... error check (0:No, 1:Yes, 2:ErrorCheck, 3:CNTI)
1359 * 0 : NoError, < 0 : Error
1360 ****************************************************************************/
1362 __AvCheckSizeOfMidFile(UINT8* src_fp, UINT32 dFsize)
1368 UINT32 dNumOfTracks;
1371 // printf ("input param: %p, %d\n", fp , dFsize);
1372 while (dFsize >= 22)
1374 dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
1375 ((UINT32)fp[2] << 8) + (UINT32)fp[3];
1376 if (dTemp == 0x4D546864) break; /* 'MThd' */
1381 // printf("__AvCheckSizeOfMidFile(): MThd Position is dFsize(%d)\n", dFsize);
1385 debug_error ("__AvCheckSizeOfMidFile Error / Too small size\n");
1386 return (AvSMW_ERROR_FILE);
1392 /*--- Check size ----------------------------------------------------*/
1393 dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
1394 ((UINT32)fp[2] << 8) + (UINT32)fp[3];
1398 debug_error ("__AvCheckSizeOfMidFile Error / Size != 6\n");
1399 return (AvSMW_ERROR_CHUNK_SIZE);
1405 if (gpMidInfo->DataInfo[1].dValid == 1) return (AvSMW_ERROR);
1406 pI = &gpMidInfo->DataInfo[1];
1412 /*--- Check format -------------------------------------------------*/
1413 dFormat = ((UINT32)fp[0] << 8) + (UINT32)fp[1];
1416 debug_error ("__AvCheckSizeOfMidFile Error/ Not Format 0 or 1\n");
1417 return (AvSMW_ERROR_SMF_FORMAT);
1420 /*--- Check number of tracks ---------------------------------------*/
1421 dNumOfTracks = (SINT32)((UINT32)fp[2] << 8) + (UINT32)fp[3];
1422 if (dNumOfTracks == 0)
1424 debug_error ("__AvCheckSizeOfMidFile Error/ Number of Tracks = 0\n");
1425 return (AvSMW_ERROR_SMF_TRACKNUM);
1427 if ((dFormat == 0) && (dNumOfTracks != 1))
1429 debug_error ("__AvCheckSizeOfMidFile Error/ Number of Tracks > 1\n");
1430 return (AvSMW_ERROR_SMF_TRACKNUM);
1433 if (dNumOfTracks > MAX_SMF_TRACKS) dNumOfTracks = MAX_SMF_TRACKS;
1434 pI->dNumOfTracks = (UINT8)dNumOfTracks;
1436 /*--- Check Time unit --------------------------------------------*/
1437 dTemp = ((UINT32)fp[4] << 8) + (UINT32)fp[5];
1438 pI->dTimeResolution = dTemp & 0x7fff;
1439 if (((dTemp & 0x8000) != 0) || (pI->dTimeResolution == 0))
1441 debug_error ("__AvCheckSizeOfMidFile Error/ Unknown TimeUnit\n");
1442 return (AvSMW_ERROR_SMF_TIMEUNIT);
1447 for (i = 0; i < dNumOfTracks; i++)
1449 /*--- Check chunk name --------------------------------------------*/
1452 dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
1453 ((UINT32)fp[2] << 8) + (UINT32)fp[3];
1454 if (dTemp == 0x4D54726B) break; /* 'MTrk' */
1461 debug_error ("__AvCheckSizeOfMidFile Error/ Bad size\n");
1462 return (AvSMW_ERROR_CHUNK_SIZE);
1465 /*--- Check size ----------------------------------------------------*/
1466 dSize = ((UINT32)fp[4] << 24) + ((UINT32)fp[5] << 16) +
1467 ((UINT32)fp[6] << 8) + (UINT32)fp[7];
1469 if (dFsize < (dSize + 8))
1471 debug_error ("__AvCheckSizeOfMidFile Error/ Bad size [%ld] vs [%ld]\n", dFsize, dSize + 22);
1472 return (AvSMW_ERROR_CHUNK_SIZE);
1474 pI->TrackInfo[i].pbBase = &fp[8];
1475 pI->TrackInfo[i].dSize = dSize;
1477 dFsize -= (dSize + 8);
1479 pI->dSmfFormat = dFormat;
1486 return (__AvGetSizeOfFileInfo(pI));
1490 __AvParseSkipXmf2Mid(UINT8* pbFile, UINT32 dFSize)
1492 UINT32 skipVal = 0, sizeOfpbFile= dFSize;
1495 if(pbFile[skipVal] == 'M' && pbFile[skipVal+1] == 'T' && pbFile[skipVal+2] == 'h' && pbFile[skipVal+3] == 'd')
1497 #ifdef __MMFILE_TEST_MODE__
1498 debug_msg ("__AvParseSkipForXMF : MThd Header found!\n");
1505 if(skipVal >= sizeOfpbFile)
1507 debug_error ("__AvParseSkipForXMF : MThd Header is not found!\n");
1508 debug_error ("__AvParseSkipForXMF :skipVal(%d) sizeOfpbFile(%d) \n", skipVal, sizeOfpbFile);
1514 // printf("__AvParseSkipForXMF : skip value(%d)\n", skipVal);