From 4dafe21d4d100092275b87e27288651a1cab5fe8 Mon Sep 17 00:00:00 2001 From: "minje.ahn" Date: Tue, 26 Jul 2022 10:52:34 +0900 Subject: [PATCH] Improve imelody related code Modified to calculate the duration of imelody directly without converting it to midi format. Change-Id: Id656ebebbeb4191fbe676b35346efc44b1f055f8 Signed-off-by: minje.ahn --- formats/ffmpeg/mm_file_format_imelody.c | 917 ++++---------------------------- 1 file changed, 114 insertions(+), 803 deletions(-) diff --git a/formats/ffmpeg/mm_file_format_imelody.c b/formats/ffmpeg/mm_file_format_imelody.c index 3dab94e..5d854e9 100755 --- a/formats/ffmpeg/mm_file_format_imelody.c +++ b/formats/ffmpeg/mm_file_format_imelody.c @@ -19,66 +19,20 @@ * */ -#include -#include /*memcmp*/ -#include /*malloc*/ - #include "mm_file_debug.h" #include "mm_file_utils.h" #include "mm_file_format_private.h" #include "mm_file_format_imelody.h" -#include "mm_file_format_midi.h" /** * Define */ -#define AV_MIDI_COUNT_MAX 1600 -#define AV_MIDI_NOTE_MAX 256 -#define AV_MIDI_VOL_MAX 250 -#define MIDI_LIMIT 127 -#define MIDI_MAX 255 - -#define VOL_INTERVAL 12 - -#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, - 0x59, 0x02, 0x00, 0x00, 0x00, 0xff, 0x51, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xb0, - 0x07, 0x00, 0x00, 0x90 - }; - - -static unsigned char noteTotal[AV_MIDI_COUNT_MAX]; -static char octave[AV_MIDI_NOTE_MAX]; -static int durationSpec[AV_MIDI_NOTE_MAX]; -static int restSpec[AV_MIDI_NOTE_MAX]; - -static struct { - char flat_sharp; - char note; - char duration; - char duration_specifier; - char rest; - char rest_specifier; - char vol; -} Melody[AV_MIDI_NOTE_MAX]; - -static struct { - int note; - int duration_on; - int duration_off; -} noteData[AV_MIDI_NOTE_MAX]; - /*imelody key string (to validatation check)*/ static const char *g_imy_key_str[] = { "BEGIN:IMELODY", @@ -145,801 +99,179 @@ failed: return NULL; } -static unsigned char __AvMIDISetVolume(const char *pMelodyBuf) -{ - /* 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; - - if (found && *(found + strlen(IMY_KEY_VOLUME)) == '0') - vol = 0; - - return vol; -} - -static int __AvMIDISetBeat(const char *pMelodyBuf) +static int __bpm_to_tempo(const char *pMelodyBuf) { /* Format - BEAT:### (Optional) */ char *found = strstr(pMelodyBuf, IMY_KEY_BEAT); /* Default [120] */ - char *beatValue = NULL; + char *bpm_str = NULL; int bpm = 120; - int beat = 0; if (found) { - beatValue = g_strndup(found + strlen(IMY_KEY_BEAT), 3); + bpm_str = g_strndup(found + strlen(IMY_KEY_BEAT), 3); /* No need to check integer bound */ - bpm = atoi(beatValue); - g_free(beatValue); + bpm = atoi(bpm_str); + g_free(bpm_str); if (bpm < 25 || bpm > 900) bpm = 120; } - beat = 1000000 * 60 / bpm; - debug_msg(RELEASE, "beat: %d\n", beat); - - return beat; + return 60 * 1000 / bpm; } -static char __AvMIDISetStyle(const char *pMelodyBuf) +static char * __remove_effect(const char *full_melody) { - /* 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; -} + gsize i = 0; + GString *result = NULL; -static void __init_imelody_data(void) -{ - int idx = 0; - - for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) { - restSpec[idx] = 0; - durationSpec[idx] = 0; - } - - for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) - octave[idx] = '%'; - - for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) { - Melody[idx].flat_sharp = '%'; - Melody[idx].note = '%'; - Melody[idx].duration = '%'; - Melody[idx].duration_specifier = '%'; - Melody[idx].rest = '%'; - Melody[idx].rest_specifier = '%'; - Melody[idx].vol = '%'; - } - - for (idx = 0; idx < AV_MIDI_NOTE_MAX; idx++) { - noteData[idx].note = 0; - noteData[idx].duration_on = 0; - noteData[idx].duration_off = 0; - } - - memset(midiData, 0, sizeof(midiData)); - memcpy(midiData, midiHeader, MIDI_HEADER_LENGTH); -} + if (!full_melody) + return NULL; -static void __get_imelody_duration(char style, int number) -{ - if (style == '0') { - switch (Melody[number].duration) { - case '0': - noteData[number].duration_on = 183; - noteData[number].duration_off = 9; - break; - case '1': - noteData[number].duration_on = 91; - noteData[number].duration_off = 5; - break; - case '2': - noteData[number].duration_on = 46; - noteData[number].duration_off = 2; - break; - case '3': - noteData[number].duration_on = 23; - noteData[number].duration_off = 1; - break; - case '4': - noteData[number].duration_on = 11; - noteData[number].duration_off = 1; - break; - case '5': - noteData[number].duration_on = 5; - noteData[number].duration_off = 1; - break; - default: - break; - } - } else if (style == '1') { - switch (Melody[number].duration) { - case '0': - noteData[number].duration_on = 192; - noteData[number].duration_off = 0; - break; - case '1': - noteData[number].duration_on = 96; - noteData[number].duration_off = 0; - break; - case '2': - noteData[number].duration_on = 48; - noteData[number].duration_off = 0; - break; - case '3': - noteData[number].duration_on = 24; - noteData[number].duration_off = 0; - break; - case '4': - noteData[number].duration_on = 12; - noteData[number].duration_off = 0; - break; - case '5': - noteData[number].duration_on = 6; - noteData[number].duration_off = 0; - break; - default: - break; - } - } else { - switch (Melody[number].duration) { - case '0': - noteData[number].duration_on = 96; - noteData[number].duration_off = 96; - break; - case '1': - noteData[number].duration_on = 48; - noteData[number].duration_off = 48; - break; - case '2': - noteData[number].duration_on = 24; - noteData[number].duration_off = 24; - break; - case '3': - noteData[number].duration_on = 12; - noteData[number].duration_off = 12; - break; - case '4': - noteData[number].duration_on = 6; - noteData[number].duration_off = 6; - break; - case '5': - noteData[number].duration_on = 3; - noteData[number].duration_off = 3; - break; - default: - break; + result = g_string_new(full_melody); + + /*Removed unnecessary values for duration calculations.*/ + g_string_replace(result, "ledon", "", 0); + g_string_replace(result, "ledoff", "", 0); + g_string_replace(result, "vibeon", "", 0); + g_string_replace(result, "vibeoff", "", 0); + g_string_replace(result, "backon", "", 0); + g_string_replace(result, "backoff", "", 0); + g_string_replace(result, "#", "", 0); + g_string_replace(result, "&", "", 0); + g_string_replace(result, "(", "", 0); + g_string_replace(result, ")", "", 0); + + while (i < result->len) { + if (result->str[i] == 'S' || result->str[i] == 'V' || result->str[i] == '@' || result->str[i] == '*') { + if ((i + 2 < result->len) && (g_ascii_digit_value(result->str[i + 2]) != -1)) + result = g_string_erase(result, i, 3); + else + result = g_string_erase(result, i, 2); + } else { + i++; } } + debug_msg(RELEASE, "melody : [%s] \n", result->str); - switch (Melody[number].duration) { - case '0': - durationSpec[number] = 192; - break; - case '1': - durationSpec[number] = 96; - break; - case '2': - durationSpec[number] = 48; - break; - case '3': - durationSpec[number] = 24; - break; - case '4': - durationSpec[number] = 12; - break; - case '5': - durationSpec[number] = 6; - break; - default: - break; - } - - if (Melody[number].duration_specifier != '%') { - switch (Melody[number].duration_specifier) { - case '.': - noteData[number].duration_on += (durationSpec[number] / 2); - break; - case ':': - noteData[number].duration_on += durationSpec[number]; - break; - case ';': - noteData[number].duration_on -= (durationSpec[number] / 3); - break; - default: - break; - } - - if (noteData[number].duration_on > MIDI_MAX) - noteData[number].duration_on = MIDI_LIMIT; - } + return g_string_free(result, FALSE); } -static void __get_imelody_melody(int number, int octaveValue) +static gchar * __get_melody(const char *buf) { - if (Melody[number].flat_sharp == '#') { - switch (Melody[number].note) { - case 'c': - noteData[number].note = octaveValue + 1; - break; - case 'd': - noteData[number].note = octaveValue + 3; - break; - case 'f': - noteData[number].note = octaveValue + 6; - break; - case 'g': - noteData[number].note = octaveValue + 8; - break; - case 'a': - noteData[number].note = octaveValue + 10; - break; - default: - break; - } - } else if (Melody[number].flat_sharp == '&') { - switch (Melody[number].note) { - case 'd': - noteData[number].note = octaveValue + 1; - break; - case 'e': - noteData[number].note = octaveValue + 3; - break; - case 'g': - noteData[number].note = octaveValue + 6; - break; - case 'a': - noteData[number].note = octaveValue + 8; - break; - case 'b': - noteData[number].note = octaveValue + 10; - break; - default: - break; - } - } else { - switch (Melody[number].note) { - case 'c': - noteData[number].note = octaveValue; - break; - case 'd': - noteData[number].note = octaveValue + 2; - break; - case 'e': - noteData[number].note = octaveValue + 4; - break; - case 'f': - noteData[number].note = octaveValue + 5; - break; - case 'g': - noteData[number].note = octaveValue + 7; - break; - case 'a': - noteData[number].note = octaveValue + 9; - break; - case 'b': - noteData[number].note = octaveValue + 11; - break; - default: - break; - } - } -} + gchar **tmp = NULL; + gchar *melody = NULL; + char *result = NULL; -static void __get_imelody_reset(int number) -{ - if (Melody[number].rest >= '0' && Melody[number].rest <= '5') { - switch (Melody[number].rest) { - case '0': - noteData[number - 1].duration_off += 192; - restSpec[number] = 192; - break; - case '1': - noteData[number - 1].duration_off += 96; - restSpec[number] = 96; - break; - case '2': - noteData[number - 1].duration_off += 48; - restSpec[number] = 48; - break; - case '3': - noteData[number - 1].duration_off += 24; - restSpec[number] = 24; - break; - case '4': - noteData[number - 1].duration_off += 12; - restSpec[number] = 12; - break; - case '5': - noteData[number - 1].duration_off += 6; - restSpec[number] = 6; - break; - default: - break; - } + if (!buf) + return NULL; - if (noteData[number - 1].duration_off > MIDI_MAX && Melody[number].rest_specifier == '%') - noteData[number - 1].duration_off = MIDI_LIMIT; - } + tmp = g_strsplit(buf, IMY_KEY_MELODY, -1); + if (g_strv_length(tmp) == 2) + melody = g_strdup(tmp[1]); - if (Melody[number].rest_specifier != '%') { - switch (Melody[number].rest_specifier) { - case '.': - noteData[number - 1].duration_off += (restSpec[number] / 2); - break; - case ':': - noteData[number - 1].duration_off += restSpec[number]; - break; - case ';': - noteData[number - 1].duration_off -= (restSpec[number] / 3); - break; - default: - break; - } + g_strfreev(tmp); + tmp = NULL; - if (noteData[number - 1].duration_off > MIDI_MAX) - noteData[number - 1].duration_off = MIDI_LIMIT; + if (melody) { + tmp = g_strsplit(melody, "\n", -1); + g_free(melody); + melody = NULL; } -} - -static void __get_imelody_notetotal(int number) -{ - char noteBase[6]; - - memset(noteBase, 0, sizeof(noteBase)); - - noteBase[0] = noteData[number].note; - noteBase[2] = noteData[number].duration_on; - noteBase[3] = noteData[number].note; - noteBase[5] = noteData[number].duration_off; - noteTotal[6 * number] = noteBase[0]; - noteTotal[6 * number + 2] = noteBase[2]; - noteTotal[6 * number + 3] = noteBase[3]; - noteTotal[6 * number + 5] = noteBase[5]; - noteTotal[6 * number + 4] = 0; + if (tmp) { + melody = g_strdup(tmp[0]); + g_strfreev(tmp); + } - if (noteTotal[6 * number + 2] > MIDI_LIMIT) - noteTotal[6 * number + 2] = MIDI_LIMIT; + result = __remove_effect(melody); + g_free(melody); - if (noteTotal[6 * number + 5] > MIDI_LIMIT) - noteTotal[6 * number + 5] = MIDI_LIMIT; + return result; } -static unsigned char * __AvConvertIMelody2MIDI(char *pMelodyBuf, unsigned int *pBufLen) +static int __calculate_duration(const char *melody, int tempo) { - /* Duration measures the length of one play. So no need extract REPEAT keyword */ - char *pStart = pMelodyBuf; - char *pMelodyStart; - int octaveCount; - int octaveValue; - int count; - int noteCount = 0; - int number; - int numberCount; - char style = '0'; - int tempoData[3]; - int tempoValue; - int trackSize; - int repeatCount = 0; - - __init_imelody_data(); - - midiData[49] = __AvMIDISetVolume(pStart); - tempoValue = __AvMIDISetBeat(pStart); - style = __AvMIDISetStyle(pStart); - - for (number = 0; tempoValue != 0; number++) { - tempoData[0] = tempoValue % 16; - tempoValue = tempoValue / 16; - - tempoData[1] = tempoValue % 16; - tempoValue = tempoValue / 16; - - tempoData[2] = tempoData[0] + tempoData[1] * 16; - - midiData[42 - number] = tempoData[2]; - } - - /* Find MELODY */ - pStart = strstr(pMelodyBuf, IMY_KEY_MELODY) + strlen(IMY_KEY_MELODY); - - /*Melody start point */ - pMelodyStart = pStart; - - /**@note if newline detected, stop reading - * why? mobileBAE player stopped at newline. - * 2009/08/12 - */ - 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; - } + int len = 0; + int i = 1; + float sum = 0.0; + float duration = 0.0; + bool is_specifier = false; - pStart++; + if (!melody || tempo == 0) + return 0; - if (*pStart == '*') { - pStart++; - - if (*pStart >= '0' && *pStart <= '8') - octave[noteCount] = *pStart; - } - - if (*pStart == '#' || *pStart == '&') - Melody[noteCount].flat_sharp = *pStart; - - if (*pStart == 'r') { - pStart++; - - if (*pStart >= '0' && *pStart <= '5') { - Melody[noteCount].rest = *pStart; - pStart++; - - if (*pStart == '.' || *pStart == ':' || *pStart == ';') - Melody[noteCount].rest_specifier = *pStart; - } - } + len = strlen(melody); - if (*pStart == 'V') { - pStart++; - - if (*pStart == '+' || *pStart == '-') - Melody[noteCount].vol = *pStart; - } - - if (*pStart >= 'a' && *pStart <= 'g') { - Melody[noteCount].note = *pStart; - pStart++; - - if (*pStart >= '0' && *pStart <= '5') { - Melody[noteCount].duration = *pStart; - pStart++; - - if (*pStart == '.' || *pStart == ':' || *pStart == ';') - Melody[noteCount].duration_specifier = *pStart; - else - pStart--; - - noteCount++; - } - } - } - - for (octaveCount = 1; octaveCount < noteCount; octaveCount++) { - if (octave[octaveCount] == '%') - octave[octaveCount] = octave[octaveCount - 1]; - } - - for (number = 0; number < noteCount; number++) { - if (octave[0] == '%' && octave[number] == '%') - octaveValue = 4; - - else - octaveValue = octave[number] - '0'; - - octaveValue = octaveValue * 12; - - __get_imelody_melody(number, octaveValue); - } - - pStart = pMelodyStart; - - for (number = 0; number < noteCount; number++) - __get_imelody_duration(style, number); - - for (number = 1; number < noteCount; number++) - __get_imelody_reset(number); - - if (Melody[0].rest >= '0' && Melody[0].rest <= '5') { - switch (Melody[0].rest) { + while (i < len) { + switch(melody[i]) { case '0': - midiData[50] += 192; - restSpec[0] = 192; + duration = 4; break; case '1': - midiData[50] += 96; - restSpec[0] = 96; + duration = 2; break; case '2': - midiData[50] += 48; - restSpec[0] = 48; + duration = 1; break; case '3': - midiData[50] += 24; - restSpec[0] = 24; + duration = 0.5; break; case '4': - midiData[50] += 12; - restSpec[0] = 12; + duration = 0.25; break; case '5': - midiData[50] += 6; - restSpec[0] = 6; + duration = 0.125; break; default: + duration = 0; break; } - if (Melody[0].rest_specifier != '%') { - switch (Melody[0].rest_specifier) { - case '.': - midiData[50] += (restSpec[0] / 2); - break; - case ':': - midiData[50] += restSpec[0]; - break; - case ';': - midiData[50] -= (restSpec[0] / 3); - break; - default: - break; - } - } - - if (midiData[50] > MIDI_LIMIT) - midiData[50] = MIDI_LIMIT; - - if (Melody[0].rest == '0') - midiData[50] = MIDI_LIMIT; - } - - for (number = 0; number < noteCount; number++) - __get_imelody_notetotal(number); - - for (number = 1; number < noteCount; number++) { - noteTotal[1] = 84; - - if (Melody[0].vol == '+') - noteTotal[1] = 84 + VOL_INTERVAL; - - if (Melody[0].vol == '-') - noteTotal[1] = 84 - VOL_INTERVAL; - - switch (Melody[number].vol) { - case '+': - noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] + VOL_INTERVAL; - break; - case '-': - noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] - VOL_INTERVAL; - break; - default: - break; + if (i + 1 >= len) + goto FINALIZE; + + if (melody[i + 1] == '.') { + is_specifier = true; + sum += duration; + duration *= 0.5; + } else if (melody[i + 1] == ':') { + is_specifier = true; + sum += duration; + duration *= 0.5; + sum += duration; + duration *= 0.5; + } else if (melody[i + 1] == ';') { + is_specifier = true; + duration *= 2.0 / 3.0; } - if (noteTotal[6 * number + 1] > MIDI_LIMIT) - noteTotal[6 * number + 1] = MIDI_LIMIT; - - if ((noteTotal[6 * (number - 1) + 1] == 0 || noteTotal[6 * (number - 1) + 1] == 7) && Melody[number].vol == '-') - noteTotal[6 * number + 1] = 0; - - if (Melody[number].vol == '%') - noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1]; - } - - for (number = 0; number < 6 * noteCount; number++) - midiData[52 + number] = noteTotal[number]; - - for (number = 6 * noteCount; number < 6 * noteCount; number++) { - noteTotal[number] = noteTotal[repeatCount]; - midiData[52 + number] = noteTotal[number]; - repeatCount++; - - if (repeatCount == 6 * noteCount) - repeatCount = 0; +FINALIZE: + sum += duration; + i += (is_specifier) ? 3 : 2; + is_specifier = false; } - for (number = 1; number < 6 * noteCount; number = number + 6) { - if (midiData[52 + number] > MIDI_LIMIT) - midiData[52 + number] = MIDI_LIMIT; - } - - pStart = pMelodyStart; - count = noteCount; - - if (*pStart != 'E' && *pStart != ':') { - pStart--; - - while (*pStart != 'E') { - if (noteCount >= AV_MIDI_NOTE_MAX) { - debug_warning(DEBUG, "__AvConvertIMelody2MIDI : noteCount>=AV_MIDI_NOTE_MAX\n"); - break; - } - - pStart++; - - if (*pStart == '*') { - pStart++; - - if (*pStart >= '0' && *pStart <= '8') - octave[noteCount] = *pStart; - } - - if (*pStart == '#' || *pStart == '&') - Melody[noteCount].flat_sharp = *pStart; - - if (*pStart == 'r') { - pStart++; - - if (*pStart >= '0' && *pStart <= '5') { - Melody[noteCount].rest = *pStart; - pStart++; - - if (*pStart == '.' || *pStart == ':' || *pStart == ';') - Melody[noteCount].rest_specifier = *pStart; - } - } - - if (*pStart == 'V') { - pStart++; - - if (*pStart == '+' || *pStart == '-') - Melody[noteCount].vol = *pStart; - } - - if (*pStart >= 'a' && *pStart <= 'g') { - Melody[noteCount].note = *pStart; - pStart++; - - if (*pStart >= '0' && *pStart <= '5') { - Melody[noteCount].duration = *pStart; - pStart++; - - if (*pStart == '.' || *pStart == ':' || *pStart == ';') - Melody[noteCount].duration_specifier = *pStart; - - else - pStart--; - - noteCount++; - } - } - } - - for (octaveCount = count; octaveCount < noteCount && octaveCount < AV_MIDI_NOTE_MAX; octaveCount++) { - if (octave[octaveCount] == '%') - octave[octaveCount] = octave[octaveCount - 1]; - } - - for (number = count; number < noteCount && number < AV_MIDI_NOTE_MAX; number++) { - octaveValue = octave[number] - '0'; - - octaveValue = octaveValue * 12; - - __get_imelody_melody(number, octaveValue); - __get_imelody_duration(style, number); - } - - for (number = count + 1; number < noteCount && number < AV_MIDI_NOTE_MAX; number++) - __get_imelody_reset(number); - - if (Melody[count].rest >= '0' && Melody[count].rest <= '5') { - switch (Melody[count].rest) { - case '0': - midiData[52 + (6 * count - 1)] += 192; - restSpec[count] = 192; - break; - case '1': - midiData[52 + (6 * count - 1)] += 96; - restSpec[count] = 96; - break; - case '2': - midiData[52 + (6 * count - 1)] += 48; - restSpec[count] = 48; - break; - case '3': - midiData[52 + (6 * count - 1)] += 24; - restSpec[count] = 24; - break; - case '4': - midiData[52 + (6 * count - 1)] += 12; - restSpec[count] = 12; - break; - case '5': - midiData[52 + (6 * count - 1)] += 6; - restSpec[count] = 6; - break; - default: - break; - } - - if (Melody[count].rest_specifier != '%') { - switch (Melody[count].rest_specifier) { - case '.': - midiData[52 + (6 * count - 1)] += (restSpec[count] / 2); - break; - case ':': - midiData[52 + (6 * count - 1)] += restSpec[count]; - break; - case ';': - midiData[52 + (6 * count - 1)] -= (restSpec[count] / 3); - break; - default: - break; - } - } - - if (midiData[52 + (6 * count - 1)] > MIDI_LIMIT) - midiData[52 + (6 * count - 1)] = MIDI_LIMIT; - - if (Melody[count].rest == '0') - 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 - 5)]; - - if (Melody[count].vol == '+') - noteTotal[6 * count + 1] = noteTotal[6 * count + 1] + VOL_INTERVAL; - - if (Melody[count].vol == '-' && (noteTotal[6 * count + 1] == 0 || noteTotal[6 * count + 1] == 7)) - noteTotal[6 * count + 1] = 0; - - if (Melody[count].vol == '-' && noteTotal[6 * count + 1] >= 12) - noteTotal[6 * count + 1] = noteTotal[6 * count + 1] - VOL_INTERVAL; - - if (noteTotal[6 * count + 1] > MIDI_LIMIT) - noteTotal[6 * count + 1] = MIDI_LIMIT; - - switch (Melody[number].vol) { - case '+': - noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] + VOL_INTERVAL; - break; - case '-': - noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1] - VOL_INTERVAL; - break; - default: - break; - } - - if (noteTotal[6 * number + 1] > MIDI_LIMIT) - noteTotal[6 * number + 1] = MIDI_LIMIT; - - if ((noteTotal[6 * (number - 1) + 1] == 0 || noteTotal[6 * (number - 1) + 1] == 7) && Melody[number].vol == '-') - noteTotal[6 * number + 1] = 0; + return (int)(sum * tempo); +} - if (Melody[number].vol == '%') - noteTotal[6 * number + 1] = noteTotal[6 * (number - 1) + 1]; - } +static int __AvGetDuration(const char *pMelodyBuf) +{ + char *melody_part = NULL; + int tempo = 0; + int result = 0; - numberCount = 6 * count; + if (!pMelodyBuf) + return 0; - for (number = 6 * count; number < 6 * (count + (noteCount - count)); number++) { - midiData[52 + number] = noteTotal[numberCount]; - numberCount++; - } + tempo = __bpm_to_tempo(pMelodyBuf); + debug_msg(RELEASE, "tempo : %d ms\n", tempo); + melody_part = __get_melody(pMelodyBuf); + if (melody_part) { + result = __calculate_duration(melody_part, tempo); + g_free(melody_part); } - 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 + (noteCount - count)); number <= 6 * (count + (noteCount - count)) + 3; number++) - midiData[51 + number] = noteTotal[number]; - - trackSize = (6 * (count + (noteCount - count)) + 56) - 22 - 1 ; - - midiData[20] = (trackSize & 0xff00) >> 8; - midiData[21] = (trackSize & 0x00ff); - - - *pBufLen = 6 * (count + (noteCount - count)) + 56 - 1; - - return g_memdup2(midiData, *pBufLen); + return result; } static int __get_imelody_tag(const char *uriname, tMMFileImelodyTagInfo *tags) @@ -1010,14 +342,10 @@ int mmfile_format_open_imy(MMFileFormatContext *formatContext) 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]; mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL); @@ -1032,23 +360,11 @@ int mmfile_format_read_stream_imy(MMFileFormatContext *formatContext) 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->duration = __AvGetDuration((const char *)imy); formatContext->videoStreamId = -1; formatContext->videoTotalTrackNum = 0; - formatContext->audioTotalTrackNum = info->track_num; + formatContext->audioTotalTrackNum = 1; formatContext->nbStreams = 1; audioStream = g_new0(MMFileFormatStream, 1); @@ -1068,14 +384,10 @@ int mmfile_format_read_stream_imy(MMFileFormatContext *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; } @@ -1132,5 +444,4 @@ int mmfile_format_read_tag_imy(MMFileFormatContext *formatContext) int mmfile_format_close_imy(MMFileFormatContext *formatContext) { return MMFILE_FORMAT_SUCCESS; -} - +} \ No newline at end of file -- 2.7.4