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.
23 #include <string.h> /*memcmp*/
24 #include <stdlib.h> /*malloc*/
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"
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
41 #define VOL_INTERVAL 12
43 #define MIDI_HEADER_LENGTH 52
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
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];
62 char duration_specifier;
66 } Melody[AV_MIDI_NOTE_MAX];
72 } noteData[AV_MIDI_NOTE_MAX];
74 /*imelody key string (to validatation check)*/
75 static const char *g_imy_key_str[] = {
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);
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);
101 int mmfile_format_open_imy(MMFileFormatContext *formatContext)
105 if (!formatContext) {
106 debug_error(DEBUG, "formatContext is NULL\n");
107 return MMFILE_FORMAT_FAIL;
110 ret = MMFileFormatIsValidIMY(NULL, formatContext->uriFileName, 0);
112 debug_error(DEBUG, "It is not imelody file\n");
113 return MMFILE_FORMAT_FAIL;
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;
121 formatContext->videoTotalTrackNum = 0;
122 formatContext->audioTotalTrackNum = 1;
124 formatContext->privateFormatData = NULL;
126 return MMFILE_FORMAT_SUCCESS;
130 int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext)
132 MIDI_INFO_SIMPLE *info = NULL;
133 MMFileFormatStream *audioStream = NULL;
135 unsigned char *imy = NULL;
137 unsigned char *midi = NULL;
138 unsigned int midi_size = 0;
139 char src2[MMFILE_URI_MAX_LEN];
143 if (!formatContext) {
144 debug_error(DEBUG, "formatContext is NULL\n");
145 return MMFILE_FORMAT_FAIL;
148 /*convert iMelody to Midi*/
149 imy = __get_load_memory(formatContext->uriFileName, &imy_size);
151 debug_error(DEBUG, "failed to load memory.\n");
154 ret = __is_good_imelody(imy, imy_size);
155 if (ret != MMFILE_FORMAT_SUCCESS) {
156 debug_error(DEBUG, "it's broken file.\n");
159 midi = __AvConvertIMelody2MIDI((char *)imy, &midi_size);
161 debug_error(DEBUG, "failed to convert.");
166 memset(src2, 0x00, MMFILE_URI_MAX_LEN);
167 snprintf(src2, sizeof(src2), "%s%u:%u", MMFILE_MEM_URI, (unsigned int)midi, midi_size);
170 info = mmfile_format_get_midi_infomation(src2);
172 debug_error(DEBUG, "failed to get infomation");
176 formatContext->duration = info->duration;
177 formatContext->videoStreamId = -1;
178 formatContext->videoTotalTrackNum = 0;
179 formatContext->audioTotalTrackNum = info->track_num;
180 formatContext->nbStreams = 1;
183 audioStream = mmfile_malloc(sizeof(MMFileFormatStream));
184 if (NULL == audioStream) {
185 debug_error(DEBUG, "error: mmfile_malloc audiostream\n");
186 ret = MMFILE_FORMAT_FAIL;
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;
200 #ifdef __MMFILE_TEST_MODE__
201 mmfile_format_print_contents(formatContext);
206 mmfile_format_free_midi_infomation(info);
207 return MMFILE_FORMAT_SUCCESS;
212 mmfile_format_free_midi_infomation(info);
213 mmfile_free(audioStream);
214 return MMFILE_FORMAT_FAIL;
218 int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
220 return MMFILE_FORMAT_SUCCESS;
225 int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext)
227 tMMFileImelodyTagInfo taginfo = {0, };
228 unsigned int tag_len;
229 unsigned int cnv_len;
230 const char *locale = MMFileUtilGetLocale();
232 if (!formatContext) {
233 debug_error(DEBUG, "formatContext is NULL\n");
234 return MMFILE_FORMAT_FAIL;
237 __get_imelody_tag(formatContext->uriFileName, &taginfo);
243 tag_len = strlen(taginfo.title);
245 formatContext->title = mmfile_string_convert((const char *)taginfo.title,
250 (unsigned int *)&cnv_len);
252 if (formatContext->title == NULL) {
253 debug_warning(DEBUG, "failed to UTF8 convert.\n");
254 formatContext->title = mmfile_strdup(taginfo.title);
256 mmfile_free(taginfo.title);
259 if (taginfo.composer) {
260 tag_len = strlen(taginfo.composer);
262 formatContext->composer = mmfile_string_convert((const char *)taginfo.composer,
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);
272 mmfile_free(taginfo.composer);
275 if (taginfo.comment) {
276 tag_len = strlen(taginfo.comment);
278 formatContext->comment = mmfile_string_convert((const char *)taginfo.comment,
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);
288 mmfile_free(taginfo.comment);
291 if (taginfo.copyright) {
292 tag_len = strlen(taginfo.copyright);
294 formatContext->copyright = mmfile_string_convert((const char *)taginfo.copyright,
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);
304 mmfile_free(taginfo.copyright);
307 return MMFILE_FORMAT_SUCCESS;
311 int mmfile_format_close_imy(MMFileFormatContext *formatContext)
313 return MMFILE_FORMAT_SUCCESS;
316 static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags)
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
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;
336 int ret = MMFILE_FORMAT_FAIL;
338 if (!uriname || !tags) {
339 debug_error(DEBUG, "uriname or tags is NULL\n");
340 return MMFILE_FORMAT_FAIL;
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;
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;
356 /* set begin and end point at the file */
358 endoffset = filesize;
362 while (i < endoffset) {
363 mmfile_seek(fp, i, MMFILE_SEEK_SET);
364 readed = mmfile_read(fp, buffer, _MMFILE_IMY_TAG_BUFFER_LENGTH);
366 debug_error(DEBUG, "read error. size = %d. Maybe end of file.\n", readed);
373 if (*(buffer + j) == 0x3a) {
375 } else if (*(buffer + j) == 0x0d) {
376 } else if (*(buffer + j) == 0x0a) {
381 if (imy_key_buffer_index < _MMFILE_IMY_KEY_BUFFER_LENGTH) {
382 imy_key_buffer[imy_key_buffer_index++] = *(buffer + j);
386 if (imy_value_buffer_index < _MMFILE_IMY_VALUE_BUFFER_LENGTH) {
387 imy_value_buffer[imy_value_buffer_index++] = *(buffer + j);
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);
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;
414 memset(buffer, 0x00, _MMFILE_IMY_TAG_BUFFER_LENGTH);
424 static unsigned char *
425 __get_load_memory(char *src, int *out_size)
427 unsigned char *buf = NULL;
428 MMFileIOHandle *fp = NULL;
429 long long src_size = 0L;
434 ret = mmfile_open(&fp, src, MMFILE_RDONLY);
435 if (ret == MMFILE_UTIL_FAIL) {
436 debug_error(DEBUG, "open failed.\n");
441 src_size = mmfile_get_size(fp);
443 debug_error(DEBUG, "failed to get file size.\n");
447 /*alloc read buffer*/
448 if ((buf = mmfile_malloc(src_size)) == NULL) {
449 debug_error(DEBUG, "memory allocation failed.\n");
454 if ((readed = mmfile_read(fp, buf, src_size)) != src_size) {
455 debug_error(DEBUG, "read error. size = %d\n", readed);
459 *out_size = (int)src_size;
472 __is_good_imelody(unsigned char *src, unsigned int size)
478 unsigned int num = sizeof(g_imy_key_str) / sizeof(g_imy_key_str[0]);
480 for (i = 0; i < num; i++) {
481 key_len = strlen(g_imy_key_str[i]);
484 for (j = 0; j <= size - key_len; j++, p++) {
485 if (memcmp(g_imy_key_str[i], p, key_len) == 0) {
490 if (is_found) continue;
491 else return MMFILE_FORMAT_FAIL;
494 return MMFILE_FORMAT_SUCCESS;
498 __init_imelody_data(void)
502 for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) {
504 durationSpec[idx] = 0;
507 for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++)
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 = '%';
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;
526 memset(midiData, 0, sizeof(midiData));
527 memcpy(midiData, midiHeader, MIDI_HEADER_LENGTH);
531 __get_imelody_duration(char style, int number)
534 switch (Melody[number].duration) {
536 noteData[number].duration_on = 183;
537 noteData[number].duration_off = 9;
540 noteData[number].duration_on = 91;
541 noteData[number].duration_off = 5;
544 noteData[number].duration_on = 46;
545 noteData[number].duration_off = 2;
548 noteData[number].duration_on = 23;
549 noteData[number].duration_off = 1;
552 noteData[number].duration_on = 11;
553 noteData[number].duration_off = 1;
556 noteData[number].duration_on = 5;
557 noteData[number].duration_off = 1;
564 else if (style == '1') {
565 switch (Melody[number].duration) {
567 noteData[number].duration_on = 192;
568 noteData[number].duration_off = 0;
571 noteData[number].duration_on = 96;
572 noteData[number].duration_off = 0;
575 noteData[number].duration_on = 48;
576 noteData[number].duration_off = 0;
579 noteData[number].duration_on = 24;
580 noteData[number].duration_off = 0;
583 noteData[number].duration_on = 12;
584 noteData[number].duration_off = 0;
587 noteData[number].duration_on = 6;
588 noteData[number].duration_off = 0;
596 switch (Melody[number].duration) {
598 noteData[number].duration_on = 96;
599 noteData[number].duration_off = 96;
602 noteData[number].duration_on = 48;
603 noteData[number].duration_off = 48;
606 noteData[number].duration_on = 24;
607 noteData[number].duration_off = 24;
610 noteData[number].duration_on = 12;
611 noteData[number].duration_off = 12;
614 noteData[number].duration_on = 6;
615 noteData[number].duration_off = 6;
618 noteData[number].duration_on = 3;
619 noteData[number].duration_off = 3;
626 switch (Melody[number].duration) {
628 durationSpec[number] = 192;
631 durationSpec[number] = 96;
634 durationSpec[number] = 48;
637 durationSpec[number] = 24;
640 durationSpec[number] = 12;
643 durationSpec[number] = 6;
649 if (Melody[number].duration_specifier != '%') {
650 switch (Melody[number].duration_specifier) {
652 noteData[number].duration_on += (durationSpec[number] / 2);
655 noteData[number].duration_on += durationSpec[number];
658 noteData[number].duration_on -= (durationSpec[number] / 3);
664 if (noteData[number].duration_on > MIDI_MAX)
665 noteData[number].duration_on = MIDI_LIMIT;
670 __get_imelody_melody(int number, int octaveValue)
672 if (Melody[number].flat_sharp == '#') {
673 switch (Melody[number].note) {
675 noteData[number].note = octaveValue + 1;
678 noteData[number].note = octaveValue + 3;
681 noteData[number].note = octaveValue + 6;
684 noteData[number].note = octaveValue + 8;
687 noteData[number].note = octaveValue + 10;
694 else if (Melody[number].flat_sharp == '&') {
695 switch (Melody[number].note) {
697 noteData[number].note = octaveValue + 1;
700 noteData[number].note = octaveValue + 3;
703 noteData[number].note = octaveValue + 6;
706 noteData[number].note = octaveValue + 8;
709 noteData[number].note = octaveValue + 10;
717 switch (Melody[number].note) {
719 noteData[number].note = octaveValue;
722 noteData[number].note = octaveValue + 2;
725 noteData[number].note = octaveValue + 4;
728 noteData[number].note = octaveValue + 5;
731 noteData[number].note = octaveValue + 7;
734 noteData[number].note = octaveValue + 9;
737 noteData[number].note = octaveValue + 11;
746 __get_imelody_reset(int number)
748 if (Melody[number].rest >= '0' && Melody[number].rest <= '5') {
749 switch (Melody[number].rest) {
751 noteData[number - 1].duration_off += 192;
752 restSpec[number] = 192;
755 noteData[number - 1].duration_off += 96;
756 restSpec[number] = 96;
759 noteData[number - 1].duration_off += 48;
760 restSpec[number] = 48;
763 noteData[number - 1].duration_off += 24;
764 restSpec[number] = 24;
767 noteData[number - 1].duration_off += 12;
768 restSpec[number] = 12;
771 noteData[number - 1].duration_off += 6;
772 restSpec[number] = 6;
778 if (noteData[number - 1].duration_off > MIDI_MAX && Melody[number].rest_specifier == '%')
779 noteData[number - 1].duration_off = MIDI_LIMIT;
782 if (Melody[number].rest_specifier != '%') {
783 switch (Melody[number].rest_specifier) {
785 noteData[number - 1].duration_off += (restSpec[number] / 2);
788 noteData[number - 1].duration_off += restSpec[number];
791 noteData[number - 1].duration_off -= (restSpec[number] / 3);
797 if (noteData[number - 1].duration_off > MIDI_MAX)
798 noteData[number - 1].duration_off = MIDI_LIMIT;
803 __get_imelody_notetotal(int number)
807 memset(noteBase, 0, sizeof(noteBase));
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;
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;
820 if (noteTotal[6 * number + 2] > MIDI_LIMIT)
821 noteTotal[6 * number + 2] = MIDI_LIMIT;
823 if (noteTotal[6 * number + 5] > MIDI_LIMIT)
824 noteTotal[6 * number + 5] = MIDI_LIMIT;
827 static unsigned char *
828 __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
830 unsigned char *pConvertBuf;
846 __init_imelody_data();
850 midiData[49] = __AvMIDISetVolume(pMelodyBuf);
854 tempoValue = __AvMIDISetBeat(pMelodyBuf);
856 for (number = 0; tempoValue != 0; number++) {
857 tempoData[0] = tempoValue % 16;
858 tempoValue = tempoValue / 16;
860 tempoData[1] = tempoValue % 16;
861 tempoValue = tempoValue / 16;
863 tempoData[2] = tempoData[0] + tempoData[1] * 16;
865 midiData[42 - number] = tempoData[2];
870 while (!(*pMelodyBuf == '@' || (*pMelodyBuf == 'E' && *(pMelodyBuf + 2) == 'D')))
875 if (*pMelodyBuf >= '1' && *pMelodyBuf <= '9') {
876 repeat = *pMelodyBuf - '0';
885 pMelodyBuf = pMelodyBuf + 42;
887 while (!(*pMelodyBuf == 'M' && *(pMelodyBuf + 5) == 'Y' && *(pMelodyBuf + 6) == ':')) /*2007-02-28 AVMS_Sound:k2bogus - UMTS200073205;imy play, [MELODY:] extract fix */
890 pMelodyBuf = pMelodyBuf + 6;
892 pMelodyStart = pMelodyBuf;
894 /**@note if newline detected, stop reading
895 * why? mobileBAE player stopped at newline.
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");
906 if (*pMelodyBuf == '*') {
909 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '8')
910 octave[noteCount] = *pMelodyBuf;
913 if (*pMelodyBuf == '#' || *pMelodyBuf == '&')
914 Melody[noteCount].flat_sharp = *pMelodyBuf;
916 if (*pMelodyBuf == 'r') {
919 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
920 Melody[noteCount].rest = *pMelodyBuf;
923 if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
924 Melody[noteCount].rest_specifier = *pMelodyBuf;
928 if (*pMelodyBuf == 'V') {
931 if (*pMelodyBuf == '+' || *pMelodyBuf == '-')
932 Melody[noteCount].vol = *pMelodyBuf;
935 if (*pMelodyBuf >= 'a' && *pMelodyBuf <= 'g') {
936 Melody[noteCount].note = *pMelodyBuf;
939 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
940 Melody[noteCount].duration = *pMelodyBuf;
943 if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
944 Melody[noteCount].duration_specifier = *pMelodyBuf;
954 for (octaveCount = 1; octaveCount < noteCount; octaveCount++) {
955 if (octave[octaveCount] == '%')
956 octave[octaveCount] = octave[octaveCount - 1];
959 for (number = 0; number < noteCount; number++) {
960 if (octave[0] == '%' && octave[number] == '%')
964 octaveValue = octave[number] - '0';
966 octaveValue = octaveValue * 12;
968 __get_imelody_melody(number, octaveValue);
971 pMelodyBuf = pMelodyStart;
973 style = __AvMIDISetStyle(pMelodyBuf);
975 for (number = 0; number < noteCount; number++)
976 __get_imelody_duration(style, number);
978 for (number = 1; number < noteCount; number++)
979 __get_imelody_reset(number);
981 if (Melody[0].rest >= '0' && Melody[0].rest <= '5') {
982 switch (Melody[0].rest) {
1011 if (Melody[0].rest_specifier != '%') {
1012 switch (Melody[0].rest_specifier) {
1014 midiData[50] += (restSpec[0] / 2);
1017 midiData[50] += restSpec[0];
1020 midiData[50] -= (restSpec[0] / 3);
1027 if (midiData[50] > MIDI_LIMIT)
1028 midiData[50] = MIDI_LIMIT;
1030 if (Melody[0].rest == '0')
1031 midiData[50] = MIDI_LIMIT;
1034 for (number = 0; number < noteCount; number++)
1035 __get_imelody_notetotal(number);
1037 for (number = 1; number < noteCount; number++) {
1040 if (Melody[0].vol == '+')
1041 noteTotal[1] = 84 + VOL_INTERVAL;
1043 if (Melody[0].vol == '-')
1044 noteTotal[1] = 84 - VOL_INTERVAL;
1046 switch (Melody[number].vol) {
1048 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] + VOL_INTERVAL;
1051 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] - VOL_INTERVAL;
1057 if (noteTotal[6 * number + 1] > MIDI_LIMIT)
1058 noteTotal[6 * number + 1] = MIDI_LIMIT;
1060 if ((noteTotal[6 * (number - 1) + 1] == 0 || noteTotal[6 * (number - 1) + 1] == 7) && Melody[number].vol == '-')
1061 noteTotal[6 * number + 1] = 0;
1063 if (Melody[number].vol == '%')
1064 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1];
1067 for (number = 0; number < 6 * noteCount; number++)
1068 midiData[52 + number] = noteTotal[number];
1070 for (number = 6 * noteCount; number < 6 * noteCount * (repeat + 1); number++) {
1071 noteTotal[number] = noteTotal[repeatCount];
1072 midiData[52 + number] = noteTotal[number];
1075 if (repeatCount == 6 * noteCount)
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;
1084 pMelodyBuf = pMelodyStart;
1087 if (*pMelodyBuf != 'E' && *pMelodyBuf != ':') {
1090 while (*pMelodyBuf != 'E') {
1091 if (noteCount >= AV_MIDI_NOTE_MAX) {
1092 debug_warning(DEBUG, "__AvConvertIMelody2MIDI : noteCount>=AV_MIDI_NOTE_MAX\n");
1098 if (*pMelodyBuf == '*') {
1101 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '8')
1102 octave[noteCount] = *pMelodyBuf;
1105 if (*pMelodyBuf == '#' || *pMelodyBuf == '&')
1106 Melody[noteCount].flat_sharp = *pMelodyBuf;
1108 if (*pMelodyBuf == 'r') {
1111 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
1112 Melody[noteCount].rest = *pMelodyBuf;
1115 if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
1116 Melody[noteCount].rest_specifier = *pMelodyBuf;
1120 if (*pMelodyBuf == 'V') {
1123 if (*pMelodyBuf == '+' || *pMelodyBuf == '-')
1124 Melody[noteCount].vol = *pMelodyBuf;
1127 if (*pMelodyBuf >= 'a' && *pMelodyBuf <= 'g') {
1128 Melody[noteCount].note = *pMelodyBuf;
1131 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
1132 Melody[noteCount].duration = *pMelodyBuf;
1135 if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
1136 Melody[noteCount].duration_specifier = *pMelodyBuf;
1146 for (octaveCount = count; octaveCount < noteCount && octaveCount < AV_MIDI_NOTE_MAX; octaveCount++) {
1147 if (octave[octaveCount] == '%')
1148 octave[octaveCount] = octave[octaveCount - 1];
1151 for (number = count; number < noteCount && number < AV_MIDI_NOTE_MAX; number++) {
1152 octaveValue = octave[number] - '0';
1154 octaveValue = octaveValue * 12;
1156 __get_imelody_melody(number, octaveValue);
1157 __get_imelody_duration(style, number);
1160 for (number = count + 1; number < noteCount && number < AV_MIDI_NOTE_MAX; number++)
1161 __get_imelody_reset(number);
1163 if (Melody[count].rest >= '0' && Melody[count].rest <= '5') {
1164 switch (Melody[count].rest) {
1166 midiData[52 + (6 * count * (repeat + 1) - 1)] += 192;
1167 restSpec[count] = 192;
1170 midiData[52 + (6 * count * (repeat + 1) - 1)] += 96;
1171 restSpec[count] = 96;
1174 midiData[52 + (6 * count * (repeat + 1) - 1)] += 48;
1175 restSpec[count] = 48;
1178 midiData[52 + (6 * count * (repeat + 1) - 1)] += 24;
1179 restSpec[count] = 24;
1182 midiData[52 + (6 * count * (repeat + 1) - 1)] += 12;
1183 restSpec[count] = 12;
1186 midiData[52 + (6 * count * (repeat + 1) - 1)] += 6;
1187 restSpec[count] = 6;
1193 if (Melody[count].rest_specifier != '%') {
1194 switch (Melody[count].rest_specifier) {
1196 midiData[52 + (6 * count * (repeat + 1) - 1)] += (restSpec[count] / 2);
1199 midiData[52 + (6 * count * (repeat + 1) - 1)] += restSpec[count];
1202 midiData[52 + (6 * count * (repeat + 1) - 1)] -= (restSpec[count] / 3);
1209 if (midiData[52 + (6 * count * (repeat + 1) - 1)] > MIDI_LIMIT)
1210 midiData[52 + (6 * count * (repeat + 1) - 1)] = MIDI_LIMIT;
1212 if (Melody[count].rest == '0')
1213 midiData[52 + (6 * count * (repeat + 1) - 1)] = MIDI_LIMIT;
1216 for (number = count; number < noteCount; number++)
1217 __get_imelody_notetotal(number);
1219 for (number = count + 1; number < noteCount; number++) {
1220 noteTotal[6 * count + 1] = midiData[52 + (6 * count * (repeat + 1) - 5)];
1222 if (Melody[count].vol == '+')
1223 noteTotal[6 * count + 1] = noteTotal[6 * count + 1] + VOL_INTERVAL;
1225 if (Melody[count].vol == '-' && (noteTotal[6 * count + 1] == 0 || noteTotal[6 * count + 1] == 7))
1226 noteTotal[6 * count + 1] = 0;
1228 if (Melody[count].vol == '-' && noteTotal[6 * count + 1] >= 12)
1229 noteTotal[6 * count + 1] = noteTotal[6 * count + 1] - VOL_INTERVAL;
1231 if (noteTotal[6 * count + 1] > MIDI_LIMIT)
1232 noteTotal[6 * count + 1] = MIDI_LIMIT;
1234 switch (Melody[number].vol) {
1236 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] + VOL_INTERVAL;
1239 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] - VOL_INTERVAL;
1245 if (noteTotal[6 * number + 1] > MIDI_LIMIT)
1246 noteTotal[6 * number + 1] = MIDI_LIMIT;
1248 if ((noteTotal[6 * (number - 1) + 1] == 0 || noteTotal[6 * (number - 1) + 1] == 7) && Melody[number].vol == '-')
1249 noteTotal[6 * number + 1] = 0;
1251 if (Melody[number].vol == '%')
1252 noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1];
1255 numberCount = 6 * count;
1257 for (number = 6 * count * (repeat + 1); number < 6 * (count * (repeat + 1) + (noteCount - count)); number++) {
1258 midiData[52 + number] = noteTotal[numberCount];
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 */
1268 for (number = 6 * (count * (repeat + 1) + (noteCount - count)); number <= 6 * (count * (repeat + 1) + (noteCount - count)) + 3; number++)
1269 midiData[51 + number] = noteTotal[number];
1271 trackSize = (6 * (count * (repeat + 1) + (noteCount - count)) + 56) - 22 - 1 ;
1273 midiData[20] = (trackSize & 0xff00) >> 8;
1274 midiData[21] = (trackSize & 0x00ff);
1277 *pBufLen = 6 * (count * (repeat + 1) + (noteCount - count)) + 56 - 1;
1279 pConvertBuf = (unsigned char *) mmfile_malloc(*pBufLen);
1280 if (pConvertBuf == NULL) {
1281 debug_error(DEBUG, "__AvConvertIMelody2MIDI: malloc failed!\n");
1285 memcpy(pConvertBuf, midiData, *pBufLen);
1290 static unsigned char
1291 __AvMIDISetVolume(char *pMelodyBuf)
1293 unsigned char midiVol;
1295 pMelodyBuf = pMelodyBuf + 42;
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 */
1300 if (*pMelodyBuf != 'V')
1301 midiVol = AV_MIDI_VOL_MAX;
1304 pMelodyBuf = pMelodyBuf + 5;
1306 if (*pMelodyBuf == 'E')
1307 pMelodyBuf = pMelodyBuf + 3;
1310 pMelodyBuf = pMelodyBuf - 4;
1312 if (*pMelodyBuf == '1') {
1315 switch (*pMelodyBuf) {
1317 midiVol = AV_MIDI_VOL_MAX;
1320 midiVol = AV_MIDI_VOL_MAX;
1323 midiVol = AV_MIDI_VOL_MAX;
1326 midiVol = AV_MIDI_VOL_MAX;
1329 midiVol = AV_MIDI_VOL_MAX;
1332 midiVol = AV_MIDI_VOL_MAX;
1335 midiVol = AV_MIDI_VOL_MAX;
1341 switch (*pMelodyBuf) {
1346 midiVol = AV_MIDI_VOL_MAX;
1349 midiVol = AV_MIDI_VOL_MAX;
1352 midiVol = AV_MIDI_VOL_MAX;
1355 midiVol = AV_MIDI_VOL_MAX;
1358 midiVol = AV_MIDI_VOL_MAX;
1361 midiVol = AV_MIDI_VOL_MAX;
1364 midiVol = AV_MIDI_VOL_MAX;
1367 midiVol = AV_MIDI_VOL_MAX;
1370 midiVol = AV_MIDI_VOL_MAX;
1379 __AvMIDISetBeat(char *pMelodyBuf)
1381 int bpmValue[4] = {0};
1384 pMelodyBuf = pMelodyBuf + 42;
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 */
1389 if (*pMelodyBuf != 'B')
1393 pMelodyBuf = pMelodyBuf + 4;
1395 if (*pMelodyBuf == ':') {
1398 if (*pMelodyBuf >= '1' && *pMelodyBuf <= '9') {
1399 bpmValue[0] = *pMelodyBuf - '0';
1402 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9') {
1403 bpmValue[1] = *pMelodyBuf - '0';
1406 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9') {
1407 bpmValue[2] = *pMelodyBuf - '0';
1409 bpmValue[0] = bpmValue[0] * 100;
1410 bpmValue[1] = bpmValue[1] * 10;
1415 bpmValue[0] = bpmValue[0] * 10;
1419 bpmValue[3] = bpmValue[0] + bpmValue[1] + bpmValue[2];
1423 if (bpmValue[3] < 25 || bpmValue[3] > 900)
1426 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9')
1429 beatValue = 1000000 * 60 / bpmValue[3];
1431 debug_msg(RELEASE, "beat: %d = 1000000 * 60 / %d\n", beatValue, bpmValue[3]);
1437 __AvMIDISetStyle(char *pMelodyBuf)
1439 char styleValue = '0';
1441 while (*pMelodyBuf != 'S')
1446 if (*pMelodyBuf >= '0' && *pMelodyBuf <= '2')
1449 if (*pMelodyBuf != '.') {
1451 styleValue = *pMelodyBuf;
1454 if (styleValue < '0' || styleValue > '2') {
1455 debug_warning(DEBUG, "unknown style. use default(S0)\n");
1459 debug_msg(RELEASE, "style: '%c'\n", styleValue);