Unify duplicated codes regarding getting file size
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_format_imelody.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 <stdio.h>
23 #include <string.h>     /*memcmp*/
24 #include <stdlib.h>     /*malloc*/
25
26 #include "mm_file_debug.h"
27 #include "mm_file_utils.h"
28 #include "mm_file_format_private.h"
29 #include "mm_file_format_imelody.h"
30 #include "mm_file_format_midi.h"
31
32 /**
33  * Define
34  */
35 #define AV_MIDI_COUNT_MAX               1600
36 #define AV_MIDI_NOTE_MAX                256
37 #define AV_MIDI_VOL_MAX                 250
38 #define MIDI_LIMIT                              127
39 #define MIDI_MAX                                255
40
41 #define VOL_INTERVAL                    12
42
43 #define MIDI_HEADER_LENGTH              52
44
45 static unsigned char midiData[AV_MIDI_COUNT_MAX] ;
46 static unsigned char midiHeader[MIDI_HEADER_LENGTH] = {0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x4d, 0x54,
47                                                                                                         0x72, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff,
48                                                                                                         0x59, 0x02, 0x00, 0x00, 0x00, 0xff, 0x51, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xb0,
49                                                                                                         0x07, 0x00, 0x00, 0x90
50                                                                                                         };
51
52
53 static unsigned char noteTotal[AV_MIDI_COUNT_MAX];
54 static char octave[AV_MIDI_NOTE_MAX];
55 static int durationSpec[AV_MIDI_NOTE_MAX];
56 static int restSpec[AV_MIDI_NOTE_MAX];
57
58 static  struct {
59         char flat_sharp;
60         char note;
61         char duration;
62         char duration_specifier;
63         char rest;
64         char rest_specifier;
65         char vol;
66 } Melody[AV_MIDI_NOTE_MAX];
67
68 static  struct {
69         int note;
70         int duration_on;
71         int duration_off;
72 } noteData[AV_MIDI_NOTE_MAX];
73
74 /*imelody key string (to validatation check)*/
75 static const char *g_imy_key_str[] = {
76         "BEGIN:IMELODY",
77         "VERSION:",
78         "FORMAT:",
79         "MELODY:",
80         "END:IMELODY",
81 };
82
83
84 static int __is_good_imelody(unsigned char *src, unsigned int size);
85 static unsigned char *__get_load_memory(char *src, int *out_size);
86 static unsigned char __AvMIDISetVolume(char *pMelodyBuf);
87 static int __AvMIDISetBeat(char *pMelodyBuf);
88 static char __AvMIDISetStyle(char *pMelodyBuf);
89 static unsigned char *__AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen);
90 static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags);
91
92
93 /* interface functions */
94 int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext);
95 int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
96 int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext);
97 int mmfile_format_close_imy(MMFileFormatContext *formatContext);
98
99
100 EXPORT_API
101 int mmfile_format_open_imy(MMFileFormatContext *formatContext)
102 {
103         int ret = 0;
104
105         if (!formatContext) {
106                 debug_error(DEBUG, "formatContext is NULL\n");
107                 return MMFILE_FORMAT_FAIL;
108         }
109
110         ret = MMFileFormatIsValidIMY(NULL, formatContext->uriFileName, 0);
111         if (ret == 0) {
112                 debug_error(DEBUG, "It is not imelody file\n");
113                 return MMFILE_FORMAT_FAIL;
114         }
115
116         formatContext->ReadStream   = mmfile_format_read_stream_imy;
117         formatContext->ReadFrame    = mmfile_format_read_frame_imy;
118         formatContext->ReadTag      = mmfile_format_read_tag_imy;
119         formatContext->Close        = mmfile_format_close_imy;
120
121         formatContext->videoTotalTrackNum = 0;
122         formatContext->audioTotalTrackNum = 1;
123
124         formatContext->privateFormatData = NULL;
125
126         return MMFILE_FORMAT_SUCCESS;
127 }
128
129 EXPORT_API
130 int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext)
131 {
132         MIDI_INFO_SIMPLE *info = NULL;
133         MMFileFormatStream  *audioStream = NULL;
134
135         unsigned char   *imy = NULL;
136         int                             imy_size = 0;
137         unsigned char   *midi = NULL;
138         unsigned int    midi_size = 0;
139         char                    src2[MMFILE_URI_MAX_LEN];
140
141         int ret = 0;
142
143         if (!formatContext) {
144                 debug_error(DEBUG, "formatContext is NULL\n");
145                 return MMFILE_FORMAT_FAIL;
146         }
147
148         /*convert iMelody to Midi*/
149         imy = __get_load_memory(formatContext->uriFileName, &imy_size);
150         if (!imy) {
151                 debug_error(DEBUG, "failed to load memory.\n");
152                 goto exception;
153         }
154         ret = __is_good_imelody(imy, imy_size);
155         if (ret != MMFILE_FORMAT_SUCCESS) {
156                 debug_error(DEBUG, "it's broken file.\n");
157                 goto exception;
158         }
159         midi = __AvConvertIMelody2MIDI((char *)imy, &midi_size);
160         if (!midi) {
161                 debug_error(DEBUG, "failed to convert.");
162                 goto exception;
163         }
164
165         /*make uri*/
166         memset(src2, 0x00, MMFILE_URI_MAX_LEN);
167         snprintf(src2, sizeof(src2), "%s%u:%u", MMFILE_MEM_URI, (unsigned int)midi, midi_size);
168
169         /*get infomation*/
170         info = mmfile_format_get_midi_infomation(src2);
171         if (!info) {
172                 debug_error(DEBUG, "failed to get infomation");
173                 goto exception;
174         }
175
176         formatContext->duration = info->duration;
177         formatContext->videoStreamId = -1;
178         formatContext->videoTotalTrackNum = 0;
179         formatContext->audioTotalTrackNum = info->track_num;
180         formatContext->nbStreams = 1;
181
182
183         audioStream = mmfile_malloc(sizeof(MMFileFormatStream));
184         if (NULL == audioStream) {
185                 debug_error(DEBUG, "error: mmfile_malloc audiostream\n");
186                 ret = MMFILE_FORMAT_FAIL;
187                 goto exception;
188         }
189
190         audioStream->streamType = MMFILE_AUDIO_STREAM;
191         audioStream->codecId = MM_AUDIO_CODEC_IMELODY;
192         audioStream->bitRate = 0;
193         audioStream->framePerSec = 0;
194         audioStream->width = 0;
195         audioStream->height = 0;
196         audioStream->nbChannel = 1;
197         audioStream->samplePerSec = 0;
198         formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
199
200 #ifdef  __MMFILE_TEST_MODE__
201         mmfile_format_print_contents(formatContext);
202 #endif
203
204         mmfile_free(imy);
205         mmfile_free(midi);
206         mmfile_format_free_midi_infomation(info);
207         return MMFILE_FORMAT_SUCCESS;
208
209 exception:
210         mmfile_free(imy);
211         mmfile_free(midi);
212         mmfile_format_free_midi_infomation(info);
213         mmfile_free(audioStream);
214         return MMFILE_FORMAT_FAIL;
215 }
216
217 EXPORT_API
218 int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
219 {
220         return MMFILE_FORMAT_SUCCESS;
221 }
222
223
224 EXPORT_API
225 int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext)
226 {
227         tMMFileImelodyTagInfo taginfo = {0, };
228         unsigned int tag_len;
229         unsigned int cnv_len;
230         const char *locale = MMFileUtilGetLocale();
231
232         if (!formatContext) {
233                 debug_error(DEBUG, "formatContext is NULL\n");
234                 return MMFILE_FORMAT_FAIL;
235         }
236
237         __get_imelody_tag(formatContext->uriFileName, &taginfo);
238
239         /**
240          * UTF8 convert
241          */
242         if (taginfo.title) {
243                 tag_len = strlen(taginfo.title);
244                 cnv_len = 0;
245                 formatContext->title = mmfile_string_convert((const char *)taginfo.title,
246                                                                                                 tag_len,
247                                                                                                 "UTF-8",
248                                                                                                 locale,
249                                                                                                 NULL,
250                                                                                                 (unsigned int *)&cnv_len);
251
252                 if (formatContext->title == NULL) {
253                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
254                         formatContext->title = mmfile_strdup(taginfo.title);
255                 }
256                 mmfile_free(taginfo.title);
257         }
258
259         if (taginfo.composer) {
260                 tag_len = strlen(taginfo.composer);
261                 cnv_len = 0;
262                 formatContext->composer = mmfile_string_convert((const char *)taginfo.composer,
263                                                                                                 tag_len,
264                                                                                                 "UTF-8",
265                                                                                                 locale,
266                                                                                                 NULL,
267                                                                                                 (unsigned int *)&cnv_len);
268                 if (formatContext->composer == NULL) {
269                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
270                         formatContext->composer = mmfile_strdup(taginfo.composer);
271                 }
272                 mmfile_free(taginfo.composer);
273         }
274
275         if (taginfo.comment) {
276                 tag_len = strlen(taginfo.comment);
277                 cnv_len = 0;
278                 formatContext->comment = mmfile_string_convert((const char *)taginfo.comment,
279                                                                                                 tag_len,
280                                                                                                 "UTF-8",
281                                                                                                 locale,
282                                                                                                 NULL,
283                                                                                                 (unsigned int *)&cnv_len);
284                 if (formatContext->comment == NULL) {
285                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
286                         formatContext->comment = mmfile_strdup(taginfo.comment);
287                 }
288                 mmfile_free(taginfo.comment);
289         }
290
291         if (taginfo.copyright) {
292                 tag_len = strlen(taginfo.copyright);
293                 cnv_len = 0;
294                 formatContext->copyright = mmfile_string_convert((const char *)taginfo.copyright,
295                                                                                                 tag_len,
296                                                                                                 "UTF-8",
297                                                                                                 locale,
298                                                                                                 NULL,
299                                                                                                 (unsigned int *)&cnv_len);
300                 if (formatContext->copyright == NULL) {
301                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
302                         formatContext->copyright = mmfile_strdup(taginfo.copyright);
303                 }
304                 mmfile_free(taginfo.copyright);
305         }
306
307         return MMFILE_FORMAT_SUCCESS;
308 }
309
310 EXPORT_API
311 int mmfile_format_close_imy(MMFileFormatContext *formatContext)
312 {
313         return MMFILE_FORMAT_SUCCESS;
314 }
315
316 static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags)
317 {
318 #define _MMFILE_IMY_TAG_BUFFER_LENGTH   512
319 #define _MMFILE_IMY_HEADER_LENGTH       20
320 #define _MMFILE_IMY_KEY_BUFFER_LENGTH   20
321 #define _MMFILE_IMY_VALUE_BUFFER_LENGTH 128
322
323         MMFileIOHandle *fp = NULL;
324         unsigned char buffer[_MMFILE_IMY_TAG_BUFFER_LENGTH] = {0, };
325         long long     filesize = 0;
326         unsigned int  startoffset = 0;
327         unsigned int  endoffset = 0, i = 0;
328         int  readed = 0, j = 0;
329         char          imy_key_buffer[_MMFILE_IMY_KEY_BUFFER_LENGTH] = {0, };
330         unsigned int  imy_key_buffer_index = 0;
331         char          imy_value_buffer[_MMFILE_IMY_VALUE_BUFFER_LENGTH] = {0, };
332         unsigned int  imy_value_buffer_index = 0;
333         int           isKeyBuffer = 1;
334         int           isDone  = 0;
335
336         int ret = MMFILE_FORMAT_FAIL;
337
338         if (!uriname || !tags) {
339                 debug_error(DEBUG, "uriname or tags is NULL\n");
340                 return MMFILE_FORMAT_FAIL;
341         }
342
343         ret = mmfile_open(&fp, uriname, MMFILE_RDONLY);
344         if (ret == MMFILE_UTIL_FAIL) {
345                 debug_error(DEBUG, "open failed.\n");
346                 return MMFILE_FORMAT_FAIL;
347         }
348
349         filesize = mmfile_get_size(fp);
350         if (filesize < _MMFILE_IMY_HEADER_LENGTH) {
351                 debug_error(DEBUG, "header is too small.\n");
352                 ret = MMFILE_FORMAT_FAIL;
353                 goto exit;
354         }
355
356         /* set begin and end point at the file */
357         startoffset = 0;
358         endoffset = filesize;
359
360         i = startoffset;
361         isKeyBuffer = 1;
362         while (i < endoffset) {
363                 mmfile_seek(fp, i, MMFILE_SEEK_SET);
364                 readed = mmfile_read(fp, buffer, _MMFILE_IMY_TAG_BUFFER_LENGTH);
365                 if (readed < 0) {
366                         debug_error(DEBUG, "read error. size = %d. Maybe end of file.\n", readed);
367                         ret = 0;
368                         break;
369                 }
370
371                 j = 0;
372                 while (j < readed) {
373                         if (*(buffer + j) == 0x3a) {
374                                 isKeyBuffer = 0;
375                         } else if (*(buffer + j) == 0x0d) {
376                         } else if (*(buffer + j) == 0x0a) {
377                                 isKeyBuffer = 1;
378                                 isDone = 1;
379                         } else {
380                                 if (isKeyBuffer) {
381                                         if (imy_key_buffer_index < _MMFILE_IMY_KEY_BUFFER_LENGTH) {
382                                                 imy_key_buffer[imy_key_buffer_index++] = *(buffer + j);
383                                         }
384
385                                 } else {
386                                         if (imy_value_buffer_index < _MMFILE_IMY_VALUE_BUFFER_LENGTH) {
387                                                 imy_value_buffer[imy_value_buffer_index++] = *(buffer + j);
388                                         }
389                                 }
390                         }
391
392                         if (isDone) {
393                                 if (!strncmp(imy_key_buffer, "NAME", 4)) {
394                                         mmfile_free(tags->title);
395                                         tags->title = mmfile_strdup(imy_value_buffer);
396                                 } else if (!strncmp(imy_key_buffer, "COMPOSER", 8)) {
397                                         mmfile_free(tags->composer);
398                                         tags->composer = mmfile_strdup(imy_value_buffer);
399                                 } else if (!strncmp(imy_key_buffer, "COPYRIGHT", 9)) {
400                                         mmfile_free(tags->copyright);
401                                         tags->copyright = mmfile_strdup(imy_value_buffer);
402                                 }
403
404                                 memset(imy_key_buffer, 0x00, _MMFILE_IMY_KEY_BUFFER_LENGTH);
405                                 memset(imy_value_buffer, 0x00, _MMFILE_IMY_VALUE_BUFFER_LENGTH);
406                                 imy_key_buffer_index = 0;
407                                 imy_value_buffer_index = 0;
408                                 isDone = 0;
409                         }
410
411                         j++;
412                 }
413
414                 memset(buffer, 0x00, _MMFILE_IMY_TAG_BUFFER_LENGTH);
415
416                 i = i + j;
417         }
418
419 exit:
420         mmfile_close(fp);
421         return ret;
422 }
423
424 static unsigned char *
425 __get_load_memory(char *src, int *out_size)
426 {
427         unsigned char                   *buf = NULL;
428         MMFileIOHandle  *fp = NULL;
429         long long               src_size = 0L;
430         int                             readed = 0;
431         int                             ret = 0;
432
433         /*open*/
434         ret = mmfile_open(&fp, src, MMFILE_RDONLY);
435         if (ret == MMFILE_UTIL_FAIL) {
436                 debug_error(DEBUG, "open failed.\n");
437                 return NULL;
438         }
439
440         /*get file size*/
441         src_size = mmfile_get_size(fp);
442         if (src_size <= 0) {
443                 debug_error(DEBUG, "failed to get file size.\n");
444                 goto failed;
445         }
446
447         /*alloc read buffer*/
448         if ((buf = mmfile_malloc(src_size)) == NULL) {
449                 debug_error(DEBUG, "memory allocation failed.\n");
450                 goto failed;
451         }
452
453         /*read data*/
454         if ((readed = mmfile_read(fp, buf, src_size)) != src_size) {
455                 debug_error(DEBUG, "read error. size = %d\n", readed);
456                 goto failed;
457         }
458
459         *out_size = (int)src_size;
460         mmfile_close(fp);
461
462         return buf;
463
464 failed:
465         mmfile_free(buf);
466         mmfile_close(fp);
467         return NULL;
468 }
469
470
471 static int
472 __is_good_imelody(unsigned char *src, unsigned int size)
473 {
474         unsigned int i, j;
475         int key_len;
476         int is_found;
477         unsigned char *p;
478         unsigned int num = sizeof(g_imy_key_str) / sizeof(g_imy_key_str[0]);
479
480         for (i = 0; i < num; i++) {
481                 key_len = strlen(g_imy_key_str[i]);
482                 p = src;
483                 is_found = 0;
484                 for (j = 0; j <= size - key_len; j++, p++) {
485                         if (memcmp(g_imy_key_str[i], p, key_len) == 0) {
486                                 is_found = 1;
487                                 break;
488                         }
489                 }
490                 if (is_found) continue;
491                 else return MMFILE_FORMAT_FAIL;
492         }
493
494         return MMFILE_FORMAT_SUCCESS;
495 }
496
497 static void
498 __init_imelody_data(void)
499 {
500         int idx = 0;
501
502         for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) {
503                 restSpec[idx] = 0;
504                 durationSpec[idx] = 0;
505         }
506
507         for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++)
508                 octave[idx] = '%';
509
510         for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) {
511                 Melody[idx].flat_sharp = '%';
512                 Melody[idx].note = '%';
513                 Melody[idx].duration = '%';
514                 Melody[idx].duration_specifier = '%';
515                 Melody[idx].rest = '%';
516                 Melody[idx].rest_specifier = '%';
517                 Melody[idx].vol = '%';
518         }
519
520         for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) {
521                 noteData[idx].note = 0;
522                 noteData[idx].duration_on = 0;
523                 noteData[idx].duration_off = 0;
524         }
525
526         memset(midiData, 0, sizeof(midiData));
527         memcpy(midiData, midiHeader, MIDI_HEADER_LENGTH);
528 }
529
530 static void
531 __get_imelody_duration(char style, int number)
532 {
533         if (style == '0') {
534                 switch (Melody[number].duration) {
535                 case '0':
536                         noteData[number].duration_on = 183;
537                         noteData[number].duration_off = 9;
538                         break;
539                 case '1':
540                         noteData[number].duration_on = 91;
541                         noteData[number].duration_off = 5;
542                         break;
543                 case '2':
544                         noteData[number].duration_on = 46;
545                         noteData[number].duration_off = 2;
546                         break;
547                 case '3':
548                         noteData[number].duration_on = 23;
549                         noteData[number].duration_off = 1;
550                         break;
551                 case '4':
552                         noteData[number].duration_on = 11;
553                         noteData[number].duration_off = 1;
554                         break;
555                 case '5':
556                         noteData[number].duration_on = 5;
557                         noteData[number].duration_off = 1;
558                         break;
559                 default:
560                         break;
561                 }
562         }
563
564         else if (style == '1') {
565                 switch (Melody[number].duration) {
566                 case '0':
567                         noteData[number].duration_on = 192;
568                         noteData[number].duration_off = 0;
569                         break;
570                 case '1':
571                         noteData[number].duration_on = 96;
572                         noteData[number].duration_off = 0;
573                         break;
574                 case '2':
575                         noteData[number].duration_on = 48;
576                         noteData[number].duration_off = 0;
577                         break;
578                 case '3':
579                         noteData[number].duration_on = 24;
580                         noteData[number].duration_off = 0;
581                         break;
582                 case '4':
583                         noteData[number].duration_on = 12;
584                         noteData[number].duration_off = 0;
585                         break;
586                 case '5':
587                         noteData[number].duration_on = 6;
588                         noteData[number].duration_off = 0;
589                         break;
590                 default:
591                         break;
592                 }
593         }
594
595         else {
596                 switch (Melody[number].duration) {
597                 case '0':
598                         noteData[number].duration_on = 96;
599                         noteData[number].duration_off = 96;
600                         break;
601                 case '1':
602                         noteData[number].duration_on = 48;
603                         noteData[number].duration_off = 48;
604                         break;
605                 case '2':
606                         noteData[number].duration_on = 24;
607                         noteData[number].duration_off = 24;
608                         break;
609                 case '3':
610                         noteData[number].duration_on = 12;
611                         noteData[number].duration_off = 12;
612                         break;
613                 case '4':
614                         noteData[number].duration_on = 6;
615                         noteData[number].duration_off = 6;
616                         break;
617                 case '5':
618                         noteData[number].duration_on = 3;
619                         noteData[number].duration_off = 3;
620                         break;
621                 default:
622                         break;
623                 }
624         }
625
626         switch (Melody[number].duration) {
627         case '0':
628                 durationSpec[number] = 192;
629                 break;
630         case '1':
631                 durationSpec[number] = 96;
632                 break;
633         case '2':
634                 durationSpec[number] = 48;
635                 break;
636         case '3':
637                 durationSpec[number] = 24;
638                 break;
639         case '4':
640                 durationSpec[number] = 12;
641                 break;
642         case '5':
643                 durationSpec[number] = 6;
644                 break;
645         default:
646                 break;
647         }
648
649         if (Melody[number].duration_specifier != '%') {
650                 switch (Melody[number].duration_specifier) {
651                 case '.':
652                         noteData[number].duration_on += (durationSpec[number] / 2);
653                         break;
654                 case ':':
655                         noteData[number].duration_on += durationSpec[number];
656                         break;
657                 case ';':
658                         noteData[number].duration_on -= (durationSpec[number] / 3);
659                         break;
660                 default:
661                         break;
662                 }
663
664                 if (noteData[number].duration_on > MIDI_MAX)
665                         noteData[number].duration_on = MIDI_LIMIT;
666         }
667 }
668
669 static void
670 __get_imelody_melody(int number, int octaveValue)
671 {
672         if (Melody[number].flat_sharp == '#') {
673                 switch (Melody[number].note) {
674                 case 'c':
675                         noteData[number].note = octaveValue + 1;
676                         break;
677                 case 'd':
678                         noteData[number].note = octaveValue + 3;
679                         break;
680                 case 'f':
681                         noteData[number].note = octaveValue + 6;
682                         break;
683                 case 'g':
684                         noteData[number].note = octaveValue + 8;
685                         break;
686                 case 'a':
687                         noteData[number].note = octaveValue + 10;
688                         break;
689                 default:
690                         break;
691                 }
692         }
693
694         else if (Melody[number].flat_sharp == '&') {
695                 switch (Melody[number].note) {
696                 case 'd':
697                         noteData[number].note = octaveValue + 1;
698                         break;
699                 case 'e':
700                         noteData[number].note = octaveValue + 3;
701                         break;
702                 case 'g':
703                         noteData[number].note = octaveValue + 6;
704                         break;
705                 case 'a':
706                         noteData[number].note = octaveValue + 8;
707                         break;
708                 case 'b':
709                         noteData[number].note = octaveValue + 10;
710                         break;
711                 default:
712                         break;
713                 }
714         }
715
716         else {
717                 switch (Melody[number].note) {
718                 case 'c':
719                         noteData[number].note = octaveValue;
720                         break;
721                 case 'd':
722                         noteData[number].note = octaveValue + 2;
723                         break;
724                 case 'e':
725                         noteData[number].note = octaveValue + 4;
726                         break;
727                 case 'f':
728                         noteData[number].note = octaveValue + 5;
729                         break;
730                 case 'g':
731                         noteData[number].note = octaveValue + 7;
732                         break;
733                 case 'a':
734                         noteData[number].note = octaveValue + 9;
735                         break;
736                 case 'b':
737                         noteData[number].note = octaveValue + 11;
738                         break;
739                 default:
740                         break;
741                 }
742         }
743 }
744
745 static void
746 __get_imelody_reset(int number)
747 {
748         if (Melody[number].rest >= '0' && Melody[number].rest <= '5') {
749                 switch (Melody[number].rest) {
750                 case '0':
751                         noteData[number - 1].duration_off += 192;
752                         restSpec[number] = 192;
753                         break;
754                 case '1':
755                         noteData[number - 1].duration_off += 96;
756                         restSpec[number] = 96;
757                         break;
758                 case '2':
759                         noteData[number - 1].duration_off += 48;
760                         restSpec[number] = 48;
761                         break;
762                 case '3':
763                         noteData[number - 1].duration_off += 24;
764                         restSpec[number] = 24;
765                         break;
766                 case '4':
767                         noteData[number - 1].duration_off += 12;
768                         restSpec[number] = 12;
769                         break;
770                 case '5':
771                         noteData[number - 1].duration_off += 6;
772                         restSpec[number] = 6;
773                         break;
774                 default:
775                         break;
776                 }
777
778                 if (noteData[number - 1].duration_off > MIDI_MAX && Melody[number].rest_specifier == '%')
779                         noteData[number - 1].duration_off = MIDI_LIMIT;
780         }
781
782         if (Melody[number].rest_specifier != '%') {
783                 switch (Melody[number].rest_specifier) {
784                 case '.':
785                         noteData[number - 1].duration_off += (restSpec[number] / 2);
786                         break;
787                 case ':':
788                         noteData[number - 1].duration_off += restSpec[number];
789                         break;
790                 case ';':
791                         noteData[number - 1].duration_off -= (restSpec[number] / 3);
792                         break;
793                 default:
794                         break;
795                 }
796
797                 if (noteData[number - 1].duration_off > MIDI_MAX)
798                         noteData[number - 1].duration_off = MIDI_LIMIT;
799         }
800 }
801
802 static void
803 __get_imelody_notetotal(int number)
804 {
805         char noteBase[6];
806
807         memset(noteBase, 0, sizeof(noteBase));
808
809         noteBase[0] = noteData[number].note;
810         noteBase[2] = noteData[number].duration_on;
811         noteBase[3] = noteData[number].note;
812         noteBase[5] = noteData[number].duration_off;
813
814         noteTotal[6 * number] = noteBase[0];
815         noteTotal[6 * number + 2] = noteBase[2];
816         noteTotal[6 * number + 3] = noteBase[3];
817         noteTotal[6 * number + 5] = noteBase[5];
818         noteTotal[6 * number + 4] = 0;
819
820         if (noteTotal[6 * number + 2] > MIDI_LIMIT)
821                 noteTotal[6 * number + 2] = MIDI_LIMIT;
822
823         if (noteTotal[6 * number + 5] > MIDI_LIMIT)
824                 noteTotal[6 * number + 5] = MIDI_LIMIT;
825 }
826
827 static unsigned char *
828 __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
829 {
830         unsigned char *pConvertBuf;
831         char *pStart;
832         char *pMelodyStart;
833         int octaveCount;
834         int octaveValue;
835         int count;
836         int noteCount = 0;
837         int number;
838         int numberCount;
839         char style = '0';
840         int tempoData[3];
841         int tempoValue;
842         int trackSize;
843         int repeat = 0;
844         int repeatCount = 0;
845
846         __init_imelody_data();
847
848         pStart = pMelodyBuf;
849
850         midiData[49] = __AvMIDISetVolume(pMelodyBuf);
851
852         pMelodyBuf = pStart;
853
854         tempoValue = __AvMIDISetBeat(pMelodyBuf);
855
856         for (number = 0; tempoValue != 0; number++) {
857                 tempoData[0] = tempoValue % 16;
858                 tempoValue = tempoValue / 16;
859
860                 tempoData[1] = tempoValue % 16;
861                 tempoValue = tempoValue / 16;
862
863                 tempoData[2] = tempoData[0] + tempoData[1] * 16;
864
865                 midiData[42 - number] = tempoData[2];
866         }
867
868         pMelodyBuf = pStart;
869
870         while (!(*pMelodyBuf == '@' || (*pMelodyBuf == 'E' && *(pMelodyBuf + 2) == 'D')))
871                 pMelodyBuf++;
872
873         pMelodyBuf++;
874
875         if (*pMelodyBuf >= '1' && *pMelodyBuf <= '9') {
876                 repeat = *pMelodyBuf - '0';
877                 pMelodyBuf++;
878
879         }
880
881         repeat = 0;
882
883         pMelodyBuf = pStart;
884
885         pMelodyBuf = pMelodyBuf + 42;
886
887         while (!(*pMelodyBuf == 'M' && *(pMelodyBuf + 5) == 'Y' && *(pMelodyBuf + 6) == ':')) /*2007-02-28 AVMS_Sound:k2bogus - UMTS200073205;imy play, [MELODY:] extract fix */
888                 pMelodyBuf++;
889
890         pMelodyBuf = pMelodyBuf + 6;
891
892         pMelodyStart = pMelodyBuf;
893
894         /**@note if newline detected, stop reading
895          *       why? mobileBAE player stopped at newline.
896          *       2009/08/12
897          */
898         while (!((*pMelodyBuf == 'E' && *(pMelodyBuf + 2) == 'D') || (*pMelodyBuf == '\n'))) {
899                 if (noteCount >= AV_MIDI_NOTE_MAX) {
900                         debug_warning(DEBUG, "__AvConvertIMelody2MIDI : noteCount>=AV_MIDI_NOTE_MAX\n");
901                         break;
902                 }
903
904                 pMelodyBuf++;
905
906                 if (*pMelodyBuf == '*') {
907                         pMelodyBuf++;
908
909                         if (*pMelodyBuf >= '0' && *pMelodyBuf <= '8')
910                                 octave[noteCount] = *pMelodyBuf;
911                 }
912
913                 if (*pMelodyBuf == '#' || *pMelodyBuf == '&')
914                         Melody[noteCount].flat_sharp = *pMelodyBuf;
915
916                 if (*pMelodyBuf == 'r') {
917                         pMelodyBuf++;
918
919                         if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
920                                 Melody[noteCount].rest = *pMelodyBuf;
921                                 pMelodyBuf++;
922
923                                 if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
924                                         Melody[noteCount].rest_specifier = *pMelodyBuf;
925                         }
926                 }
927
928                 if (*pMelodyBuf == 'V') {
929                         pMelodyBuf++;
930
931                         if (*pMelodyBuf == '+' || *pMelodyBuf == '-')
932                                 Melody[noteCount].vol = *pMelodyBuf;
933                 }
934
935                 if (*pMelodyBuf >= 'a' && *pMelodyBuf <= 'g') {
936                         Melody[noteCount].note = *pMelodyBuf;
937                         pMelodyBuf++;
938
939                         if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
940                                 Melody[noteCount].duration = *pMelodyBuf;
941                                 pMelodyBuf++;
942
943                                 if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
944                                         Melody[noteCount].duration_specifier = *pMelodyBuf;
945
946                                 else
947                                         pMelodyBuf--;
948
949                                 noteCount++;
950                         }
951                 }
952         }
953
954         for (octaveCount = 1; octaveCount < noteCount; octaveCount++) {
955                 if (octave[octaveCount] == '%')
956                         octave[octaveCount] = octave[octaveCount - 1];
957         }
958
959         for (number = 0; number < noteCount; number++) {
960                 if (octave[0] == '%' && octave[number] == '%')
961                         octaveValue = 4;
962
963                 else
964                         octaveValue = octave[number] - '0';
965
966                 octaveValue = octaveValue * 12;
967
968                 __get_imelody_melody(number, octaveValue);
969         }
970
971         pMelodyBuf = pMelodyStart;
972
973         style = __AvMIDISetStyle(pMelodyBuf);
974
975         for (number = 0; number < noteCount; number++)
976                 __get_imelody_duration(style, number);
977
978         for (number = 1; number < noteCount; number++)
979                 __get_imelody_reset(number);
980
981         if (Melody[0].rest >= '0' && Melody[0].rest <= '5') {
982                 switch (Melody[0].rest) {
983                 case '0':
984                         midiData[50] += 192;
985                         restSpec[0] = 192;
986                         break;
987                 case '1':
988                         midiData[50] += 96;
989                         restSpec[0] = 96;
990                         break;
991                 case '2':
992                         midiData[50] += 48;
993                         restSpec[0] = 48;
994                         break;
995                 case '3':
996                         midiData[50] += 24;
997                         restSpec[0] = 24;
998                         break;
999                 case '4':
1000                         midiData[50] += 12;
1001                         restSpec[0] = 12;
1002                         break;
1003                 case '5':
1004                         midiData[50] += 6;
1005                         restSpec[0] = 6;
1006                         break;
1007                 default:
1008                         break;
1009                 }
1010
1011                 if (Melody[0].rest_specifier != '%') {
1012                         switch (Melody[0].rest_specifier) {
1013                         case '.':
1014                                 midiData[50] += (restSpec[0] / 2);
1015                                 break;
1016                         case ':':
1017                                 midiData[50] += restSpec[0];
1018                                 break;
1019                         case ';':
1020                                 midiData[50] -= (restSpec[0] / 3);
1021                                 break;
1022                         default:
1023                                 break;
1024                         }
1025                 }
1026
1027                 if (midiData[50] > MIDI_LIMIT)
1028                         midiData[50] = MIDI_LIMIT;
1029
1030                 if (Melody[0].rest == '0')
1031                         midiData[50] = MIDI_LIMIT;
1032         }
1033
1034         for (number = 0; number < noteCount; number++)
1035                 __get_imelody_notetotal(number);
1036
1037         for (number = 1; number < noteCount; number++) {
1038                 noteTotal[1] = 84;
1039
1040                 if (Melody[0].vol == '+')
1041                         noteTotal[1] = 84 + VOL_INTERVAL;
1042
1043                 if (Melody[0].vol == '-')
1044                         noteTotal[1] = 84 - VOL_INTERVAL;
1045
1046                 switch (Melody[number].vol) {
1047                 case '+':
1048                         noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] + VOL_INTERVAL;
1049                         break;
1050                 case '-':
1051                         noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] - VOL_INTERVAL;
1052                         break;
1053                 default:
1054                         break;
1055                 }
1056
1057                 if (noteTotal[6 * number + 1] > MIDI_LIMIT)
1058                         noteTotal[6 * number + 1] = MIDI_LIMIT;
1059
1060                 if ((noteTotal[6 * (number - 1) + 1] == 0 || noteTotal[6 * (number - 1) + 1] == 7) && Melody[number].vol == '-')
1061                         noteTotal[6 * number + 1] = 0;
1062
1063                 if (Melody[number].vol == '%')
1064                         noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1];
1065         }
1066
1067         for (number = 0; number < 6 * noteCount; number++)
1068                 midiData[52 + number] = noteTotal[number];
1069
1070         for (number = 6 * noteCount; number < 6 * noteCount * (repeat + 1); number++) {
1071                 noteTotal[number] = noteTotal[repeatCount];
1072                 midiData[52 + number] = noteTotal[number];
1073                 repeatCount++;
1074
1075                 if (repeatCount == 6 * noteCount)
1076                         repeatCount = 0;
1077         }
1078
1079         for (number = 1; number < 6 * noteCount * (repeat + 1); number = number + 6) {
1080                 if (midiData[52 + number] > MIDI_LIMIT)
1081                         midiData[52 + number] = MIDI_LIMIT;
1082         }
1083
1084         pMelodyBuf = pMelodyStart;
1085         count = noteCount;
1086
1087         if (*pMelodyBuf != 'E' && *pMelodyBuf != ':') {
1088                 pMelodyBuf--;
1089
1090                 while (*pMelodyBuf != 'E') {
1091                         if (noteCount >= AV_MIDI_NOTE_MAX) {
1092                                 debug_warning(DEBUG, "__AvConvertIMelody2MIDI : noteCount>=AV_MIDI_NOTE_MAX\n");
1093                                 break;
1094                         }
1095
1096                         pMelodyBuf++;
1097
1098                         if (*pMelodyBuf == '*') {
1099                                 pMelodyBuf++;
1100
1101                                 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '8')
1102                                         octave[noteCount] = *pMelodyBuf;
1103                         }
1104
1105                         if (*pMelodyBuf == '#' || *pMelodyBuf == '&')
1106                                 Melody[noteCount].flat_sharp = *pMelodyBuf;
1107
1108                         if (*pMelodyBuf == 'r') {
1109                                 pMelodyBuf++;
1110
1111                                 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
1112                                         Melody[noteCount].rest = *pMelodyBuf;
1113                                         pMelodyBuf++;
1114
1115                                         if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
1116                                                 Melody[noteCount].rest_specifier = *pMelodyBuf;
1117                                 }
1118                         }
1119
1120                         if (*pMelodyBuf == 'V') {
1121                                 pMelodyBuf++;
1122
1123                                 if (*pMelodyBuf == '+' || *pMelodyBuf == '-')
1124                                         Melody[noteCount].vol = *pMelodyBuf;
1125                         }
1126
1127                         if (*pMelodyBuf >= 'a' && *pMelodyBuf <= 'g') {
1128                                 Melody[noteCount].note = *pMelodyBuf;
1129                                 pMelodyBuf++;
1130
1131                                 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
1132                                         Melody[noteCount].duration = *pMelodyBuf;
1133                                         pMelodyBuf++;
1134
1135                                         if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
1136                                                 Melody[noteCount].duration_specifier = *pMelodyBuf;
1137
1138                                         else
1139                                                 pMelodyBuf--;
1140
1141                                         noteCount++;
1142                                 }
1143                         }
1144                 }
1145
1146                 for (octaveCount = count; octaveCount < noteCount && octaveCount < AV_MIDI_NOTE_MAX; octaveCount++) {
1147                         if (octave[octaveCount] == '%')
1148                                 octave[octaveCount] = octave[octaveCount - 1];
1149                 }
1150
1151                 for (number = count; number < noteCount && number < AV_MIDI_NOTE_MAX; number++) {
1152                         octaveValue = octave[number] - '0';
1153
1154                         octaveValue = octaveValue * 12;
1155
1156                         __get_imelody_melody(number, octaveValue);
1157                         __get_imelody_duration(style, number);
1158                 }
1159
1160                 for (number = count + 1; number < noteCount && number < AV_MIDI_NOTE_MAX; number++)
1161                         __get_imelody_reset(number);
1162
1163                 if (Melody[count].rest >= '0' && Melody[count].rest <= '5') {
1164                         switch (Melody[count].rest) {
1165                         case '0':
1166                                 midiData[52 + (6 * count * (repeat + 1) - 1)] += 192;
1167                                 restSpec[count] = 192;
1168                                 break;
1169                         case '1':
1170                                 midiData[52 + (6 * count * (repeat + 1) - 1)] += 96;
1171                                 restSpec[count] = 96;
1172                                 break;
1173                         case '2':
1174                                 midiData[52 + (6 * count * (repeat + 1) - 1)] += 48;
1175                                 restSpec[count] = 48;
1176                                 break;
1177                         case '3':
1178                                 midiData[52 + (6 * count * (repeat + 1) - 1)] += 24;
1179                                 restSpec[count] = 24;
1180                                 break;
1181                         case '4':
1182                                 midiData[52 + (6 * count * (repeat + 1) - 1)] += 12;
1183                                 restSpec[count] = 12;
1184                                 break;
1185                         case '5':
1186                                 midiData[52 + (6 * count * (repeat + 1) - 1)] += 6;
1187                                 restSpec[count] = 6;
1188                                 break;
1189                         default:
1190                                 break;
1191                         }
1192
1193                         if (Melody[count].rest_specifier != '%') {
1194                                 switch (Melody[count].rest_specifier) {
1195                                 case '.':
1196                                         midiData[52 + (6 * count * (repeat + 1) - 1)] += (restSpec[count] / 2);
1197                                         break;
1198                                 case ':':
1199                                         midiData[52 + (6 * count * (repeat + 1) - 1)] += restSpec[count];
1200                                         break;
1201                                 case ';':
1202                                         midiData[52 + (6 * count * (repeat + 1) - 1)] -= (restSpec[count] / 3);
1203                                         break;
1204                                 default:
1205                                         break;
1206                                 }
1207                         }
1208
1209                         if (midiData[52 + (6 * count * (repeat + 1) - 1)] > MIDI_LIMIT)
1210                                 midiData[52 + (6 * count * (repeat + 1) - 1)] = MIDI_LIMIT;
1211
1212                         if (Melody[count].rest == '0')
1213                                 midiData[52 + (6 * count * (repeat + 1) - 1)] = MIDI_LIMIT;
1214                 }
1215
1216                 for (number = count; number < noteCount; number++)
1217                         __get_imelody_notetotal(number);
1218
1219                 for (number = count + 1; number < noteCount; number++) {
1220                         noteTotal[6 * count + 1] = midiData[52 + (6 * count * (repeat + 1) - 5)];
1221
1222                         if (Melody[count].vol == '+')
1223                                 noteTotal[6 * count + 1] = noteTotal[6 * count + 1] + VOL_INTERVAL;
1224
1225                         if (Melody[count].vol == '-' && (noteTotal[6 * count + 1] == 0 || noteTotal[6 * count + 1] == 7))
1226                                 noteTotal[6 * count + 1] = 0;
1227
1228                         if (Melody[count].vol == '-' && noteTotal[6 * count + 1] >= 12)
1229                                 noteTotal[6 * count + 1] = noteTotal[6 * count + 1] - VOL_INTERVAL;
1230
1231                         if (noteTotal[6 * count + 1] > MIDI_LIMIT)
1232                                 noteTotal[6 * count + 1] = MIDI_LIMIT;
1233
1234                         switch (Melody[number].vol) {
1235                         case '+':
1236                                 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] + VOL_INTERVAL;
1237                                 break;
1238                         case '-':
1239                                 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] - VOL_INTERVAL;
1240                                 break;
1241                         default:
1242                                 break;
1243                         }
1244
1245                         if (noteTotal[6 * number + 1] > MIDI_LIMIT)
1246                                 noteTotal[6 * number + 1] = MIDI_LIMIT;
1247
1248                         if ((noteTotal[6 * (number - 1) + 1] == 0 || noteTotal[6 * (number - 1) + 1] == 7) && Melody[number].vol == '-')
1249                                 noteTotal[6 * number + 1] = 0;
1250
1251                         if (Melody[number].vol == '%')
1252                                 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1];
1253                 }
1254
1255                 numberCount = 6 * count;
1256
1257                 for (number = 6 * count * (repeat + 1); number < 6 * (count * (repeat + 1) + (noteCount - count)); number++) {
1258                         midiData[52 + number] = noteTotal[numberCount];
1259                         numberCount++;
1260                 }
1261         }
1262
1263         noteTotal[6 * (count * (repeat + 1) + (noteCount - count))] = 0;                                /*0x00 */
1264         noteTotal[6 * (count * (repeat + 1) + (noteCount - count)) + 1] = MIDI_MAX;             /*0xff */
1265         noteTotal[6 * (count * (repeat + 1) + (noteCount - count)) + 2] = 47;                   /*0x2f */
1266         noteTotal[6 * (count * (repeat + 1) + (noteCount - count)) + 3] = 0;                    /*0x00 */
1267
1268         for (number = 6 * (count * (repeat + 1) + (noteCount - count)); number <= 6 * (count * (repeat + 1) + (noteCount - count)) + 3; number++)
1269                 midiData[51 + number] = noteTotal[number];
1270
1271         trackSize = (6 * (count * (repeat + 1) + (noteCount - count)) + 56) - 22 - 1 ;
1272
1273         midiData[20] = (trackSize & 0xff00) >> 8;
1274         midiData[21] = (trackSize & 0x00ff);
1275
1276
1277         *pBufLen = 6 * (count * (repeat + 1) + (noteCount - count)) + 56 - 1;
1278
1279         pConvertBuf = (unsigned char *) mmfile_malloc(*pBufLen);
1280         if (pConvertBuf == NULL) {
1281                 debug_error(DEBUG, "__AvConvertIMelody2MIDI: malloc failed!\n");
1282                 return NULL;
1283         }
1284
1285         memcpy(pConvertBuf, midiData, *pBufLen);
1286
1287         return pConvertBuf;
1288 }
1289
1290 static unsigned char
1291 __AvMIDISetVolume(char *pMelodyBuf)
1292 {
1293         unsigned char midiVol;
1294
1295         pMelodyBuf = pMelodyBuf + 42;
1296
1297         while (!((*pMelodyBuf == 'V' && (*(pMelodyBuf + 1) < 'a' || *(pMelodyBuf + 1) > 'z')) || (*pMelodyBuf == 'M' && *(pMelodyBuf + 5) == 'Y' && *(pMelodyBuf + 6) == ':'))) /*2007-02-28 AVMS_Sound:k2bogus - UMTS200073205;imy play, [MELODY:] extract fix */
1298                 pMelodyBuf++;
1299
1300         if (*pMelodyBuf != 'V')
1301                 midiVol = AV_MIDI_VOL_MAX;
1302
1303         else {
1304                 pMelodyBuf = pMelodyBuf + 5;
1305
1306                 if (*pMelodyBuf == 'E')
1307                         pMelodyBuf = pMelodyBuf + 3;
1308
1309                 else
1310                         pMelodyBuf = pMelodyBuf - 4;
1311
1312                 if (*pMelodyBuf == '1') {
1313                         pMelodyBuf++;
1314
1315                         switch (*pMelodyBuf) {
1316                         case '0':
1317                                 midiVol = AV_MIDI_VOL_MAX;
1318                                 break;
1319                         case '1':
1320                                 midiVol = AV_MIDI_VOL_MAX;
1321                                 break;
1322                         case '2':
1323                                 midiVol = AV_MIDI_VOL_MAX;
1324                                 break;
1325                         case '3':
1326                                 midiVol = AV_MIDI_VOL_MAX;
1327                                 break;
1328                         case '4':
1329                                 midiVol = AV_MIDI_VOL_MAX;
1330                                 break;
1331                         case '5':
1332                                 midiVol = AV_MIDI_VOL_MAX;
1333                                 break;
1334                         default:
1335                                 midiVol = AV_MIDI_VOL_MAX;
1336                                 break;
1337                         }
1338                 }
1339
1340                 else
1341                         switch (*pMelodyBuf) {
1342                         case '0':
1343                                 midiVol = 0;
1344                                 break;
1345                         case '2':
1346                                 midiVol = AV_MIDI_VOL_MAX;
1347                                 break;
1348                         case '3':
1349                                 midiVol = AV_MIDI_VOL_MAX;
1350                                 break;
1351                         case '4':
1352                                 midiVol = AV_MIDI_VOL_MAX;
1353                                 break;
1354                         case '5':
1355                                 midiVol = AV_MIDI_VOL_MAX;
1356                                 break;
1357                         case '6':
1358                                 midiVol = AV_MIDI_VOL_MAX;
1359                                 break;
1360                         case '7':
1361                                 midiVol = AV_MIDI_VOL_MAX;
1362                                 break;
1363                         case '8':
1364                                 midiVol = AV_MIDI_VOL_MAX;
1365                                 break;
1366                         case '9':
1367                                 midiVol = AV_MIDI_VOL_MAX;
1368                                 break;
1369                         default:
1370                                 midiVol = AV_MIDI_VOL_MAX;
1371                                 break;
1372                         }
1373         }
1374
1375         return midiVol;
1376 }
1377
1378 static int
1379 __AvMIDISetBeat(char *pMelodyBuf)
1380 {
1381         int bpmValue[4] = {0};
1382         int beatValue;
1383
1384         pMelodyBuf = pMelodyBuf + 42;
1385
1386         while (!((*pMelodyBuf == 'B' && (*(pMelodyBuf + 1) < 'a' || *(pMelodyBuf + 1) > 'z')) || (*pMelodyBuf == 'M' && *(pMelodyBuf + 5) == 'Y' && *(pMelodyBuf + 6) == ':'))) /*2007-02-28 AVMS_Sound:k2bogus - UMTS200073205;imy play, [MELODY:] extract fix */
1387                 pMelodyBuf++;
1388
1389         if (*pMelodyBuf != 'B')
1390                 bpmValue[3] = 120;
1391
1392         else {
1393                 pMelodyBuf = pMelodyBuf + 4;
1394
1395                 if (*pMelodyBuf == ':') {
1396                         pMelodyBuf++;
1397
1398                         if (*pMelodyBuf >= '1' && *pMelodyBuf <= '9') {
1399                                 bpmValue[0] = *pMelodyBuf - '0';
1400                                 pMelodyBuf++;
1401
1402                                 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9') {
1403                                         bpmValue[1] = *pMelodyBuf - '0';
1404                                         pMelodyBuf++;
1405
1406                                         if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9') {
1407                                                 bpmValue[2] = *pMelodyBuf - '0';
1408
1409                                                 bpmValue[0] = bpmValue[0] * 100;
1410                                                 bpmValue[1] = bpmValue[1] * 10;
1411                                                 pMelodyBuf++;
1412                                         }
1413
1414                                         else
1415                                                 bpmValue[0] = bpmValue[0] * 10;
1416                                 }
1417                         }
1418
1419                         bpmValue[3] = bpmValue[0] + bpmValue[1] + bpmValue[2];
1420                 }
1421         }
1422
1423         if (bpmValue[3] < 25 || bpmValue[3] > 900)
1424                 bpmValue[3] = 120;
1425
1426         if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9')
1427                 bpmValue[3] = 120;
1428
1429         beatValue = 1000000 * 60 / bpmValue[3];
1430
1431         debug_msg(RELEASE, "beat: %d = 1000000 * 60 / %d\n", beatValue, bpmValue[3]);
1432
1433         return beatValue;
1434 }
1435
1436 static char
1437 __AvMIDISetStyle(char *pMelodyBuf)
1438 {
1439         char styleValue = '0';
1440
1441         while (*pMelodyBuf != 'S')
1442                 pMelodyBuf--;
1443
1444         pMelodyBuf++;
1445
1446         if (*pMelodyBuf >= '0' && *pMelodyBuf <= '2')
1447                 pMelodyBuf++;
1448
1449         if (*pMelodyBuf != '.') {
1450                 pMelodyBuf--;
1451                 styleValue = *pMelodyBuf;
1452         }
1453
1454         if (styleValue < '0' || styleValue > '2') {
1455                 debug_warning(DEBUG, "unknown style. use default(S0)\n");
1456                 styleValue = '0';
1457         }
1458
1459         debug_msg(RELEASE, "style: '%c'\n", styleValue);
1460
1461         return styleValue;
1462 }