format IMELODY cleanup 22/233222/2
authorMinje Ahn <minje.ahn@samsung.com>
Wed, 13 May 2020 06:08:46 +0000 (15:08 +0900)
committerMinje ahn <minje.ahn@samsung.com>
Wed, 13 May 2020 06:25:49 +0000 (06:25 +0000)
Change-Id: I581d81b7b4b7043adadbf9759535721ba39c4712
Signed-off-by: Minje Ahn <minje.ahn@samsung.com>
formats/ffmpeg/mm_file_format_imelody.c

index d9e4298..f5ac646 100755 (executable)
 
 #define MIDI_HEADER_LENGTH             52
 
+#define IMY_KEY_STYLE "STYLE:S"
+#define IMY_KEY_BEAT "BEAT:"
+#define IMY_KEY_VOLUME "VOLUME:V"
+#define IMY_KEY_NAME "NAME:"
+#define IMY_KEY_COMPOSER "COMPOSER:"
+#define IMY_KEY_COPYRIGHT "COPYRIGHT:"
+#define IMY_KEY_MELODY "MELODY:"
+
 static unsigned char midiData[AV_MIDI_COUNT_MAX] ;
 static unsigned char midiHeader[MIDI_HEADER_LENGTH] = {0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x4d, 0x54,
                                                                                                        0x72, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff,
@@ -80,345 +88,28 @@ static const char *g_imy_key_str[] = {
        "END:IMELODY",
 };
 
-
-static int __is_good_imelody(unsigned char *src, unsigned int size);
-static unsigned char *__get_load_memory(char *src, int *out_size);
-static unsigned char __AvMIDISetVolume(char *pMelodyBuf);
-static int __AvMIDISetBeat(char *pMelodyBuf);
-static char __AvMIDISetStyle(char *pMelodyBuf);
-static unsigned char *__AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen);
-static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags);
-
-
-/* interface functions */
-int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext);
-int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
-int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext);
-int mmfile_format_close_imy(MMFileFormatContext *formatContext);
-
-
-
-int mmfile_format_open_imy(MMFileFormatContext *formatContext)
+static bool __is_good_imelody(char *src, unsigned int size)
 {
-       int ret = 0;
-
-       if (!formatContext) {
-               debug_error(DEBUG, "formatContext is NULL\n");
-               return MMFILE_FORMAT_FAIL;
-       }
-
-       ret = MMFileFormatIsValidIMY(NULL, formatContext->uriFileName, 0);
-       if (ret == 0) {
-               debug_error(DEBUG, "It is not imelody file\n");
-               return MMFILE_FORMAT_FAIL;
-       }
-
-       formatContext->ReadStream   = mmfile_format_read_stream_imy;
-       formatContext->ReadFrame    = mmfile_format_read_frame_imy;
-       formatContext->ReadTag      = mmfile_format_read_tag_imy;
-       formatContext->Close        = mmfile_format_close_imy;
-
-       formatContext->videoTotalTrackNum = 0;
-       formatContext->audioTotalTrackNum = 1;
-
-       formatContext->privateFormatData = NULL;
-
-       return MMFILE_FORMAT_SUCCESS;
-}
-
-
-int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext)
-{
-       MIDI_INFO_SIMPLE *info = NULL;
-       MMFileFormatStream  *audioStream = NULL;
-
-       unsigned char   *imy = NULL;
-       int                             imy_size = 0;
-       unsigned char   *midi = NULL;
-       unsigned int    midi_size = 0;
-       char                    src2[MMFILE_URI_MAX_LEN];
-
-       int ret = 0;
-
-       if (!formatContext) {
-               debug_error(DEBUG, "formatContext is NULL\n");
-               return MMFILE_FORMAT_FAIL;
-       }
-
-       /*convert iMelody to Midi*/
-       imy = __get_load_memory(formatContext->uriFileName, &imy_size);
-       if (!imy) {
-               debug_error(DEBUG, "failed to load memory.\n");
-               goto exception;
-       }
-       ret = __is_good_imelody(imy, imy_size);
-       if (ret != MMFILE_FORMAT_SUCCESS) {
-               debug_error(DEBUG, "it's broken file.\n");
-               goto exception;
-       }
-       midi = __AvConvertIMelody2MIDI((char *)imy, &midi_size);
-       if (!midi) {
-               debug_error(DEBUG, "failed to convert.");
-               goto exception;
-       }
-
-       /*make uri*/
-       memset(src2, 0x00, MMFILE_URI_MAX_LEN);
-       snprintf(src2, sizeof(src2), "%s%u:%u", MMFILE_MEM_URI, (unsigned int)midi, midi_size);
-
-       /*get infomation*/
-       info = mmfile_format_get_midi_infomation(src2);
-
-       formatContext->duration = info->duration;
-       formatContext->videoStreamId = -1;
-       formatContext->videoTotalTrackNum = 0;
-       formatContext->audioTotalTrackNum = info->track_num;
-       formatContext->nbStreams = 1;
-
-       audioStream = g_new0(MMFileFormatStream, 1);
+       char *found = NULL;
+       int i = 0;
+       int num = sizeof(g_imy_key_str) / sizeof(g_imy_key_str[0]);
 
-       audioStream->streamType = MMFILE_AUDIO_STREAM;
-       audioStream->codecId = MM_AUDIO_CODEC_IMELODY;
-       audioStream->bitRate = 0;
-       audioStream->framePerSec = 0;
-       audioStream->width = 0;
-       audioStream->height = 0;
-       audioStream->nbChannel = 1;
-       audioStream->samplePerSec = 0;
-       formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
-
-#ifdef  __MMFILE_TEST_MODE__
-       mmfile_format_print_contents(formatContext);
-#endif
-
-       mmfile_free(imy);
-       mmfile_free(midi);
-       mmfile_format_free_midi_infomation(info);
-       return MMFILE_FORMAT_SUCCESS;
-
-exception:
-       mmfile_free(imy);
-       mmfile_free(midi);
-       mmfile_format_free_midi_infomation(info);
-       mmfile_free(audioStream);
-       return MMFILE_FORMAT_FAIL;
-}
-
-
-int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
-{
-       return MMFILE_FORMAT_SUCCESS;
-}
-
-
-
-int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext)
-{
-       tMMFileImelodyTagInfo taginfo = {0, };
-       unsigned int tag_len;
-       unsigned int cnv_len;
-       const char *locale = MMFileUtilGetLocale();
-
-       if (!formatContext) {
-               debug_error(DEBUG, "formatContext is NULL\n");
-               return MMFILE_FORMAT_FAIL;
-       }
-
-       __get_imelody_tag(formatContext->uriFileName, &taginfo);
-
-       /**
-        * UTF8 convert
-        */
-       if (taginfo.title) {
-               tag_len = strlen(taginfo.title);
-               cnv_len = 0;
-               formatContext->title = mmfile_string_convert((const char *)taginfo.title,
-                                                                                               tag_len,
-                                                                                               "UTF-8",
-                                                                                               locale,
-                                                                                               NULL,
-                                                                                               (unsigned int *)&cnv_len);
-
-               if (formatContext->title == NULL) {
-                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
-                       formatContext->title = g_strdup(taginfo.title);
-               }
-               mmfile_free(taginfo.title);
-       }
-
-       if (taginfo.composer) {
-               tag_len = strlen(taginfo.composer);
-               cnv_len = 0;
-               formatContext->composer = mmfile_string_convert((const char *)taginfo.composer,
-                                                                                               tag_len,
-                                                                                               "UTF-8",
-                                                                                               locale,
-                                                                                               NULL,
-                                                                                               (unsigned int *)&cnv_len);
-               if (formatContext->composer == NULL) {
-                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
-                       formatContext->composer = g_strdup(taginfo.composer);
-               }
-               mmfile_free(taginfo.composer);
-       }
-
-       if (taginfo.comment) {
-               tag_len = strlen(taginfo.comment);
-               cnv_len = 0;
-               formatContext->comment = mmfile_string_convert((const char *)taginfo.comment,
-                                                                                               tag_len,
-                                                                                               "UTF-8",
-                                                                                               locale,
-                                                                                               NULL,
-                                                                                               (unsigned int *)&cnv_len);
-               if (formatContext->comment == NULL) {
-                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
-                       formatContext->comment = g_strdup(taginfo.comment);
-               }
-               mmfile_free(taginfo.comment);
-       }
-
-       if (taginfo.copyright) {
-               tag_len = strlen(taginfo.copyright);
-               cnv_len = 0;
-               formatContext->copyright = mmfile_string_convert((const char *)taginfo.copyright,
-                                                                                               tag_len,
-                                                                                               "UTF-8",
-                                                                                               locale,
-                                                                                               NULL,
-                                                                                               (unsigned int *)&cnv_len);
-               if (formatContext->copyright == NULL) {
-                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
-                       formatContext->copyright = g_strdup(taginfo.copyright);
-               }
-               mmfile_free(taginfo.copyright);
+       for (i = 0; i < num; i++) {
+               found = g_strstr_len(src, size, g_imy_key_str[i]);
+               if (!found)
+                       return false;
        }
 
-       return MMFILE_FORMAT_SUCCESS;
-}
-
-
-int mmfile_format_close_imy(MMFileFormatContext *formatContext)
-{
-       return MMFILE_FORMAT_SUCCESS;
+       return true;
 }
 
-static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags)
+static unsigned char * __get_load_memory(const char *src, int *out_size)
 {
-#define _MMFILE_IMY_TAG_BUFFER_LENGTH   512
-#define _MMFILE_IMY_HEADER_LENGTH       20
-#define _MMFILE_IMY_KEY_BUFFER_LENGTH   20
-#define _MMFILE_IMY_VALUE_BUFFER_LENGTH 128
-
+       unsigned char *buf = NULL;
        MMFileIOHandle *fp = NULL;
-       unsigned char buffer[_MMFILE_IMY_TAG_BUFFER_LENGTH] = {0, };
-       long long     filesize = 0;
-       unsigned int  startoffset = 0;
-       unsigned int  endoffset = 0, i = 0;
-       int  readed = 0, j = 0;
-       char          imy_key_buffer[_MMFILE_IMY_KEY_BUFFER_LENGTH] = {0, };
-       unsigned int  imy_key_buffer_index = 0;
-       char          imy_value_buffer[_MMFILE_IMY_VALUE_BUFFER_LENGTH] = {0, };
-       unsigned int  imy_value_buffer_index = 0;
-       int           isKeyBuffer = 1;
-       int           isDone  = 0;
-
-       int ret = MMFILE_FORMAT_FAIL;
-
-       if (!uriname || !tags) {
-               debug_error(DEBUG, "uriname or tags is NULL\n");
-               return MMFILE_FORMAT_FAIL;
-       }
-
-       ret = mmfile_open(&fp, uriname, MMFILE_RDONLY);
-       if (ret == MMFILE_UTIL_FAIL) {
-               debug_error(DEBUG, "open failed.\n");
-               return MMFILE_FORMAT_FAIL;
-       }
-
-       filesize = mmfile_get_size(fp);
-       if (filesize < _MMFILE_IMY_HEADER_LENGTH) {
-               debug_error(DEBUG, "header is too small.\n");
-               ret = MMFILE_FORMAT_FAIL;
-               goto exit;
-       }
-
-       /* set begin and end point at the file */
-       startoffset = 0;
-       endoffset = filesize;
-
-       i = startoffset;
-       isKeyBuffer = 1;
-       while (i < endoffset) {
-               mmfile_seek(fp, i, MMFILE_SEEK_SET);
-               readed = mmfile_read(fp, buffer, _MMFILE_IMY_TAG_BUFFER_LENGTH);
-               if (readed < 0) {
-                       debug_error(DEBUG, "read error. size = %d. Maybe end of file.\n", readed);
-                       ret = 0;
-                       break;
-               }
-
-               j = 0;
-               while (j < readed) {
-                       if (*(buffer + j) == 0x3a) {
-                               isKeyBuffer = 0;
-                       } else if (*(buffer + j) == 0x0d) {
-                       } else if (*(buffer + j) == 0x0a) {
-                               isKeyBuffer = 1;
-                               isDone = 1;
-                       } else {
-                               if (isKeyBuffer) {
-                                       if (imy_key_buffer_index < _MMFILE_IMY_KEY_BUFFER_LENGTH) {
-                                               imy_key_buffer[imy_key_buffer_index++] = *(buffer + j);
-                                       }
-
-                               } else {
-                                       if (imy_value_buffer_index < _MMFILE_IMY_VALUE_BUFFER_LENGTH) {
-                                               imy_value_buffer[imy_value_buffer_index++] = *(buffer + j);
-                                       }
-                               }
-                       }
-
-                       if (isDone) {
-                               if (!strncmp(imy_key_buffer, "NAME", 4)) {
-                                       mmfile_free(tags->title);
-                                       tags->title = g_strdup(imy_value_buffer);
-                               } else if (!strncmp(imy_key_buffer, "COMPOSER", 8)) {
-                                       mmfile_free(tags->composer);
-                                       tags->composer = g_strdup(imy_value_buffer);
-                               } else if (!strncmp(imy_key_buffer, "COPYRIGHT", 9)) {
-                                       mmfile_free(tags->copyright);
-                                       tags->copyright = g_strdup(imy_value_buffer);
-                               }
-
-                               memset(imy_key_buffer, 0x00, _MMFILE_IMY_KEY_BUFFER_LENGTH);
-                               memset(imy_value_buffer, 0x00, _MMFILE_IMY_VALUE_BUFFER_LENGTH);
-                               imy_key_buffer_index = 0;
-                               imy_value_buffer_index = 0;
-                               isDone = 0;
-                       }
-
-                       j++;
-               }
-
-               memset(buffer, 0x00, _MMFILE_IMY_TAG_BUFFER_LENGTH);
-
-               i = i + j;
-       }
-
-exit:
-       mmfile_close(fp);
-       return ret;
-}
-
-static unsigned char *
-__get_load_memory(char *src, int *out_size)
-{
-       unsigned char                   *buf = NULL;
-       MMFileIOHandle  *fp = NULL;
-       long long               src_size = 0L;
-       int                             readed = 0;
-       int                             ret = 0;
+       long long src_size = 0L;
+       int readed = 0;
+       int ret = 0;
 
        /*open*/
        ret = mmfile_open(&fp, src, MMFILE_RDONLY);
@@ -454,35 +145,61 @@ failed:
        return NULL;
 }
 
