#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,
"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);
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;
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) {
default:
break;
}
- }
-
- else if (style == '1') {
+ } else if (style == '1') {
switch (Melody[number].duration) {
case '0':
noteData[number].duration_on = 192;
default:
break;
}
- }
-
- else {
+ } else {
switch (Melody[number].duration) {
case '0':
noteData[number].duration_on = 96;
}
}
-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) {
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;
default:
break;
}
- }
-
- else {
+ } else {
switch (Melody[number].note) {
case 'c':
noteData[number].note = 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) {
}
}
-static void
-__get_imelody_notetotal(int number)
+static void __get_imelody_notetotal(int number)
{
char noteBase[6];
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;
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;
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++;
}
__get_imelody_melody(number, octaveValue);
}
- pMelodyBuf = pMelodyStart;
-
- style = __AvMIDISetStyle(pMelodyBuf);
+ pStart = pMelodyStart;
for (number = 0; number < noteCount; number++)
__get_imelody_duration(style, number);
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++;
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++;
}
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:
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;
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;
}
+