summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common
Side-by-side diff
Diffstat (limited to 'gammu/emb/common') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/common.pro2
-rw-r--r--gammu/emb/common/commonE.pro1
-rw-r--r--gammu/emb/common/service/gsmring.c3
3 files changed, 4 insertions, 2 deletions
diff --git a/gammu/emb/common/common.pro b/gammu/emb/common/common.pro
index d27dbeb..9342cb7 100644
--- a/gammu/emb/common/common.pro
+++ b/gammu/emb/common/common.pro
@@ -1,186 +1,186 @@
######################################################################
# Automatically generated by qmake (1.07a) Fri Jul 30 22:13:34 2004
######################################################################
TEMPLATE = lib
DEPENDPATH += device \
misc \
phone \
protocol \
service \
device/bluetoth \
device/irda \
device/serial \
misc/coding \
phone/alcatel \
phone/at \
phone/nokia \
phone/obex \
phone/symbian \
protocol/alcatel \
protocol/at \
protocol/nokia \
protocol/obex \
protocol/symbian \
service/backup \
service/sms \
phone/nokia/dct3 \
phone/nokia/dct4
INCLUDEPATH += . \
misc/coding \
misc \
device \
phone/nokia/dct4 \
phone/nokia/dct3 \
phone/at \
phone/alcatel \
phone/obex \
phone/symbian \
protocol \
protocol/nokia \
protocol/at \
protocol/alcatel \
protocol/obex \
protocol/symbian \
device/serial \
device/irda \
device/bluetoth \
service \
service/sms \
service/backup \
phone/nokia \
phone
# Input
HEADERS += config.h \
gammu.h \
gsmcomon.h \
gsmstate.h \
device/devfunc.h \
misc/cfg.h \
misc/misc.h \
phone/pfunc.h \
protocol/protocol.h \
service/gsmcal.h \
service/gsmcall.h \
service/gsmdata.h \
service/gsmlogo.h \
service/gsmmisc.h \
service/gsmnet.h \
service/gsmpbk.h \
service/gsmprof.h \
service/gsmring.h \
device/bluetoth/affix.h \
device/bluetoth/blue_w32.h \
device/bluetoth/bluetoth.h \
device/bluetoth/bluez.h \
device/irda/irda.h \
device/irda/irda_unx.h \
device/irda/irda_w32.h \
device/serial/ser_djg.h \
device/serial/ser_unx.h \
device/serial/ser_w32.h \
misc/coding/coding.h \
misc/coding/md5.h \
phone/alcatel/alcatel.h \
phone/at/atgen.h \
phone/nokia/ncommon.h \
phone/nokia/nfunc.h \
phone/nokia/nfuncold.h \
phone/obex/obexgen.h \
phone/symbian/mroutgen.h \
protocol/alcatel/alcabus.h \
protocol/at/at.h \
protocol/nokia/fbus2.h \
protocol/nokia/mbus2.h \
protocol/nokia/phonet.h \
protocol/obex/obex.h \
protocol/symbian/mrouter.h \
service/backup/backgen.h \
service/backup/backics.h \
service/backup/backldif.h \
service/backup/backlmb.h \
service/backup/backtext.h \
service/backup/backvcf.h \
service/backup/backvcs.h \
service/backup/gsmback.h \
service/sms/gsmems.h \
service/sms/gsmmulti.h \
service/sms/gsmsms.h \
phone/nokia/dct3/dct3comm.h \
phone/nokia/dct3/dct3func.h \
phone/nokia/dct3/n6110.h \
phone/nokia/dct3/n7110.h \
phone/nokia/dct3/n9210.h \
phone/nokia/dct4/dct4func.h \
phone/nokia/dct4/n3320.h \
phone/nokia/dct4/n3650.h \
phone/nokia/dct4/n6510.h
SOURCES +=gsmcomon.c \
gsmstate.c \
misc/misc.c \
misc/cfg.c \
misc/coding/coding.c \
misc/coding/md5.c \
service/sms/gsmsms.c \
service/sms/gsmems.c \
service/sms/gsmmulti.c \
service/gsmcal.c \
service/gsmdata.c \
service/gsmpbk.c \
service/gsmring.c \
service/gsmlogo.c \
service/gsmmisc.c \
service/gsmnet.c \
service/backup/gsmback.c \
service/backup/backldif.c \
service/backup/backlmb.c \
service/backup/backtext.c \
service/backup/backvcs.c \
service/backup/backvcf.c \
service/backup/backics.c \
device/bluetoth/affix.c \
device/bluetoth/bluez.c \
device/bluetoth/blue_w32.c \
device/bluetoth/bluetoth.c \
device/serial/ser_djg.c \
device/irda/irda.c \
device/devfunc.c \
protocol/at/at.c \
protocol/alcatel/alcabus.c \
protocol/nokia/mbus2.c \
protocol/nokia/fbus2.c \
protocol/nokia/phonet.c \
protocol/obex/obex.c \
protocol/symbian/mrouter.c \
phone/pfunc.c \
phone/at/atgen.c \
phone/at/siemens.c \
phone/at/sonyeric.c \
phone/alcatel/alcatel.c \
phone/nokia/dct3/n6110.c \
phone/nokia/dct3/n7110.c \
phone/nokia/dct3/n9210.c \
phone/nokia/dct3/dct3func.c \
phone/nokia/dct4/n3320.c \
phone/nokia/dct4/n3650.c \
phone/nokia/dct4/n6510.c \
phone/nokia/dct4/dct4func.c \
phone/nokia/nauto.c \
phone/nokia/nfunc.c \
phone/nokia/nfuncold.c \
phone/obex/obexgen.c \
phone/symbian/mroutgen.c
TARGET = microgammu
-CONFIG += console
+CONFIG = warn_off release console
DESTDIR = ../../../bin
OBJECTS_DIR = obj/unix
MOC_DIR = moc/unix
unix: {
SOURCES += device/serial/ser_unx.c
}
win32:{
SOURCES += device/serial/ser_w32.c
}
diff --git a/gammu/emb/common/commonE.pro b/gammu/emb/common/commonE.pro
index 49fecc6..33c0224 100644
--- a/gammu/emb/common/commonE.pro
+++ b/gammu/emb/common/commonE.pro
@@ -1,179 +1,180 @@
######################################################################
# Automatically generated by qmake (1.07a) Fri Jul 30 22:13:34 2004
######################################################################
TEMPLATE = lib
DEPENDPATH += device \
misc \
phone \
protocol \
service \
device/bluetoth \
device/irda \
device/serial \
misc/coding \
phone/alcatel \
phone/at \
phone/nokia \
phone/obex \
phone/symbian \
protocol/alcatel \
protocol/at \
protocol/nokia \
protocol/obex \
protocol/symbian \
service/backup \
service/sms \
phone/nokia/dct3 \
phone/nokia/dct4
INCLUDEPATH += . \
misc/coding \
misc \
device \
phone/nokia/dct4 \
phone/nokia/dct3 \
phone/at \
phone/alcatel \
phone/obex \
phone/symbian \
protocol \
protocol/nokia \
protocol/at \
protocol/alcatel \
protocol/obex \
protocol/symbian \
device/serial \
device/irda \
device/bluetoth \
service \
service/sms \
service/backup \
phone/nokia \
phone
# Input
HEADERS += config.h \
gammu.h \
gsmcomon.h \
gsmstate.h \
device/devfunc.h \
misc/cfg.h \
misc/misc.h \
phone/pfunc.h \
protocol/protocol.h \
service/gsmcal.h \
service/gsmcall.h \
service/gsmdata.h \
service/gsmlogo.h \
service/gsmmisc.h \
service/gsmnet.h \
service/gsmpbk.h \
service/gsmprof.h \
service/gsmring.h \
device/bluetoth/affix.h \
device/bluetoth/blue_w32.h \
device/bluetoth/bluetoth.h \
device/bluetoth/bluez.h \
device/irda/irda.h \
device/irda/irda_unx.h \
device/irda/irda_w32.h \
device/serial/ser_djg.h \
device/serial/ser_unx.h \
device/serial/ser_w32.h \
misc/coding/coding.h \
misc/coding/md5.h \
phone/alcatel/alcatel.h \
phone/at/atgen.h \
phone/nokia/ncommon.h \
phone/nokia/nfunc.h \
phone/nokia/nfuncold.h \
phone/obex/obexgen.h \
phone/symbian/mroutgen.h \
protocol/alcatel/alcabus.h \
protocol/at/at.h \
protocol/nokia/fbus2.h \
protocol/nokia/mbus2.h \
protocol/nokia/phonet.h \
protocol/obex/obex.h \
protocol/symbian/mrouter.h \
service/backup/backgen.h \
service/backup/backics.h \
service/backup/backldif.h \
service/backup/backlmb.h \
service/backup/backtext.h \
service/backup/backvcf.h \
service/backup/backvcs.h \
service/backup/gsmback.h \
service/sms/gsmems.h \
service/sms/gsmmulti.h \
service/sms/gsmsms.h \
phone/nokia/dct3/dct3comm.h \
phone/nokia/dct3/dct3func.h \
phone/nokia/dct3/n6110.h \
phone/nokia/dct3/n7110.h \
phone/nokia/dct3/n9210.h \
phone/nokia/dct4/dct4func.h \
phone/nokia/dct4/n3320.h \
phone/nokia/dct4/n3650.h \
phone/nokia/dct4/n6510.h
SOURCES +=gsmcomon.c \
gsmstate.c \
misc/misc.c \
misc/cfg.c \
misc/coding/coding.c \
misc/coding/md5.c \
service/sms/gsmsms.c \
service/sms/gsmems.c \
service/sms/gsmmulti.c \
service/gsmcal.c \
service/gsmdata.c \
service/gsmpbk.c \
service/gsmring.c \
service/gsmlogo.c \
service/gsmmisc.c \
service/gsmnet.c \
service/backup/gsmback.c \
service/backup/backldif.c \
service/backup/backlmb.c \
service/backup/backtext.c \
service/backup/backvcs.c \
service/backup/backvcf.c \
service/backup/backics.c \
device/bluetoth/affix.c \
device/bluetoth/bluez.c \
device/bluetoth/blue_w32.c \
device/bluetoth/bluetoth.c \
device/serial/ser_unx.c \
device/serial/ser_djg.c \
device/irda/irda.c \
device/devfunc.c \
protocol/at/at.c \
protocol/alcatel/alcabus.c \
protocol/nokia/mbus2.c \
protocol/nokia/fbus2.c \
protocol/nokia/phonet.c \
protocol/obex/obex.c \
protocol/symbian/mrouter.c \
phone/pfunc.c \
phone/at/atgen.c \
phone/at/siemens.c \
phone/at/sonyeric.c \
phone/alcatel/alcatel.c \
phone/nokia/dct3/n6110.c \
phone/nokia/dct3/n7110.c \
phone/nokia/dct3/n9210.c \
phone/nokia/dct3/dct3func.c \
phone/nokia/dct4/n3320.c \
phone/nokia/dct4/n3650.c \
phone/nokia/dct4/n6510.c \
phone/nokia/dct4/dct4func.c \
phone/nokia/nauto.c \
phone/nokia/nfunc.c \
phone/nokia/nfuncold.c \
phone/obex/obexgen.c \
phone/symbian/mroutgen.c
TARGET = microgammu
DESTDIR = $(QPEDIR)/lib
OBJECTS_DIR = obj/$(PLATFORM)
MOC_DIR = moc/$(PLATFORM)
+CONFIG = warn_off release console
diff --git a/gammu/emb/common/service/gsmring.c b/gammu/emb/common/service/gsmring.c
index 5a1ff87..f7f7082 100644
--- a/gammu/emb/common/service/gsmring.c
+++ b/gammu/emb/common/service/gsmring.c
@@ -1,491 +1,492 @@
/* (c) 2001-2004 by Marcin Wiacek */
/* Based on some work from Ralf Thelen (7110 ringtones),
* Gnokii (RTTL and SM) and others
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#ifdef WIN32
# include <windows.h>
#endif
#include "../gsmcomon.h"
#include "../misc/coding/coding.h"
#include "../gsmstate.h"
#include "gsmring.h"
#include "sms/gsmsms.h"
int GSM_RingNoteGetFrequency(GSM_RingNote Note)
{
double freq=0;
/* Values according to the software from http://iki.fi/too/sw/xring/
* generated with:
* perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)'
*/
switch (Note.Note) {
case Note_C : freq = 523.3; break;
case Note_Cis: freq = 554.4; break;
case Note_D : freq = 587.3; break;
case Note_Dis: freq = 622.3; break;
case Note_E : freq = 659.3; break;
case Note_F : freq = 698.5; break;
case Note_Fis: freq = 740; break;
case Note_G : freq = 784; break;
case Note_Gis: freq = 830.6; break;
case Note_A : freq = 880; break;
case Note_Ais: freq = 932.3; break;
case Note_H : freq = 987.8; break;
case Note_Pause: break;
}
switch (Note.Scale) {
case Scale_440 : freq = freq / 2; break;
case Scale_880 : break;
case Scale_1760: freq = freq * 2; break;
case Scale_3520: freq = freq * 4; break;
default : break;
}
return (int)freq;
}
int GSM_RingNoteGetFullDuration(GSM_RingNote Note)
{
int duration = 1;
switch (Note.Duration) {
case Duration_Full : duration = 128; break;
case Duration_1_2 : duration = 64; break;
case Duration_1_4 : duration = 32; break;
case Duration_1_8 : duration = 16; break;
case Duration_1_16 : duration = 8; break;
case Duration_1_32 : duration = 4; break;
}
switch (Note.DurationSpec) {
case NoSpecialDuration : break;
case DottedNote : duration = duration * 3/2; break;
case DoubleDottedNote : duration = duration * 9/4; break;
case Length_2_3 : duration = duration * 2/3; break;
}
return duration;
}
#ifndef PI
# define PI 3.141592654
#endif
#define WAV_SAMPLE_RATE 44100
GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone)
{
unsigned char WAV_Header[] = {
'R','I','F','F',
0x00,0x00,0x00,0x00, /* Length */
'W','A','V','E'};
unsigned char FMT_Header[] = {'f','m','t',' ',
0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x44,0xac,
0x00,0x00,0x88,0x58,0x01,0x00,0x02,0x00,0x10,0x00};
unsigned char DATA_Header[] = {
'd','a','t','a',
0x00,0x00,0x00,0x00}; /* Length */
short DATA_Buffer[60000];
long wavfilesize;
GSM_RingNote *Note;
long i,j,length=0;
double phase=0,phase_step;
fwrite(&WAV_Header, 1, sizeof(WAV_Header), file);
fwrite(&FMT_Header, 1, sizeof(FMT_Header), file);
fwrite(&DATA_Header, 1, sizeof(DATA_Header), file);
for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
Note = &ringtone->NoteTone.Commands[i].Note;
phase_step = GSM_RingNoteGetFrequency(*Note)*WAV_SAMPLE_RATE*1.5;
for (j=0;j<((long)(GSM_RingNoteGetFullDuration(*Note)*WAV_SAMPLE_RATE/70));j++) {
- DATA_Buffer[j] = ((int)(sin(phase*PI)*50000));
+ /*DATA_Buffer[j] = ((int)(sin(phase*PI)*50000));*/
+ DATA_Buffer[j] = ((int)(0.5*50000));
phase = phase + phase_step;
length++;
}
fwrite(&DATA_Buffer,sizeof(short),j,file);
}
}
wavfilesize = sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header) + length*2;
WAV_Header[4] = ((unsigned char)wavfilesize % 256);
WAV_Header[5] = ((unsigned char)wavfilesize / 256);
WAV_Header[6] = ((unsigned char)wavfilesize / (256*256));
WAV_Header[7] = ((unsigned char)wavfilesize / (256*256*256));
wavfilesize = wavfilesize - 54;
DATA_Header[4] = ((unsigned char)wavfilesize % 256);
DATA_Header[5] = ((unsigned char)wavfilesize / 256);
DATA_Header[6] = ((unsigned char)wavfilesize / (256*256));
DATA_Header[7] = ((unsigned char)wavfilesize / (256*256*256));
fseek( file, 0, SEEK_SET);
fwrite(&WAV_Header, 1, sizeof(WAV_Header), file);
fwrite(&FMT_Header, 1, sizeof(FMT_Header), file);
fwrite(&DATA_Header, 1, sizeof(DATA_Header), file);
return ERR_NONE;
}
static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone)
{
char nullchar=0x00;
fwrite(&nullchar,1,1,file);
fwrite(&nullchar,1,1,file);
fprintf(file,"\x0C\x01\x2C");
fprintf(file,"%s",DecodeUnicodeString(ringtone->Name));
fwrite(&nullchar,1,1,file);
fwrite(&nullchar,1,1,file);
fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file);
return ERR_NONE;
}
static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone)
{
fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file);
return ERR_NONE;
}
GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone)
{
GSM_RingNoteScale DefNoteScale;
GSM_RingNoteDuration DefNoteDuration;
GSM_RingNoteStyle DefNoteStyle=0;
int DefNoteTempo=0;
bool started = false, firstcomma = true;
GSM_RingNote *Note;
unsigned char buffer[15];
int i,j,k=0;
/* Saves ringtone name */
fprintf(file,"%s:",DecodeUnicodeString(ringtone->Name));
/* Find the most frequently used duration */
for (i=0;i<6;i++) buffer[i]=0;
for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
Note = &ringtone->NoteTone.Commands[i].Note;
/* some durations need 2 bytes in file, some 1 */
if (Note->Duration >= Duration_Full && Note->Duration <= Duration_1_8) {
buffer[Note->Duration/32]++;
}
if (Note->Duration >= Duration_1_16 && Note->Duration <= Duration_1_32) {
buffer[Note->Duration/32]+=2;
}
}
}
/* Now find the most frequently used */
j=0;
for (i=0;i<6;i++) {
if (buffer[i]>j) {
k=i;
j=buffer[i];
}
}
/* Finally convert the default duration */
DefNoteDuration = k * 32;
dbgprintf("DefNoteDuration=%d\n", DefNoteDuration);
switch (DefNoteDuration) {
case Duration_Full:fprintf(file,"d=1"); break;
case Duration_1_2 :fprintf(file,"d=2"); break;
case Duration_1_4 :fprintf(file,"d=4"); break;
case Duration_1_8 :fprintf(file,"d=8"); break;
case Duration_1_16:fprintf(file,"d=16");break;
case Duration_1_32:fprintf(file,"d=32");break;
}
/* Find the most frequently used scale */
for (i=0;i<9;i++) buffer[i]=0;
for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
Note = &ringtone->NoteTone.Commands[i].Note;
if (Note->Note!=Note_Pause &&
Note->Scale >= Scale_55 && Note->Scale <= Scale_14080) {
buffer[Note->Scale - 1]++;
}
}
}
j=0;
for (i=0;i<9;i++) {
if (buffer[i]>j) {
k = i;
j=buffer[i];
}
}
DefNoteScale = k + 1;
/* Save the default scale */
fprintf(file,",o=%i,",DefNoteScale);
dbgprintf("DefNoteScale=%d\n", DefNoteScale);
for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
if (ringtone->NoteTone.Commands[i].Type != RING_Note) continue;
Note = &ringtone->NoteTone.Commands[i].Note;
/* Trick from PPM Edit */
if (Note->DurationSpec == DoubleDottedNote) {
switch (Note->Duration) {
case Duration_Full:Note->Duration = Duration_Full;break;
case Duration_1_2 :Note->Duration = Duration_Full;break;
case Duration_1_4 :Note->Duration = Duration_1_2; break;
case Duration_1_8 :Note->Duration = Duration_1_4; break;
case Duration_1_16:Note->Duration = Duration_1_8; break;
case Duration_1_32:Note->Duration = Duration_1_16;break;
}
Note->DurationSpec = NoSpecialDuration;
}
if (!started) {
DefNoteTempo=Note->Tempo;
DefNoteStyle=Note->Style;
switch (Note->Style) {
case StaccatoStyle : fprintf(file,"s=S,"); break;
case NaturalStyle : fprintf(file,"s=N,"); break;
case ContinuousStyle : break;
}
/* Save the default tempo */
fprintf(file,"b=%i:",DefNoteTempo);
dbgprintf("DefNoteTempo=%d\n", DefNoteTempo);
started = true;
firstcomma = true;
}
if (!started) continue;
if (Note->Style!=DefNoteStyle) {
/* And a separator */
if (!firstcomma) fprintf(file,",");
firstcomma = false;
DefNoteStyle=Note->Style;
switch (Note->Style) {
case StaccatoStyle : fprintf(file,"s=S"); break;
case NaturalStyle : fprintf(file,"s=N"); break;
case ContinuousStyle: fprintf(file,"s=C"); break;
}
}
if (Note->Tempo!=DefNoteTempo) {
/* And a separator */
if (!firstcomma) fprintf(file,",");
firstcomma = false;
DefNoteTempo=Note->Tempo;
fprintf(file,"b=%i",DefNoteTempo);
}
/* This note has a duration different than the default. We must save it */
if (Note->Duration!=DefNoteDuration) {
/* And a separator */
if (!firstcomma) fprintf(file,",");
firstcomma = false;
switch (Note->Duration) {
case Duration_Full:fprintf(file,"1"); break;
case Duration_1_2 :fprintf(file,"2"); break;
case Duration_1_4 :fprintf(file,"4"); break;
case Duration_1_8 :fprintf(file,"8"); break;
case Duration_1_16:fprintf(file,"16");break;
case Duration_1_32:fprintf(file,"32");break;
}
} else {
/* And a separator */
if (!firstcomma) fprintf(file,",");
firstcomma = false;
}
/* Now save the actual note */
switch (Note->Note) {
case Note_C :fprintf(file,"c"); break;
case Note_Cis:fprintf(file,"c#"); break;
case Note_D :fprintf(file,"d"); break;
case Note_Dis:fprintf(file,"d#"); break;
case Note_E :fprintf(file,"e"); break;
case Note_F :fprintf(file,"f"); break;
case Note_Fis:fprintf(file,"f#"); break;
case Note_G :fprintf(file,"g"); break;
case Note_Gis:fprintf(file,"g#"); break;
case Note_A :fprintf(file,"a"); break;
case Note_Ais:fprintf(file,"a#"); break;
case Note_H :fprintf(file,"h"); break;
default :fprintf(file,"p"); break; /*Pause ?*/
}
switch (Note->DurationSpec) {
case DottedNote : fprintf(file,"."); break;
default : break;
}
if (Note->Note!=Note_Pause && Note->Scale != DefNoteScale) {
fprintf(file,"%i",Note->Scale);
}
}
return ERR_NONE;
}
void saveimelody(FILE *file, GSM_Ringtone *ringtone)
{
char Buffer[2000];
int i=2000;
GSM_EncodeEMSSound(*ringtone, Buffer, &i, (float)1.2, true);
fwrite(Buffer, 1, i, file);
}
#ifndef ENABLE_LGPL
static void WriteVarLen(unsigned char* midifile, int* current, long value)
{
long buffer;
buffer = value & 0x7f;
while (value >>= 7) {
buffer <<= 8;
buffer |= 0x80;
buffer += (value & 0x7f);
}
while (1) {
midifile[(*current)++] = (unsigned char)buffer;
if (buffer & 0x80) {
buffer >>= 8;
} else {
break;
}
}
}
#define singlepauses
/* FIXME: need adding tempo before each note and scale too ? */
void savemid(FILE* file, GSM_Ringtone *ringtone)
{
int pause = 0, current = 26, duration, i, note=0, length = 20;
bool started = false;
GSM_RingNote *Note;
unsigned char midifile[3000] = {
0x4D, 0x54, 0x68, 0x64, // MThd
0x00, 0x00, 0x00, 0x06, // chunk length
0x00, 0x00, // format 0
0x00, 0x01, // one track
0x00, 0x20, // 32 per quarter note
0x4D, 0x54, 0x72, 0x6B, // MTrk
0x00, 0x00, 0x00, 0x00, // chunk length
0x00, 0xFF, 0x51, 0x03, // tempo meta event
0x00, 0x00, 0x00}; // 3 bytes for us for a quarter note
for (i = 0; i < ringtone->NoteTone.NrCommands; i++) {
if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
Note = &ringtone->NoteTone.Commands[i].Note;
if (!started) {
/* readmid does not read pauses at the beginning */
if (Note->Note != Note_Pause) {
/* FIXME: we need add tempo before each note or so... */
long duration=60000000/Note->Tempo;
midifile[current++] = (unsigned char)(duration >> 16);
midifile[current++] = (unsigned char)(duration >> 8);
midifile[current++] = (unsigned char)duration;
started = true;
}
}
if (!started) continue;
duration = GSM_RingNoteGetFullDuration(*Note);
if (Note->Note == Note_Pause) {
pause += duration;
#ifdef singlepauses
WriteVarLen(midifile,&current,pause);
pause=0;
midifile[current++]=0x00; // pause
midifile[current++]=0x00;
#endif
} else {
if (Note->Note >= Note_C && Note->Note <= Note_H) {
note = Note->Note/16 + 12 * Note->Scale - 1;
}
WriteVarLen(midifile,&current,pause);
pause=0;
midifile[current++]=0x90; // note on
midifile[current++]=note;
midifile[current++]=0x64; // forte
WriteVarLen(midifile,&current,duration);
midifile[current++]=0x80; // note off
midifile[current++]=note;
midifile[current++]=0x64;
}
}
}
if (pause) {
WriteVarLen(midifile,&current,pause);
midifile[current++]=0x00; // pause
midifile[current++]=0x00; //
}
midifile[current++] = 0x00;
midifile[current++] = 0xFF; // track end
midifile[current++] = 0x2F;
midifile[current++] = 0x00;
midifile[length++] = (current-22) >> 8;
midifile[length++] = current-22;
fwrite(midifile,1,current,file);
}
#endif
void saveott(FILE *file, GSM_Ringtone *ringtone)
{
char Buffer[2000];
int i=2000;
GSM_EncodeNokiaRTTLRingtone(*ringtone, Buffer, &i);
fwrite(Buffer, 1, i, file);
}
GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone)
{
FILE *file;
file = fopen(FileName, "wb");
if (file == NULL) return ERR_CANTOPENFILE;
switch (ringtone->Format) {
case RING_NOTETONE:
if (strstr(FileName,".ott")) {
saveott(file,ringtone);
#ifndef ENABLE_LGPL
} else if (strstr(FileName,".mid")) {
savemid(file,ringtone);
#endif
} else if (strstr(FileName,".rng")) {
saveott(file,ringtone);
} else if (strstr(FileName,".imy")) {
saveimelody(file,ringtone);
} else if (strstr(FileName,".ime")) {
saveimelody(file,ringtone);
} else if (strstr(FileName,".wav")) {
savewav(file,ringtone);
} else {
saverttl(file, ringtone);
}
break;
case RING_NOKIABINARY:
savebin(file, ringtone);
break;
case RING_MIDI:
savepuremidi(file, ringtone);
break;
}
fclose(file);
return ERR_NONE;
}
static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone)
{