-
-static int
-__is_good_imelody(unsigned char *src, unsigned int size)
+static unsigned char __AvMIDISetVolume(const char *pMelodyBuf)
 {
-       unsigned int i, j;
-       int key_len;
-       int is_found;
-       unsigned char *p;
-       unsigned int num = sizeof(g_imy_key_str) / sizeof(g_imy_key_str[0]);
+       /* Format - VOLUME:V## (V0 to V15, Optional) */
+       char *found = strstr(pMelodyBuf, IMY_KEY_VOLUME);
+       /* Default [AV_MIDI_VOL_MAX] */
+       unsigned char vol = AV_MIDI_VOL_MAX;
 
-       for (i = 0; i < num; i++) {
-               key_len = strlen(g_imy_key_str[i]);
-               p = src;
-               is_found = 0;
-               for (j = 0; j <= size - key_len; j++, p++) {
-                       if (memcmp(g_imy_key_str[i], p, key_len) == 0) {
-                               is_found = 1;
-                               break;
-                       }
-               }
-               if (is_found) continue;
-               else return MMFILE_FORMAT_FAIL;
+       if (found && *(found + strlen(IMY_KEY_VOLUME)) == '0')
+                       vol = 0;
+
+       return vol;
+}
+
+static int __AvMIDISetBeat(const char *pMelodyBuf)
+{
+       /* Format - BEAT:### (Optional) */
+       char *found = strstr(pMelodyBuf, IMY_KEY_BEAT);
+       /* Default [120] */
+       char *beatValue = NULL;
+       int bpm = 120;
+       int beat = 0;
+
+       if (found) {
+               beatValue = g_strndup(found + strlen(IMY_KEY_BEAT), 3);
+               /* No need to check integer bound */
+               bpm = atoi(beatValue);
+
+               if (bpm < 25 || bpm > 900)
+                       bpm = 120;
        }
 
-       return MMFILE_FORMAT_SUCCESS;
+       beat = 1000000 * 60 / bpm;
+       debug_msg(RELEASE, "beat: %d\n", beat);
+
+       return beat;
 }
 
-static void
-__init_imelody_data(void)
+static char __AvMIDISetStyle(const char *pMelodyBuf)
+{
+       /* Format - STYLE:S# (S0 to S2, Optional) */
+       char *found = strstr(pMelodyBuf, IMY_KEY_STYLE);
+       char style = '0';
+
+       if (found)
+               style = *(found + strlen(IMY_KEY_STYLE));
+
+       if (style != '0' && style != '1' && style != '2')
+               style = '0';
+
+       debug_msg(RELEASE, "style: '%c'\n", style);
+
+       return style;
+}
+
+static void __init_imelody_data(void)
 {
        int idx = 0;
 
@@ -514,8 +231,7 @@ __init_imelody_data(void)
        memcpy(midiData, midiHeader, MIDI_HEADER_LENGTH);
 }
 
-static void
-__get_imelody_duration(char style, int number)
+static void __get_imelody_duration(char style, int number)
 {
        if (style == '0') {
                switch (Melody[number].duration) {
@@ -546,9 +262,7 @@ __get_imelody_duration(char style, int number)
                default:
                        break;
                }
-       }
-
-       else if (style == '1') {
+       } else if (style == '1') {
                switch (Melody[number].duration) {
                case '0':
                        noteData[number].duration_on = 192;
@@ -577,9 +291,7 @@ __get_imelody_duration(char style, int number)
                default:
                        break;
                }
-       }
-
-       else {
+       } else {
                switch (Melody[number].duration) {
                case '0':
                        noteData[number].duration_on = 96;
@@ -653,8 +365,7 @@ __get_imelody_duration(char style, int number)
        }
 }
 
-static void
-__get_imelody_melody(int number, int octaveValue)
+static void __get_imelody_melody(int number, int octaveValue)
 {
        if (Melody[number].flat_sharp == '#') {
                switch (Melody[number].note) {
@@ -676,9 +387,7 @@ __get_imelody_melody(int number, int octaveValue)
                default:
                        break;
                }
-       }
-
-       else if (Melody[number].flat_sharp == '&') {
+       } else if (Melody[number].flat_sharp == '&') {
                switch (Melody[number].note) {
                case 'd':
                        noteData[number].note = octaveValue + 1;
@@ -698,9 +407,7 @@ __get_imelody_melody(int number, int octaveValue)
                default:
                        break;
                }
-       }
-
-       else {
+       } else {
                switch (Melody[number].note) {
                case 'c':
                        noteData[number].note = octaveValue;
@@ -729,8 +436,7 @@ __get_imelody_melody(int number, int octaveValue)
        }
 }
 
-static void
-__get_imelody_reset(int number)
+static void __get_imelody_reset(int number)
 {
        if (Melody[number].rest >= '0' && Melody[number].rest <= '5') {
                switch (Melody[number].rest) {
@@ -786,8 +492,7 @@ __get_imelody_reset(int number)
        }
 }
 
-static void
-__get_imelody_notetotal(int number)
+static void __get_imelody_notetotal(int number)
 {
        char noteBase[6];
 
@@ -811,10 +516,10 @@ __get_imelody_notetotal(int number)
                noteTotal[6 * number + 5] = MIDI_LIMIT;
 }
 
-static unsigned char *
-__AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
+static unsigned char * __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
 {
-       char *pStart;
+       /* Duration measures the length of one play. So no need extract REPEAT keyword */
+       char *pStart = pMelodyBuf;
        char *pMelodyStart;
        int octaveCount;
        int octaveValue;
@@ -826,18 +531,13 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
        int tempoData[3];
        int tempoValue;
        int trackSize;
-       int repeat = 0;
        int repeatCount = 0;
 
        __init_imelody_data();
 
-       pStart = pMelodyBuf;
-
-       midiData[49] = __AvMIDISetVolume(pMelodyBuf);
-
-       pMelodyBuf = pStart;
-
-       tempoValue = __AvMIDISetBeat(pMelodyBuf);
+       midiData[49] = __AvMIDISetVolume(pStart);
+       tempoValue = __AvMIDISetBeat(pStart);
+       style = __AvMIDISetStyle(pStart);
 
        for (number = 0; tempoValue != 0; number++) {
                tempoData[0] = tempoValue % 16;
@@ -851,86 +551,65 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
                midiData[42 - number] = tempoData[2];
        }
 
-       pMelodyBuf = pStart;
+       /* Find MELODY */
+       pStart = strstr(pMelodyBuf, IMY_KEY_MELODY) + strlen(IMY_KEY_MELODY);
 
-       while (!(*pMelodyBuf == '@' || (*pMelodyBuf == 'E' && *(pMelodyBuf + 2) == 'D')))
-               pMelodyBuf++;
-
-       pMelodyBuf++;
-
-       if (*pMelodyBuf >= '1' && *pMelodyBuf <= '9') {
-               repeat = *pMelodyBuf - '0';
-               pMelodyBuf++;
-
-       }
-
-       repeat = 0;
-
-       pMelodyBuf = pStart;
-
-       pMelodyBuf = pMelodyBuf + 42;
-
-       while (!(*pMelodyBuf == 'M' && *(pMelodyBuf + 5) == 'Y' && *(pMelodyBuf + 6) == ':')) /*2007-02-28 AVMS_Sound:k2bogus - UMTS200073205;imy play, [MELODY:] extract fix */
-               pMelodyBuf++;
-
-       pMelodyBuf = pMelodyBuf + 6;
-
-       pMelodyStart = pMelodyBuf;
+       /*Melody start point */
+       pMelodyStart = pStart;
 
        /**@note if newline detected, stop reading
         *       why? mobileBAE player stopped at newline.
         *       2009/08/12
         */
-       while (!((*pMelodyBuf == 'E' && *(pMelodyBuf + 2) == 'D') || (*pMelodyBuf == '\n'))) {
+       while (!((*pStart == 'E' && *(pStart + 2) == 'D') || (*pStart == '\n'))) {
                if (noteCount >= AV_MIDI_NOTE_MAX) {
                        debug_warning(DEBUG, "__AvConvertIMelody2MIDI : noteCount>=AV_MIDI_NOTE_MAX\n");
                        break;
                }
 
-               pMelodyBuf++;
+               pStart++;
 
-               if (*pMelodyBuf == '*') {
-                       pMelodyBuf++;
+               if (*pStart == '*') {
+                       pStart++;
 
-                       if (*pMelodyBuf >= '0' && *pMelodyBuf <= '8')
-                               octave[noteCount] = *pMelodyBuf;
+                       if (*pStart >= '0' && *pStart <= '8')
+                               octave[noteCount] = *pStart;
                }
 
-               if (*pMelodyBuf == '#' || *pMelodyBuf == '&')
-                       Melody[noteCount].flat_sharp = *pMelodyBuf;
+               if (*pStart == '#' || *pStart == '&')
+                       Melody[noteCount].flat_sharp = *pStart;
 
-               if (*pMelodyBuf == 'r') {
-                       pMelodyBuf++;
+               if (*pStart == 'r') {
+                       pStart++;
 
-                       if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
-                               Melody[noteCount].rest = *pMelodyBuf;
-                               pMelodyBuf++;
+                       if (*pStart >= '0' && *pStart <= '5') {
+                               Melody[noteCount].rest = *pStart;
+                               pStart++;
 
-                               if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
-                                       Melody[noteCount].rest_specifier = *pMelodyBuf;
+                               if (*pStart == '.' || *pStart == ':' || *pStart == ';')
+                                       Melody[noteCount].rest_specifier = *pStart;
                        }
                }
 
-               if (*pMelodyBuf == 'V') {
-                       pMelodyBuf++;
+               if (*pStart == 'V') {
+                       pStart++;
 
-                       if (*pMelodyBuf == '+' || *pMelodyBuf == '-')
-                               Melody[noteCount].vol = *pMelodyBuf;
+                       if (*pStart == '+' || *pStart == '-')
+                               Melody[noteCount].vol = *pStart;
                }
 
-               if (*pMelodyBuf >= 'a' && *pMelodyBuf <= 'g') {
-                       Melody[noteCount].note = *pMelodyBuf;
-                       pMelodyBuf++;
+               if (*pStart >= 'a' && *pStart <= 'g') {
+                       Melody[noteCount].note = *pStart;
+                       pStart++;
 
-                       if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
-                               Melody[noteCount].duration = *pMelodyBuf;
-                               pMelodyBuf++;
-
-                               if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
-                                       Melody[noteCount].duration_specifier = *pMelodyBuf;
+                       if (*pStart >= '0' && *pStart <= '5') {
+                               Melody[noteCount].duration = *pStart;
+                               pStart++;
 
+                               if (*pStart == '.' || *pStart == ':' || *pStart == ';')
+                                       Melody[noteCount].duration_specifier = *pStart;
                                else
-                                       pMelodyBuf--;
+                                       pStart--;
 
                                noteCount++;
                        }
@@ -954,9 +633,7 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
                __get_imelody_melody(number, octaveValue);
        }
 
-       pMelodyBuf = pMelodyStart;
-
-       style = __AvMIDISetStyle(pMelodyBuf);
+       pStart = pMelodyStart;
 
        for (number = 0; number < noteCount; number++)
                __get_imelody_duration(style, number);
@@ -1053,7 +730,7 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
        for (number = 0; number < 6 * noteCount; number++)
                midiData[52 + number] = noteTotal[number];
 
-       for (number = 6 * noteCount; number < 6 * noteCount * (repeat + 1); number++) {
+       for (number = 6 * noteCount; number < 6 * noteCount; number++) {
                noteTotal[number] = noteTotal[repeatCount];
                midiData[52 + number] = noteTotal[number];
                repeatCount++;
@@ -1062,67 +739,67 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
                        repeatCount = 0;
        }
 
-       for (number = 1; number < 6 * noteCount * (repeat + 1); number = number + 6) {
+       for (number = 1; number < 6 * noteCount; number = number + 6) {
                if (midiData[52 + number] > MIDI_LIMIT)
                        midiData[52 + number] = MIDI_LIMIT;
        }
 
-       pMelodyBuf = pMelodyStart;
+       pStart = pMelodyStart;
        count = noteCount;
 
-       if (*pMelodyBuf != 'E' && *pMelodyBuf != ':') {
-               pMelodyBuf--;
+       if (*pStart != 'E' && *pStart != ':') {
+               pStart--;
 
-               while (*pMelodyBuf != 'E') {
+               while (*pStart != 'E') {
                        if (noteCount >= AV_MIDI_NOTE_MAX) {
                                debug_warning(DEBUG, "__AvConvertIMelody2MIDI : noteCount>=AV_MIDI_NOTE_MAX\n");
                                break;
                        }
 
-                       pMelodyBuf++;
+                       pStart++;
 
-                       if (*pMelodyBuf == '*') {
-                               pMelodyBuf++;
+                       if (*pStart == '*') {
+                               pStart++;
 
-                               if (*pMelodyBuf >= '0' && *pMelodyBuf <= '8')
-                                       octave[noteCount] = *pMelodyBuf;
+                               if (*pStart >= '0' && *pStart <= '8')
+                                       octave[noteCount] = *pStart;
                        }
 
-                       if (*pMelodyBuf == '#' || *pMelodyBuf == '&')
-                               Melody[noteCount].flat_sharp = *pMelodyBuf;
+                       if (*pStart == '#' || *pStart == '&')
+                               Melody[noteCount].flat_sharp = *pStart;
 
-                       if (*pMelodyBuf == 'r') {
-                               pMelodyBuf++;
+                       if (*pStart == 'r') {
+                               pStart++;
 
-                               if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
-                                       Melody[noteCount].rest = *pMelodyBuf;
-                                       pMelodyBuf++;
+                               if (*pStart >= '0' && *pStart <= '5') {
+                                       Melody[noteCount].rest = *pStart;
+                                       pStart++;
 
-                                       if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
-                                               Melody[noteCount].rest_specifier = *pMelodyBuf;
+                                       if (*pStart == '.' || *pStart == ':' || *pStart == ';')
+                                               Melody[noteCount].rest_specifier = *pStart;
                                }
                        }
 
-                       if (*pMelodyBuf == 'V') {
-                               pMelodyBuf++;
+                       if (*pStart == 'V') {
+                               pStart++;
 
-                               if (*pMelodyBuf == '+' || *pMelodyBuf == '-')
-                                       Melody[noteCount].vol = *pMelodyBuf;
+                               if (*pStart == '+' || *pStart == '-')
+                                       Melody[noteCount].vol = *pStart;
                        }
 
-                       if (*pMelodyBuf >= 'a' && *pMelodyBuf <= 'g') {
-                               Melody[noteCount].note = *pMelodyBuf;
-                               pMelodyBuf++;
+                       if (*pStart >= 'a' && *pStart <= 'g') {
+                               Melody[noteCount].note = *pStart;
+                               pStart++;
 
-                               if (*pMelodyBuf >= '0' && *pMelodyBuf <= '5') {
-                                       Melody[noteCount].duration = *pMelodyBuf;
-                                       pMelodyBuf++;
+                               if (*pStart >= '0' && *pStart <= '5') {
+                                       Melody[noteCount].duration = *pStart;
+                                       pStart++;
 
-                                       if (*pMelodyBuf == '.' || *pMelodyBuf == ':' || *pMelodyBuf == ';')
-                                               Melody[noteCount].duration_specifier = *pMelodyBuf;
+                                       if (*pStart == '.' || *pStart == ':' || *pStart == ';')
+                                               Melody[noteCount].duration_specifier = *pStart;
 
                                        else
-                                               pMelodyBuf--;
+                                               pStart--;
 
                                        noteCount++;
                                }
@@ -1149,27 +826,27 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
                if (Melody[count].rest >= '0' && Melody[count].rest <= '5') {
                        switch (Melody[count].rest) {
                        case '0':
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] += 192;
+                               midiData[52 + (6 * count - 1)] += 192;
                                restSpec[count] = 192;
                                break;
                        case '1':
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] += 96;
+                               midiData[52 + (6 * count - 1)] += 96;
                                restSpec[count] = 96;
                                break;
                        case '2':
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] += 48;
+                               midiData[52 + (6 * count - 1)] += 48;
                                restSpec[count] = 48;
                                break;
                        case '3':
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] += 24;
+                               midiData[52 + (6 * count - 1)] += 24;
                                restSpec[count] = 24;
                                break;
                        case '4':
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] += 12;
+                               midiData[52 + (6 * count - 1)] += 12;
                                restSpec[count] = 12;
                                break;
                        case '5':
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] += 6;
+                               midiData[52 + (6 * count - 1)] += 6;
                                restSpec[count] = 6;
                                break;
                        default:
@@ -1179,31 +856,31 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
                        if (Melody[count].rest_specifier != '%') {
                                switch (Melody[count].rest_specifier) {
                                case '.':
-                                       midiData[52 + (6 * count * (repeat + 1) - 1)] += (restSpec[count] / 2);
+                                       midiData[52 + (6 * count - 1)] += (restSpec[count] / 2);
                                        break;
                                case ':':
-                                       midiData[52 + (6 * count * (repeat + 1) - 1)] += restSpec[count];
+                                       midiData[52 + (6 * count - 1)] += restSpec[count];
                                        break;
                                case ';':
-                                       midiData[52 + (6 * count * (repeat + 1) - 1)] -= (restSpec[count] / 3);
+                                       midiData[52 + (6 * count - 1)] -= (restSpec[count] / 3);
                                        break;
                                default:
                                        break;
                                }
                        }
 
-                       if (midiData[52 + (6 * count * (repeat + 1) - 1)] > MIDI_LIMIT)
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] = MIDI_LIMIT;
+                       if (midiData[52 + (6 * count - 1)] > MIDI_LIMIT)
+                               midiData[52 + (6 * count - 1)] = MIDI_LIMIT;
 
                        if (Melody[count].rest == '0')
-                               midiData[52 + (6 * count * (repeat + 1) - 1)] = MIDI_LIMIT;
+                               midiData[52 + (6 * count - 1)] = MIDI_LIMIT;
                }
 
                for (number = count; number < noteCount; number++)
                        __get_imelody_notetotal(number);
 
                for (number = count + 1; number < noteCount; number++) {
-                       noteTotal[6 * count + 1] = midiData[52 + (6 * count * (repeat + 1) - 5)];
+                       noteTotal[6 * count + 1] = midiData[52 + (6 * count - 5)];
 
                        if (Melody[count].vol == '+')
                                noteTotal[6 * count + 1] = noteTotal[6 * count + 1] + VOL_INTERVAL;
@@ -1240,201 +917,226 @@ __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen)
 
                numberCount = 6 * count;
 
-               for (number = 6 * count * (repeat + 1); number < 6 * (count * (repeat + 1) + (noteCount - count)); number++) {
+               for (number = 6 * count; number < 6 * (count + (noteCount - count)); number++) {
                        midiData[52 + number] = noteTotal[numberCount];
                        numberCount++;
                }
        }
 
-       noteTotal[6 * (count * (repeat + 1) + (noteCount - count))] = 0;                                /*0x00 */
-       noteTotal[6 * (count * (repeat + 1) + (noteCount - count)) + 1] = MIDI_MAX;             /*0xff */
-       noteTotal[6 * (count * (repeat + 1) + (noteCount - count)) + 2] = 47;                   /*0x2f */
-       noteTotal[6 * (count * (repeat + 1) + (noteCount - count)) + 3] = 0;                    /*0x00 */
+       noteTotal[6 * (count + (noteCount - count))] = 0;                               /*0x00 */
+       noteTotal[6 * (count + (noteCount - count)) + 1] = MIDI_MAX;            /*0xff */
+       noteTotal[6 * (count + (noteCount - count)) + 2] = 47;                  /*0x2f */
+       noteTotal[6 * (count + (noteCount - count)) + 3] = 0;                   /*0x00 */
 
-       for (number = 6 * (count * (repeat + 1) + (noteCount - count)); number <= 6 * (count * (repeat + 1) + (noteCount - count)) + 3; number++)
+       for (number = 6 * (count + (noteCount - count)); number <= 6 * (count + (noteCount - count)) + 3; number++)
                midiData[51 + number] = noteTotal[number];
 
-       trackSize = (6 * (count * (repeat + 1) + (noteCount - count)) + 56) - 22 - 1 ;
+       trackSize = (6 * (count + (noteCount - count)) + 56) - 22 - 1 ;
 
        midiData[20] = (trackSize & 0xff00) >> 8;
        midiData[21] = (trackSize & 0x00ff);
 
 
-       *pBufLen = 6 * (count * (repeat + 1) + (noteCount - count)) + 56 - 1;
+       *pBufLen = 6 * (count + (noteCount - count)) + 56 - 1;
 
        return g_memdup(midiData, *pBufLen);
 }
 
-static unsigned char
-__AvMIDISetVolume(char *pMelodyBuf)
+static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags)
 {
-       unsigned char midiVol;
+       unsigned char *imy = NULL;
+       int filesize = 0;
+       gchar **taglist = NULL;
+       guint len = 0, i;
 
-       pMelodyBuf = pMelodyBuf + 42;
+       if (!uriname || !tags) {
+               debug_error(DEBUG, "uriname or tags is NULL\n");
+               return MMFILE_FORMAT_FAIL;
+       }
 
-       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 */
-               pMelodyBuf++;
+       imy = __get_load_memory(uriname, &filesize);
+       if (filesize <= 0) {
+               mmfile_free(imy);
+               return MMFILE_FORMAT_FAIL;
+       }
 
-       if (*pMelodyBuf != 'V')
-               midiVol = AV_MIDI_VOL_MAX;
+       taglist = g_strsplit((char *)imy, "\n", -1);
+       len = g_strv_length(taglist);
+
+       for (i = 0; i < len; i++) {
+               if (g_str_has_prefix(taglist[i], IMY_KEY_NAME)) {
+                       mmfile_free(tags->title);
+                       tags->title = g_strdup(taglist[i] + strlen(IMY_KEY_NAME));
+               } else if (g_str_has_prefix(taglist[i], IMY_KEY_COMPOSER)) {
+                       mmfile_free(tags->composer);
+                       tags->composer = g_strdup(taglist[i] + strlen(IMY_KEY_COMPOSER));
+               } else if (g_str_has_prefix(taglist[i], IMY_KEY_COPYRIGHT)) {
+                       mmfile_free(tags->copyright);
+                       tags->copyright = g_strdup(taglist[i] + strlen(IMY_KEY_COPYRIGHT));
+               }
+       }
 
-       else {
-               pMelodyBuf = pMelodyBuf + 5;
+       return MMFILE_FORMAT_SUCCESS;
+}
 
-               if (*pMelodyBuf == 'E')
-                       pMelodyBuf = pMelodyBuf + 3;
 
-               else
-                       pMelodyBuf = pMelodyBuf - 4;
+/* interface functions */
+int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext);
+int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
+int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext);
+int mmfile_format_close_imy(MMFileFormatContext *formatContext);
 
-               if (*pMelodyBuf == '1') {
-                       pMelodyBuf++;
 
-                       switch (*pMelodyBuf) {
-                       case '0':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '1':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '2':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '3':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '4':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '5':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       default:
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       }
-               }
+int mmfile_format_open_imy(MMFileFormatContext *formatContext)
+{
+       mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
+       mm_file_retvm_if_fails(DEBUG, MMFileFormatIsValidIMY(NULL, formatContext->uriFileName, 0), MMFILE_FORMAT_FAIL);
 
-               else
-                       switch (*pMelodyBuf) {
-                       case '0':
-                               midiVol = 0;
-                               break;
-                       case '2':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '3':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '4':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '5':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '6':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '7':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '8':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       case '9':
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       default:
-                               midiVol = AV_MIDI_VOL_MAX;
-                               break;
-                       }
-       }
+       formatContext->ReadStream   = mmfile_format_read_stream_imy;
+       formatContext->ReadFrame    = mmfile_format_read_frame_imy;
+       formatContext->ReadTag      = mmfile_format_read_tag_imy;
+       formatContext->Close        = mmfile_format_close_imy;
 
-       return midiVol;
-}
+       formatContext->videoTotalTrackNum = 0;
+       formatContext->audioTotalTrackNum = 1;
 
-static int
-__AvMIDISetBeat(char *pMelodyBuf)
-{
-       int bpmValue[4] = {0};
-       int beatValue;
+       formatContext->privateFormatData = NULL;
 
-       pMelodyBuf = pMelodyBuf + 42;
+       return MMFILE_FORMAT_SUCCESS;
+}
 
-       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 */
-               pMelodyBuf++;
 
-       if (*pMelodyBuf != 'B')
-               bpmValue[3] = 120;
+int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext)
+{
+       MIDI_INFO_SIMPLE *info = NULL;
+       MMFileFormatStream  *audioStream = NULL;
 
-       else {
-               pMelodyBuf = pMelodyBuf + 4;
+       unsigned char   *imy = NULL;
+       int                             imy_size = 0;
+       unsigned char   *midi = NULL;
+       unsigned int    midi_size = 0;
+       char                    src2[MMFILE_URI_MAX_LEN];
 
-               if (*pMelodyBuf == ':') {
-                       pMelodyBuf++;
+       mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
 
-                       if (*pMelodyBuf >= '1' && *pMelodyBuf <= '9') {
-                               bpmValue[0] = *pMelodyBuf - '0';
-                               pMelodyBuf++;
+       /*convert iMelody to Midi*/
+       imy = __get_load_memory(formatContext->uriFileName, &imy_size);
+       if (!imy) {
+               debug_error(DEBUG, "failed to load memory.\n");
+               goto exception;
+       }
 
-                               if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9') {
-                                       bpmValue[1] = *pMelodyBuf - '0';
-                                       pMelodyBuf++;
+       if (!__is_good_imelody((char *)imy, imy_size)) {
+               debug_error(DEBUG, "it's broken file.\n");
+               goto exception;
+       }
+       midi = __AvConvertIMelody2MIDI((char *)imy, &midi_size);
+       if (!midi) {
+               debug_error(DEBUG, "failed to convert.");
+               goto exception;
+       }
 
-                                       if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9') {
-                                               bpmValue[2] = *pMelodyBuf - '0';
+       /*make uri*/
+       memset(src2, 0x00, MMFILE_URI_MAX_LEN);
+       snprintf(src2, sizeof(src2), "%s%u:%u", MMFILE_MEM_URI, (unsigned int)midi, midi_size);
 
-                                               bpmValue[0] = bpmValue[0] * 100;
-                                               bpmValue[1] = bpmValue[1] * 10;
-                                               pMelodyBuf++;
-                                       }
+       /*get infomation*/
+       info = mmfile_format_get_midi_infomation(src2);
 
-                                       else
-                                               bpmValue[0] = bpmValue[0] * 10;
-                               }
-                       }
+       formatContext->duration = info->duration;
+       formatContext->videoStreamId = -1;
+       formatContext->videoTotalTrackNum = 0;
+       formatContext->audioTotalTrackNum = info->track_num;
+       formatContext->nbStreams = 1;
 
-                       bpmValue[3] = bpmValue[0] + bpmValue[1] + bpmValue[2];
-               }
-       }
+       audioStream = g_new0(MMFileFormatStream, 1);
 
-       if (bpmValue[3] < 25 || bpmValue[3] > 900)
-               bpmValue[3] = 120;
+       audioStream->streamType = MMFILE_AUDIO_STREAM;
+       audioStream->codecId = MM_AUDIO_CODEC_IMELODY;
+       audioStream->bitRate = 0;
+       audioStream->framePerSec = 0;
+       audioStream->width = 0;
+       audioStream->height = 0;
+       audioStream->nbChannel = 1;
+       audioStream->samplePerSec = 0;
+       formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
 
-       if (*pMelodyBuf >= '0' && *pMelodyBuf <= '9')
-               bpmValue[3] = 120;
+#ifdef  __MMFILE_TEST_MODE__
+       mmfile_format_print_contents(formatContext);
+#endif
 
-       beatValue = 1000000 * 60 / bpmValue[3];
+       mmfile_free(imy);
+       mmfile_free(midi);
+       mmfile_format_free_midi_infomation(info);
+       return MMFILE_FORMAT_SUCCESS;
 
-       debug_msg(RELEASE, "beat: %d = 1000000 * 60 / %d\n", beatValue, bpmValue[3]);
+exception:
+       mmfile_free(imy);
+       mmfile_free(midi);
+       mmfile_format_free_midi_infomation(info);
+       mmfile_free(audioStream);
+       return MMFILE_FORMAT_FAIL;
+}
 
-       return beatValue;
+
+int mmfile_format_read_frame_imy(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
+{
+       return MMFILE_FORMAT_SUCCESS;
 }
 
-static char
-__AvMIDISetStyle(char *pMelodyBuf)
+int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext)
 {
-       char styleValue = '0';
+       tMMFileImelodyTagInfo taginfo = {0, };
+       unsigned int tag_len;
+       unsigned int cnv_len;
+       const char *locale = MMFileUtilGetLocale();
 
-       while (*pMelodyBuf != 'S')
-               pMelodyBuf--;
+       mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
 
-       pMelodyBuf++;
+       __get_imelody_tag(formatContext->uriFileName, &taginfo);
 
-       if (*pMelodyBuf >= '0' && *pMelodyBuf <= '2')
-               pMelodyBuf++;
+       /**
+        * UTF8 convert
+        */
+       if (taginfo.title) {
+               tag_len = strlen(taginfo.title);
+               cnv_len = 0;
+               formatContext->title = mmfile_string_convert(taginfo.title, tag_len, "UTF-8", locale, NULL, &cnv_len);
+
+               if (formatContext->title == NULL) {
+                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
+                       formatContext->title = g_strdup(taginfo.title);
+               }
+               mmfile_free(taginfo.title);
+       }
 
-       if (*pMelodyBuf != '.') {
-               pMelodyBuf--;
-               styleValue = *pMelodyBuf;
+       if (taginfo.composer) {
+               tag_len = strlen(taginfo.composer);
+               cnv_len = 0;
+               formatContext->composer = mmfile_string_convert(taginfo.composer, tag_len, "UTF-8", locale, NULL, &cnv_len);
+               if (formatContext->composer == NULL) {
+                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
+                       formatContext->composer = g_strdup(taginfo.composer);
+               }
+               mmfile_free(taginfo.composer);
        }
 
-       if (styleValue < '0' || styleValue > '2') {
-               debug_warning(DEBUG, "unknown style. use default(S0)\n");
-               styleValue = '0';
+       if (taginfo.copyright) {
+               tag_len = strlen(taginfo.copyright);
+               cnv_len = 0;
+               formatContext->copyright = mmfile_string_convert(taginfo.copyright, tag_len, "UTF-8", locale, NULL, &cnv_len);
+               if (formatContext->copyright == NULL) {
+                       debug_warning(DEBUG, "failed to UTF8 convert.\n");
+                       formatContext->copyright = g_strdup(taginfo.copyright);
+               }
+               mmfile_free(taginfo.copyright);
        }
 
-       debug_msg(RELEASE, "style: '%c'\n", styleValue);
+       return MMFILE_FORMAT_SUCCESS;
+}
 
-       return styleValue;
+int mmfile_format_close_imy(MMFileFormatContext *formatContext)
+{
+       return MMFILE_FORMAT_SUCCESS;
 }
+