*
*/
-#include <stdio.h>
-#include <string.h> /*memcmp*/
-#include <stdlib.h> /*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",
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)
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);
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);
#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_close_imy(MMFileFormatContext *formatContext)
{
return MMFILE_FORMAT_SUCCESS;
-}
-
+}
\ No newline at end of file