-rw-r--r-- | gammu/emb/common/common.pro | 2 | ||||
-rw-r--r-- | gammu/emb/common/commonE.pro | 1 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmring.c | 3 |
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,¤t,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,¤t,pause); pause=0; midifile[current++]=0x90; // note on midifile[current++]=note; midifile[current++]=0x64; // forte WriteVarLen(midifile,¤t,duration); midifile[current++]=0x80; // note off midifile[current++]=note; midifile[current++]=0x64; } } } if (pause) { WriteVarLen(midifile,¤t,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) { |