summaryrefslogtreecommitdiffabout
path: root/gammu/emb
Unidiff
Diffstat (limited to 'gammu/emb') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/common.pro1
-rw-r--r--gammu/emb/common/service/gsmring.c6
2 files changed, 6 insertions, 1 deletions
diff --git a/gammu/emb/common/common.pro b/gammu/emb/common/common.pro
index 9342cb7..0e719ee 100644
--- a/gammu/emb/common/common.pro
+++ b/gammu/emb/common/common.pro
@@ -1,186 +1,187 @@
1###################################################################### 1######################################################################
2# Automatically generated by qmake (1.07a) Fri Jul 30 22:13:34 2004 2# Automatically generated by qmake (1.07a) Fri Jul 30 22:13:34 2004
3###################################################################### 3######################################################################
4 4
5TEMPLATE = lib 5TEMPLATE = lib
6DEPENDPATH += device \ 6DEPENDPATH += device \
7 misc \ 7 misc \
8 phone \ 8 phone \
9 protocol \ 9 protocol \
10 service \ 10 service \
11 device/bluetoth \ 11 device/bluetoth \
12 device/irda \ 12 device/irda \
13 device/serial \ 13 device/serial \
14 misc/coding \ 14 misc/coding \
15 phone/alcatel \ 15 phone/alcatel \
16 phone/at \ 16 phone/at \
17 phone/nokia \ 17 phone/nokia \
18 phone/obex \ 18 phone/obex \
19 phone/symbian \ 19 phone/symbian \
20 protocol/alcatel \ 20 protocol/alcatel \
21 protocol/at \ 21 protocol/at \
22 protocol/nokia \ 22 protocol/nokia \
23 protocol/obex \ 23 protocol/obex \
24 protocol/symbian \ 24 protocol/symbian \
25 service/backup \ 25 service/backup \
26 service/sms \ 26 service/sms \
27 phone/nokia/dct3 \ 27 phone/nokia/dct3 \
28 phone/nokia/dct4 28 phone/nokia/dct4
29INCLUDEPATH += . \ 29INCLUDEPATH += . \
30 misc/coding \ 30 misc/coding \
31 misc \ 31 misc \
32 device \ 32 device \
33 phone/nokia/dct4 \ 33 phone/nokia/dct4 \
34 phone/nokia/dct3 \ 34 phone/nokia/dct3 \
35 phone/at \ 35 phone/at \
36 phone/alcatel \ 36 phone/alcatel \
37 phone/obex \ 37 phone/obex \
38 phone/symbian \ 38 phone/symbian \
39 protocol \ 39 protocol \
40 protocol/nokia \ 40 protocol/nokia \
41 protocol/at \ 41 protocol/at \
42 protocol/alcatel \ 42 protocol/alcatel \
43 protocol/obex \ 43 protocol/obex \
44 protocol/symbian \ 44 protocol/symbian \
45 device/serial \ 45 device/serial \
46 device/irda \ 46 device/irda \
47 device/bluetoth \ 47 device/bluetoth \
48 service \ 48 service \
49 service/sms \ 49 service/sms \
50 service/backup \ 50 service/backup \
51 phone/nokia \ 51 phone/nokia \
52 phone 52 phone
53 53
54# Input 54# Input
55HEADERS += config.h \ 55HEADERS += config.h \
56 gammu.h \ 56 gammu.h \
57 gsmcomon.h \ 57 gsmcomon.h \
58 gsmstate.h \ 58 gsmstate.h \
59 device/devfunc.h \ 59 device/devfunc.h \
60 misc/cfg.h \ 60 misc/cfg.h \
61 misc/misc.h \ 61 misc/misc.h \
62 phone/pfunc.h \ 62 phone/pfunc.h \
63 protocol/protocol.h \ 63 protocol/protocol.h \
64 service/gsmcal.h \ 64 service/gsmcal.h \
65 service/gsmcall.h \ 65 service/gsmcall.h \
66 service/gsmdata.h \ 66 service/gsmdata.h \
67 service/gsmlogo.h \ 67 service/gsmlogo.h \
68 service/gsmmisc.h \ 68 service/gsmmisc.h \
69 service/gsmnet.h \ 69 service/gsmnet.h \
70 service/gsmpbk.h \ 70 service/gsmpbk.h \
71 service/gsmprof.h \ 71 service/gsmprof.h \
72 service/gsmring.h \ 72 service/gsmring.h \
73 device/bluetoth/affix.h \ 73 device/bluetoth/affix.h \
74 device/bluetoth/blue_w32.h \ 74 device/bluetoth/blue_w32.h \
75 device/bluetoth/bluetoth.h \ 75 device/bluetoth/bluetoth.h \
76 device/bluetoth/bluez.h \ 76 device/bluetoth/bluez.h \
77 device/irda/irda.h \ 77 device/irda/irda.h \
78 device/irda/irda_unx.h \ 78 device/irda/irda_unx.h \
79 device/irda/irda_w32.h \ 79 device/irda/irda_w32.h \
80 device/serial/ser_djg.h \ 80 device/serial/ser_djg.h \
81 device/serial/ser_unx.h \ 81 device/serial/ser_unx.h \
82 device/serial/ser_w32.h \ 82 device/serial/ser_w32.h \
83 misc/coding/coding.h \ 83 misc/coding/coding.h \
84 misc/coding/md5.h \ 84 misc/coding/md5.h \
85 phone/alcatel/alcatel.h \ 85 phone/alcatel/alcatel.h \
86 phone/at/atgen.h \ 86 phone/at/atgen.h \
87 phone/nokia/ncommon.h \ 87 phone/nokia/ncommon.h \
88 phone/nokia/nfunc.h \ 88 phone/nokia/nfunc.h \
89 phone/nokia/nfuncold.h \ 89 phone/nokia/nfuncold.h \
90 phone/obex/obexgen.h \ 90 phone/obex/obexgen.h \
91 phone/symbian/mroutgen.h \ 91 phone/symbian/mroutgen.h \
92 protocol/alcatel/alcabus.h \ 92 protocol/alcatel/alcabus.h \
93 protocol/at/at.h \ 93 protocol/at/at.h \
94 protocol/nokia/fbus2.h \ 94 protocol/nokia/fbus2.h \
95 protocol/nokia/mbus2.h \ 95 protocol/nokia/mbus2.h \
96 protocol/nokia/phonet.h \ 96 protocol/nokia/phonet.h \
97 protocol/obex/obex.h \ 97 protocol/obex/obex.h \
98 protocol/symbian/mrouter.h \ 98 protocol/symbian/mrouter.h \
99 service/backup/backgen.h \ 99 service/backup/backgen.h \
100 service/backup/backics.h \ 100 service/backup/backics.h \
101 service/backup/backldif.h \ 101 service/backup/backldif.h \
102 service/backup/backlmb.h \ 102 service/backup/backlmb.h \
103 service/backup/backtext.h \ 103 service/backup/backtext.h \
104 service/backup/backvcf.h \ 104 service/backup/backvcf.h \
105 service/backup/backvcs.h \ 105 service/backup/backvcs.h \
106 service/backup/gsmback.h \ 106 service/backup/gsmback.h \
107 service/sms/gsmems.h \ 107 service/sms/gsmems.h \
108 service/sms/gsmmulti.h \ 108 service/sms/gsmmulti.h \
109 service/sms/gsmsms.h \ 109 service/sms/gsmsms.h \
110 phone/nokia/dct3/dct3comm.h \ 110 phone/nokia/dct3/dct3comm.h \
111 phone/nokia/dct3/dct3func.h \ 111 phone/nokia/dct3/dct3func.h \
112 phone/nokia/dct3/n6110.h \ 112 phone/nokia/dct3/n6110.h \
113 phone/nokia/dct3/n7110.h \ 113 phone/nokia/dct3/n7110.h \
114 phone/nokia/dct3/n9210.h \ 114 phone/nokia/dct3/n9210.h \
115 phone/nokia/dct4/dct4func.h \ 115 phone/nokia/dct4/dct4func.h \
116 phone/nokia/dct4/n3320.h \ 116 phone/nokia/dct4/n3320.h \
117 phone/nokia/dct4/n3650.h \ 117 phone/nokia/dct4/n3650.h \
118 phone/nokia/dct4/n6510.h 118 phone/nokia/dct4/n6510.h
119SOURCES +=gsmcomon.c \ 119SOURCES +=gsmcomon.c \
120gsmstate.c \ 120gsmstate.c \
121misc/misc.c \ 121misc/misc.c \
122misc/cfg.c \ 122misc/cfg.c \
123misc/coding/coding.c \ 123misc/coding/coding.c \
124misc/coding/md5.c \ 124misc/coding/md5.c \
125service/sms/gsmsms.c \ 125service/sms/gsmsms.c \
126service/sms/gsmems.c \ 126service/sms/gsmems.c \
127service/sms/gsmmulti.c \ 127service/sms/gsmmulti.c \
128service/gsmcal.c \ 128service/gsmcal.c \
129service/gsmdata.c \ 129service/gsmdata.c \
130service/gsmpbk.c \ 130service/gsmpbk.c \
131service/gsmring.c \ 131service/gsmring.c \
132service/gsmlogo.c \ 132service/gsmlogo.c \
133service/gsmmisc.c \ 133service/gsmmisc.c \
134service/gsmnet.c \ 134service/gsmnet.c \
135service/backup/gsmback.c \ 135service/backup/gsmback.c \
136service/backup/backldif.c \ 136service/backup/backldif.c \
137service/backup/backlmb.c \ 137service/backup/backlmb.c \
138service/backup/backtext.c \ 138service/backup/backtext.c \
139service/backup/backvcs.c \ 139service/backup/backvcs.c \
140service/backup/backvcf.c \ 140service/backup/backvcf.c \
141service/backup/backics.c \ 141service/backup/backics.c \
142device/bluetoth/affix.c \ 142device/bluetoth/affix.c \
143device/bluetoth/bluez.c \ 143device/bluetoth/bluez.c \
144device/bluetoth/blue_w32.c \ 144device/bluetoth/blue_w32.c \
145device/bluetoth/bluetoth.c \ 145device/bluetoth/bluetoth.c \
146device/serial/ser_djg.c \ 146device/serial/ser_djg.c \
147device/irda/irda.c \ 147device/irda/irda.c \
148device/devfunc.c \ 148device/devfunc.c \
149protocol/at/at.c \ 149protocol/at/at.c \
150protocol/alcatel/alcabus.c \ 150protocol/alcatel/alcabus.c \
151protocol/nokia/mbus2.c \ 151protocol/nokia/mbus2.c \
152protocol/nokia/fbus2.c \ 152protocol/nokia/fbus2.c \
153protocol/nokia/phonet.c \ 153protocol/nokia/phonet.c \
154protocol/obex/obex.c \ 154protocol/obex/obex.c \
155protocol/symbian/mrouter.c \ 155protocol/symbian/mrouter.c \
156phone/pfunc.c \ 156phone/pfunc.c \
157phone/at/atgen.c \ 157phone/at/atgen.c \
158phone/at/siemens.c \ 158phone/at/siemens.c \
159phone/at/sonyeric.c \ 159phone/at/sonyeric.c \
160phone/alcatel/alcatel.c \ 160phone/alcatel/alcatel.c \
161phone/nokia/dct3/n6110.c \ 161phone/nokia/dct3/n6110.c \
162phone/nokia/dct3/n7110.c \ 162phone/nokia/dct3/n7110.c \
163phone/nokia/dct3/n9210.c \ 163phone/nokia/dct3/n9210.c \
164phone/nokia/dct3/dct3func.c \ 164phone/nokia/dct3/dct3func.c \
165phone/nokia/dct4/n3320.c \ 165phone/nokia/dct4/n3320.c \
166phone/nokia/dct4/n3650.c \ 166phone/nokia/dct4/n3650.c \
167phone/nokia/dct4/n6510.c \ 167phone/nokia/dct4/n6510.c \
168phone/nokia/dct4/dct4func.c \ 168phone/nokia/dct4/dct4func.c \
169phone/nokia/nauto.c \ 169phone/nokia/nauto.c \
170phone/nokia/nfunc.c \ 170phone/nokia/nfunc.c \
171phone/nokia/nfuncold.c \ 171phone/nokia/nfuncold.c \
172phone/obex/obexgen.c \ 172phone/obex/obexgen.c \
173phone/symbian/mroutgen.c 173phone/symbian/mroutgen.c
174 174
175DEFINES += DESKTOP_VERSION
175TARGET = microgammu 176TARGET = microgammu
176CONFIG = warn_off release console 177CONFIG = warn_off release console
177DESTDIR = ../../../bin 178DESTDIR = ../../../bin
178OBJECTS_DIR = obj/unix 179OBJECTS_DIR = obj/unix
179MOC_DIR = moc/unix 180MOC_DIR = moc/unix
180 181
181unix: { 182unix: {
182SOURCES += device/serial/ser_unx.c 183SOURCES += device/serial/ser_unx.c
183} 184}
184win32:{ 185win32:{
185SOURCES += device/serial/ser_w32.c 186SOURCES += device/serial/ser_w32.c
186} 187}
diff --git a/gammu/emb/common/service/gsmring.c b/gammu/emb/common/service/gsmring.c
index f7f7082..7df46f1 100644
--- a/gammu/emb/common/service/gsmring.c
+++ b/gammu/emb/common/service/gsmring.c
@@ -1,620 +1,624 @@
1/* (c) 2001-2004 by Marcin Wiacek */ 1/* (c) 2001-2004 by Marcin Wiacek */
2/* Based on some work from Ralf Thelen (7110 ringtones), 2/* Based on some work from Ralf Thelen (7110 ringtones),
3 * Gnokii (RTTL and SM) and others 3 * Gnokii (RTTL and SM) and others
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h> 7#include <string.h>
8#include <ctype.h> 8#include <ctype.h>
9#include <math.h> 9#include <math.h>
10#ifdef WIN32 10#ifdef WIN32
11# include <windows.h> 11# include <windows.h>
12#endif 12#endif
13 13
14#include "../gsmcomon.h" 14#include "../gsmcomon.h"
15#include "../misc/coding/coding.h" 15#include "../misc/coding/coding.h"
16#include "../gsmstate.h" 16#include "../gsmstate.h"
17#include "gsmring.h" 17#include "gsmring.h"
18#include "sms/gsmsms.h" 18#include "sms/gsmsms.h"
19 19
20int GSM_RingNoteGetFrequency(GSM_RingNote Note) 20int GSM_RingNoteGetFrequency(GSM_RingNote Note)
21{ 21{
22 double freq=0; 22 double freq=0;
23 23
24 /* Values according to the software from http://iki.fi/too/sw/xring/ 24 /* Values according to the software from http://iki.fi/too/sw/xring/
25 * generated with: 25 * generated with:
26 * perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)' 26 * perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)'
27 */ 27 */
28 switch (Note.Note) { 28 switch (Note.Note) {
29 case Note_C : freq = 523.3; break; 29 case Note_C : freq = 523.3; break;
30 case Note_Cis: freq = 554.4; break; 30 case Note_Cis: freq = 554.4; break;
31 case Note_D : freq = 587.3; break; 31 case Note_D : freq = 587.3; break;
32 case Note_Dis: freq = 622.3; break; 32 case Note_Dis: freq = 622.3; break;
33 case Note_E : freq = 659.3; break; 33 case Note_E : freq = 659.3; break;
34 case Note_F : freq = 698.5; break; 34 case Note_F : freq = 698.5; break;
35 case Note_Fis: freq = 740; break; 35 case Note_Fis: freq = 740; break;
36 case Note_G : freq = 784; break; 36 case Note_G : freq = 784; break;
37 case Note_Gis: freq = 830.6; break; 37 case Note_Gis: freq = 830.6; break;
38 case Note_A : freq = 880; break; 38 case Note_A : freq = 880; break;
39 case Note_Ais: freq = 932.3; break; 39 case Note_Ais: freq = 932.3; break;
40 case Note_H : freq = 987.8; break; 40 case Note_H : freq = 987.8; break;
41 case Note_Pause: break; 41 case Note_Pause: break;
42 } 42 }
43 switch (Note.Scale) { 43 switch (Note.Scale) {
44 case Scale_440 : freq = freq / 2; break; 44 case Scale_440 : freq = freq / 2; break;
45 case Scale_880 : break; 45 case Scale_880 : break;
46 case Scale_1760: freq = freq * 2; break; 46 case Scale_1760: freq = freq * 2; break;
47 case Scale_3520: freq = freq * 4; break; 47 case Scale_3520: freq = freq * 4; break;
48 default : break; 48 default : break;
49 } 49 }
50 return (int)freq; 50 return (int)freq;
51} 51}
52 52
53int GSM_RingNoteGetFullDuration(GSM_RingNote Note) 53int GSM_RingNoteGetFullDuration(GSM_RingNote Note)
54{ 54{
55 int duration = 1; 55 int duration = 1;
56 56
57 switch (Note.Duration) { 57 switch (Note.Duration) {
58 case Duration_Full : duration = 128; break; 58 case Duration_Full : duration = 128; break;
59 case Duration_1_2 : duration = 64; break; 59 case Duration_1_2 : duration = 64; break;
60 case Duration_1_4 : duration = 32; break; 60 case Duration_1_4 : duration = 32; break;
61 case Duration_1_8 : duration = 16; break; 61 case Duration_1_8 : duration = 16; break;
62 case Duration_1_16 : duration = 8; break; 62 case Duration_1_16 : duration = 8; break;
63 case Duration_1_32 : duration = 4; break; 63 case Duration_1_32 : duration = 4; break;
64 } 64 }
65 switch (Note.DurationSpec) { 65 switch (Note.DurationSpec) {
66 case NoSpecialDuration : break; 66 case NoSpecialDuration : break;
67 case DottedNote : duration = duration * 3/2;break; 67 case DottedNote : duration = duration * 3/2;break;
68 case DoubleDottedNote : duration = duration * 9/4;break; 68 case DoubleDottedNote : duration = duration * 9/4;break;
69 case Length_2_3 : duration = duration * 2/3;break; 69 case Length_2_3 : duration = duration * 2/3;break;
70 } 70 }
71 return duration; 71 return duration;
72} 72}
73 73
74#ifndef PI 74#ifndef PI
75# define PI 3.141592654 75# define PI 3.141592654
76#endif 76#endif
77 77
78#define WAV_SAMPLE_RATE 44100 78#define WAV_SAMPLE_RATE 44100
79 79
80GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone) 80GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone)
81{ 81{
82 unsigned char WAV_Header[] = { 82 unsigned char WAV_Header[] = {
83 'R','I','F','F', 83 'R','I','F','F',
84 0x00,0x00,0x00,0x00,/* Length */ 84 0x00,0x00,0x00,0x00,/* Length */
85 'W','A','V','E'}; 85 'W','A','V','E'};
86 unsigned char FMT_Header[] = {'f','m','t',' ', 86 unsigned char FMT_Header[] = {'f','m','t',' ',
87 0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x44,0xac, 87 0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x44,0xac,
88 0x00,0x00,0x88,0x58,0x01,0x00,0x02,0x00,0x10,0x00}; 88 0x00,0x00,0x88,0x58,0x01,0x00,0x02,0x00,0x10,0x00};
89 unsigned char DATA_Header[] = { 89 unsigned char DATA_Header[] = {
90 'd','a','t','a', 90 'd','a','t','a',
91 0x00,0x00,0x00,0x00};/* Length */ 91 0x00,0x00,0x00,0x00};/* Length */
92 short DATA_Buffer[60000]; 92 short DATA_Buffer[60000];
93 long wavfilesize; 93 long wavfilesize;
94 GSM_RingNote *Note; 94 GSM_RingNote *Note;
95 long i,j,length=0; 95 long i,j,length=0;
96 double phase=0,phase_step; 96 double phase=0,phase_step;
97 97
98 fwrite(&WAV_Header, 1, sizeof(WAV_Header),file); 98 fwrite(&WAV_Header, 1, sizeof(WAV_Header),file);
99 fwrite(&FMT_Header, 1, sizeof(FMT_Header),file); 99 fwrite(&FMT_Header, 1, sizeof(FMT_Header),file);
100 fwrite(&DATA_Header, 1, sizeof(DATA_Header),file); 100 fwrite(&DATA_Header, 1, sizeof(DATA_Header),file);
101 101
102 for (i=0;i<ringtone->NoteTone.NrCommands;i++) { 102 for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
103 if (ringtone->NoteTone.Commands[i].Type == RING_Note) { 103 if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
104 Note = &ringtone->NoteTone.Commands[i].Note; 104 Note = &ringtone->NoteTone.Commands[i].Note;
105 phase_step = GSM_RingNoteGetFrequency(*Note)*WAV_SAMPLE_RATE*1.5; 105 phase_step = GSM_RingNoteGetFrequency(*Note)*WAV_SAMPLE_RATE*1.5;
106 for (j=0;j<((long)(GSM_RingNoteGetFullDuration(*Note)*WAV_SAMPLE_RATE/70));j++) { 106 for (j=0;j<((long)(GSM_RingNoteGetFullDuration(*Note)*WAV_SAMPLE_RATE/70));j++) {
107 /*DATA_Buffer[j] = ((int)(sin(phase*PI)*50000));*/ 107#ifdef DESKTOP_VERSION
108 DATA_Buffer[j] = ((int)(sin(phase*PI)*50000));
109#else
110 // we have no sin on Zaurus
108 DATA_Buffer[j] = ((int)(0.5*50000)); 111 DATA_Buffer[j] = ((int)(0.5*50000));
112#endif
109 phase = phase + phase_step; 113 phase = phase + phase_step;
110 length++; 114 length++;
111 } 115 }
112 fwrite(&DATA_Buffer,sizeof(short),j,file); 116 fwrite(&DATA_Buffer,sizeof(short),j,file);
113 } 117 }
114 } 118 }
115 119
116 wavfilesize = sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header) + length*2; 120 wavfilesize = sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header) + length*2;
117 WAV_Header[4] = ((unsigned char)wavfilesize % 256); 121 WAV_Header[4] = ((unsigned char)wavfilesize % 256);
118 WAV_Header[5] = ((unsigned char)wavfilesize / 256); 122 WAV_Header[5] = ((unsigned char)wavfilesize / 256);
119 WAV_Header[6] = ((unsigned char)wavfilesize / (256*256)); 123 WAV_Header[6] = ((unsigned char)wavfilesize / (256*256));
120 WAV_Header[7] = ((unsigned char)wavfilesize / (256*256*256)); 124 WAV_Header[7] = ((unsigned char)wavfilesize / (256*256*256));
121 wavfilesize = wavfilesize - 54; 125 wavfilesize = wavfilesize - 54;
122 DATA_Header[4] = ((unsigned char)wavfilesize % 256); 126 DATA_Header[4] = ((unsigned char)wavfilesize % 256);
123 DATA_Header[5] = ((unsigned char)wavfilesize / 256); 127 DATA_Header[5] = ((unsigned char)wavfilesize / 256);
124 DATA_Header[6] = ((unsigned char)wavfilesize / (256*256)); 128 DATA_Header[6] = ((unsigned char)wavfilesize / (256*256));
125 DATA_Header[7] = ((unsigned char)wavfilesize / (256*256*256)); 129 DATA_Header[7] = ((unsigned char)wavfilesize / (256*256*256));
126 130
127 fseek( file, 0, SEEK_SET); 131 fseek( file, 0, SEEK_SET);
128 fwrite(&WAV_Header, 1, sizeof(WAV_Header),file); 132 fwrite(&WAV_Header, 1, sizeof(WAV_Header),file);
129 fwrite(&FMT_Header, 1, sizeof(FMT_Header),file); 133 fwrite(&FMT_Header, 1, sizeof(FMT_Header),file);
130 fwrite(&DATA_Header, 1, sizeof(DATA_Header),file); 134 fwrite(&DATA_Header, 1, sizeof(DATA_Header),file);
131 135
132 return ERR_NONE; 136 return ERR_NONE;
133} 137}
134 138
135static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone) 139static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone)
136{ 140{
137 char nullchar=0x00; 141 char nullchar=0x00;
138 142
139 fwrite(&nullchar,1,1,file); 143 fwrite(&nullchar,1,1,file);
140 fwrite(&nullchar,1,1,file); 144 fwrite(&nullchar,1,1,file);
141 fprintf(file,"\x0C\x01\x2C"); 145 fprintf(file,"\x0C\x01\x2C");
142 fprintf(file,"%s",DecodeUnicodeString(ringtone->Name)); 146 fprintf(file,"%s",DecodeUnicodeString(ringtone->Name));
143 fwrite(&nullchar,1,1,file); 147 fwrite(&nullchar,1,1,file);
144 fwrite(&nullchar,1,1,file); 148 fwrite(&nullchar,1,1,file);
145 fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); 149 fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file);
146 return ERR_NONE; 150 return ERR_NONE;
147} 151}
148 152
149static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone) 153static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone)
150{ 154{
151 fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); 155 fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file);
152 return ERR_NONE; 156 return ERR_NONE;
153} 157}
154 158
155GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone) 159GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone)
156{ 160{
157 GSM_RingNoteScaleDefNoteScale; 161 GSM_RingNoteScaleDefNoteScale;
158 GSM_RingNoteDurationDefNoteDuration; 162 GSM_RingNoteDurationDefNoteDuration;
159 163
160 GSM_RingNoteStyleDefNoteStyle=0; 164 GSM_RingNoteStyleDefNoteStyle=0;
161 int DefNoteTempo=0; 165 int DefNoteTempo=0;
162 166
163 bool started = false, firstcomma = true; 167 bool started = false, firstcomma = true;
164 GSM_RingNote *Note; 168 GSM_RingNote *Note;
165 169
166 unsigned char buffer[15]; 170 unsigned char buffer[15];
167 int i,j,k=0; 171 int i,j,k=0;
168 172
169 /* Saves ringtone name */ 173 /* Saves ringtone name */
170 fprintf(file,"%s:",DecodeUnicodeString(ringtone->Name)); 174 fprintf(file,"%s:",DecodeUnicodeString(ringtone->Name));
171 175
172 /* Find the most frequently used duration */ 176 /* Find the most frequently used duration */
173 for (i=0;i<6;i++) buffer[i]=0; 177 for (i=0;i<6;i++) buffer[i]=0;
174 for (i=0;i<ringtone->NoteTone.NrCommands;i++) { 178 for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
175 if (ringtone->NoteTone.Commands[i].Type == RING_Note) { 179 if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
176 Note = &ringtone->NoteTone.Commands[i].Note; 180 Note = &ringtone->NoteTone.Commands[i].Note;
177 /* some durations need 2 bytes in file, some 1 */ 181 /* some durations need 2 bytes in file, some 1 */
178 if (Note->Duration >= Duration_Full && Note->Duration <= Duration_1_8) { 182 if (Note->Duration >= Duration_Full && Note->Duration <= Duration_1_8) {
179 buffer[Note->Duration/32]++; 183 buffer[Note->Duration/32]++;
180 } 184 }
181 if (Note->Duration >= Duration_1_16 && Note->Duration <= Duration_1_32) { 185 if (Note->Duration >= Duration_1_16 && Note->Duration <= Duration_1_32) {
182 buffer[Note->Duration/32]+=2; 186 buffer[Note->Duration/32]+=2;
183 } 187 }
184 } 188 }
185 } 189 }
186 /* Now find the most frequently used */ 190 /* Now find the most frequently used */
187 j=0; 191 j=0;
188 for (i=0;i<6;i++) { 192 for (i=0;i<6;i++) {
189 if (buffer[i]>j) { 193 if (buffer[i]>j) {
190 k=i; 194 k=i;
191 j=buffer[i]; 195 j=buffer[i];
192 } 196 }
193 } 197 }
194 /* Finally convert the default duration */ 198 /* Finally convert the default duration */
195 DefNoteDuration = k * 32; 199 DefNoteDuration = k * 32;
196 dbgprintf("DefNoteDuration=%d\n", DefNoteDuration); 200 dbgprintf("DefNoteDuration=%d\n", DefNoteDuration);
197 switch (DefNoteDuration) { 201 switch (DefNoteDuration) {
198 case Duration_Full:fprintf(file,"d=1"); break; 202 case Duration_Full:fprintf(file,"d=1"); break;
199 case Duration_1_2 :fprintf(file,"d=2"); break; 203 case Duration_1_2 :fprintf(file,"d=2"); break;
200 case Duration_1_4 :fprintf(file,"d=4"); break; 204 case Duration_1_4 :fprintf(file,"d=4"); break;
201 case Duration_1_8 :fprintf(file,"d=8"); break; 205 case Duration_1_8 :fprintf(file,"d=8"); break;
202 case Duration_1_16:fprintf(file,"d=16");break; 206 case Duration_1_16:fprintf(file,"d=16");break;
203 case Duration_1_32:fprintf(file,"d=32");break; 207 case Duration_1_32:fprintf(file,"d=32");break;
204 } 208 }
205 209
206 /* Find the most frequently used scale */ 210 /* Find the most frequently used scale */
207 for (i=0;i<9;i++) buffer[i]=0; 211 for (i=0;i<9;i++) buffer[i]=0;
208 for (i=0;i<ringtone->NoteTone.NrCommands;i++) { 212 for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
209 if (ringtone->NoteTone.Commands[i].Type == RING_Note) { 213 if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
210 Note = &ringtone->NoteTone.Commands[i].Note; 214 Note = &ringtone->NoteTone.Commands[i].Note;
211 if (Note->Note!=Note_Pause && 215 if (Note->Note!=Note_Pause &&
212 Note->Scale >= Scale_55 && Note->Scale <= Scale_14080) { 216 Note->Scale >= Scale_55 && Note->Scale <= Scale_14080) {
213 buffer[Note->Scale - 1]++; 217 buffer[Note->Scale - 1]++;
214 } 218 }
215 } 219 }
216 } 220 }
217 j=0; 221 j=0;
218 for (i=0;i<9;i++) { 222 for (i=0;i<9;i++) {
219 if (buffer[i]>j) { 223 if (buffer[i]>j) {
220 k = i; 224 k = i;
221 j=buffer[i]; 225 j=buffer[i];
222 } 226 }
223 } 227 }
224 DefNoteScale = k + 1; 228 DefNoteScale = k + 1;
225 /* Save the default scale */ 229 /* Save the default scale */
226 fprintf(file,",o=%i,",DefNoteScale); 230 fprintf(file,",o=%i,",DefNoteScale);
227 dbgprintf("DefNoteScale=%d\n", DefNoteScale); 231 dbgprintf("DefNoteScale=%d\n", DefNoteScale);
228 232
229 for (i=0;i<ringtone->NoteTone.NrCommands;i++) { 233 for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
230 if (ringtone->NoteTone.Commands[i].Type != RING_Note) continue; 234 if (ringtone->NoteTone.Commands[i].Type != RING_Note) continue;
231 235
232 Note = &ringtone->NoteTone.Commands[i].Note; 236 Note = &ringtone->NoteTone.Commands[i].Note;
233 237
234 /* Trick from PPM Edit */ 238 /* Trick from PPM Edit */
235 if (Note->DurationSpec == DoubleDottedNote) { 239 if (Note->DurationSpec == DoubleDottedNote) {
236 switch (Note->Duration) { 240 switch (Note->Duration) {
237 case Duration_Full:Note->Duration = Duration_Full;break; 241 case Duration_Full:Note->Duration = Duration_Full;break;
238 case Duration_1_2 :Note->Duration = Duration_Full;break; 242 case Duration_1_2 :Note->Duration = Duration_Full;break;
239 case Duration_1_4 :Note->Duration = Duration_1_2; break; 243 case Duration_1_4 :Note->Duration = Duration_1_2; break;
240 case Duration_1_8 :Note->Duration = Duration_1_4; break; 244 case Duration_1_8 :Note->Duration = Duration_1_4; break;
241 case Duration_1_16:Note->Duration = Duration_1_8; break; 245 case Duration_1_16:Note->Duration = Duration_1_8; break;
242 case Duration_1_32:Note->Duration = Duration_1_16;break; 246 case Duration_1_32:Note->Duration = Duration_1_16;break;
243 } 247 }
244 Note->DurationSpec = NoSpecialDuration; 248 Note->DurationSpec = NoSpecialDuration;
245 } 249 }
246 250
247 if (!started) { 251 if (!started) {
248 DefNoteTempo=Note->Tempo; 252 DefNoteTempo=Note->Tempo;
249 DefNoteStyle=Note->Style; 253 DefNoteStyle=Note->Style;
250 switch (Note->Style) { 254 switch (Note->Style) {
251 case StaccatoStyle: fprintf(file,"s=S,"); break; 255 case StaccatoStyle: fprintf(file,"s=S,"); break;
252 case NaturalStyle : fprintf(file,"s=N,"); break; 256 case NaturalStyle : fprintf(file,"s=N,"); break;
253 case ContinuousStyle : break; 257 case ContinuousStyle : break;
254 } 258 }
255 /* Save the default tempo */ 259 /* Save the default tempo */
256 fprintf(file,"b=%i:",DefNoteTempo); 260 fprintf(file,"b=%i:",DefNoteTempo);
257 dbgprintf("DefNoteTempo=%d\n", DefNoteTempo); 261 dbgprintf("DefNoteTempo=%d\n", DefNoteTempo);
258 started = true; 262 started = true;
259 firstcomma = true; 263 firstcomma = true;
260 } 264 }
261 265
262 if (!started) continue; 266 if (!started) continue;
263 267
264 if (Note->Style!=DefNoteStyle) { 268 if (Note->Style!=DefNoteStyle) {
265 /* And a separator */ 269 /* And a separator */
266 if (!firstcomma) fprintf(file,","); 270 if (!firstcomma) fprintf(file,",");
267 firstcomma = false; 271 firstcomma = false;
268 DefNoteStyle=Note->Style; 272 DefNoteStyle=Note->Style;
269 switch (Note->Style) { 273 switch (Note->Style) {
270 case StaccatoStyle : fprintf(file,"s=S"); break; 274 case StaccatoStyle : fprintf(file,"s=S"); break;
271 case NaturalStyle : fprintf(file,"s=N"); break; 275 case NaturalStyle : fprintf(file,"s=N"); break;
272 case ContinuousStyle: fprintf(file,"s=C"); break; 276 case ContinuousStyle: fprintf(file,"s=C"); break;
273 } 277 }
274 } 278 }
275 if (Note->Tempo!=DefNoteTempo) { 279 if (Note->Tempo!=DefNoteTempo) {
276 /* And a separator */ 280 /* And a separator */
277 if (!firstcomma) fprintf(file,","); 281 if (!firstcomma) fprintf(file,",");
278 firstcomma = false; 282 firstcomma = false;
279 DefNoteTempo=Note->Tempo; 283 DefNoteTempo=Note->Tempo;
280 fprintf(file,"b=%i",DefNoteTempo); 284 fprintf(file,"b=%i",DefNoteTempo);
281 } 285 }
282 /* This note has a duration different than the default. We must save it */ 286 /* This note has a duration different than the default. We must save it */
283 if (Note->Duration!=DefNoteDuration) { 287 if (Note->Duration!=DefNoteDuration) {
284 /* And a separator */ 288 /* And a separator */
285 if (!firstcomma) fprintf(file,","); 289 if (!firstcomma) fprintf(file,",");
286 firstcomma = false; 290 firstcomma = false;
287 switch (Note->Duration) { 291 switch (Note->Duration) {
288 case Duration_Full:fprintf(file,"1"); break; 292 case Duration_Full:fprintf(file,"1"); break;
289 case Duration_1_2 :fprintf(file,"2"); break; 293 case Duration_1_2 :fprintf(file,"2"); break;
290 case Duration_1_4 :fprintf(file,"4"); break; 294 case Duration_1_4 :fprintf(file,"4"); break;
291 case Duration_1_8 :fprintf(file,"8"); break; 295 case Duration_1_8 :fprintf(file,"8"); break;
292 case Duration_1_16:fprintf(file,"16");break; 296 case Duration_1_16:fprintf(file,"16");break;
293 case Duration_1_32:fprintf(file,"32");break; 297 case Duration_1_32:fprintf(file,"32");break;
294 } 298 }
295 } else { 299 } else {
296 /* And a separator */ 300 /* And a separator */
297 if (!firstcomma) fprintf(file,","); 301 if (!firstcomma) fprintf(file,",");
298 firstcomma = false; 302 firstcomma = false;
299 } 303 }
300 /* Now save the actual note */ 304 /* Now save the actual note */
301 switch (Note->Note) { 305 switch (Note->Note) {
302 case Note_C :fprintf(file,"c");break; 306 case Note_C :fprintf(file,"c");break;
303 case Note_Cis:fprintf(file,"c#");break; 307 case Note_Cis:fprintf(file,"c#");break;
304 case Note_D :fprintf(file,"d");break; 308 case Note_D :fprintf(file,"d");break;
305 case Note_Dis:fprintf(file,"d#");break; 309 case Note_Dis:fprintf(file,"d#");break;
306 case Note_E :fprintf(file,"e");break; 310 case Note_E :fprintf(file,"e");break;
307 case Note_F :fprintf(file,"f");break; 311 case Note_F :fprintf(file,"f");break;
308 case Note_Fis:fprintf(file,"f#");break; 312 case Note_Fis:fprintf(file,"f#");break;
309 case Note_G :fprintf(file,"g");break; 313 case Note_G :fprintf(file,"g");break;
310 case Note_Gis:fprintf(file,"g#");break; 314 case Note_Gis:fprintf(file,"g#");break;
311 case Note_A :fprintf(file,"a");break; 315 case Note_A :fprintf(file,"a");break;
312 case Note_Ais:fprintf(file,"a#");break; 316 case Note_Ais:fprintf(file,"a#");break;
313 case Note_H :fprintf(file,"h");break; 317 case Note_H :fprintf(file,"h");break;
314 default :fprintf(file,"p");break; /*Pause ?*/ 318 default :fprintf(file,"p");break; /*Pause ?*/
315 } 319 }
316 switch (Note->DurationSpec) { 320 switch (Note->DurationSpec) {
317 case DottedNote : fprintf(file,".");break; 321 case DottedNote : fprintf(file,".");break;
318 default : break; 322 default : break;
319 } 323 }
320 if (Note->Note!=Note_Pause && Note->Scale != DefNoteScale) { 324 if (Note->Note!=Note_Pause && Note->Scale != DefNoteScale) {
321 fprintf(file,"%i",Note->Scale); 325 fprintf(file,"%i",Note->Scale);
322 } 326 }
323 } 327 }
324 return ERR_NONE; 328 return ERR_NONE;
325} 329}
326 330
327void saveimelody(FILE *file, GSM_Ringtone *ringtone) 331void saveimelody(FILE *file, GSM_Ringtone *ringtone)
328{ 332{
329 char Buffer[2000]; 333 char Buffer[2000];
330 int i=2000; 334 int i=2000;
331 335
332 GSM_EncodeEMSSound(*ringtone, Buffer, &i, (float)1.2, true); 336 GSM_EncodeEMSSound(*ringtone, Buffer, &i, (float)1.2, true);
333 337
334 fwrite(Buffer, 1, i, file); 338 fwrite(Buffer, 1, i, file);
335} 339}
336 340
337#ifndef ENABLE_LGPL 341#ifndef ENABLE_LGPL
338 342
339static void WriteVarLen(unsigned char* midifile, int* current, long value) 343static void WriteVarLen(unsigned char* midifile, int* current, long value)
340{ 344{
341 long buffer; 345 long buffer;
342 346
343 buffer = value & 0x7f; 347 buffer = value & 0x7f;
344 348
345 while (value >>= 7) { 349 while (value >>= 7) {
346 buffer <<= 8; 350 buffer <<= 8;
347 buffer |= 0x80; 351 buffer |= 0x80;
348 buffer += (value & 0x7f); 352 buffer += (value & 0x7f);
349 } 353 }
350 354
351 while (1) { 355 while (1) {
352 midifile[(*current)++] = (unsigned char)buffer; 356 midifile[(*current)++] = (unsigned char)buffer;
353 if (buffer & 0x80) { 357 if (buffer & 0x80) {
354 buffer >>= 8; 358 buffer >>= 8;
355 } else { 359 } else {
356 break; 360 break;
357 } 361 }
358 } 362 }
359} 363}
360 364
361#define singlepauses 365#define singlepauses
362 366
363/* FIXME: need adding tempo before each note and scale too ? */ 367/* FIXME: need adding tempo before each note and scale too ? */
364void savemid(FILE* file, GSM_Ringtone *ringtone) 368void savemid(FILE* file, GSM_Ringtone *ringtone)
365{ 369{
366 int pause = 0, current = 26, duration, i, note=0, length = 20; 370 int pause = 0, current = 26, duration, i, note=0, length = 20;
367 bool started = false; 371 bool started = false;
368 GSM_RingNote *Note; 372 GSM_RingNote *Note;
369 unsigned char midifile[3000] = { 373 unsigned char midifile[3000] = {
370 0x4D, 0x54, 0x68, 0x64, // MThd 374 0x4D, 0x54, 0x68, 0x64, // MThd
371 0x00, 0x00, 0x00, 0x06, // chunk length 375 0x00, 0x00, 0x00, 0x06, // chunk length
372 0x00, 0x00, // format 0 376 0x00, 0x00, // format 0
373 0x00, 0x01, // one track 377 0x00, 0x01, // one track
374 0x00, 0x20, // 32 per quarter note 378 0x00, 0x20, // 32 per quarter note
375 0x4D, 0x54, 0x72, 0x6B, // MTrk 379 0x4D, 0x54, 0x72, 0x6B, // MTrk
376 0x00, 0x00, 0x00, 0x00, // chunk length 380 0x00, 0x00, 0x00, 0x00, // chunk length
377 0x00, 0xFF, 0x51, 0x03, // tempo meta event 381 0x00, 0xFF, 0x51, 0x03, // tempo meta event
378 0x00, 0x00, 0x00}; // 3 bytes for us for a quarter note 382 0x00, 0x00, 0x00}; // 3 bytes for us for a quarter note
379 383
380 for (i = 0; i < ringtone->NoteTone.NrCommands; i++) { 384 for (i = 0; i < ringtone->NoteTone.NrCommands; i++) {
381 if (ringtone->NoteTone.Commands[i].Type == RING_Note) { 385 if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
382 Note = &ringtone->NoteTone.Commands[i].Note; 386 Note = &ringtone->NoteTone.Commands[i].Note;
383 if (!started) { 387 if (!started) {
384 /* readmid does not read pauses at the beginning */ 388 /* readmid does not read pauses at the beginning */
385 if (Note->Note != Note_Pause) { 389 if (Note->Note != Note_Pause) {
386 /* FIXME: we need add tempo before each note or so... */ 390 /* FIXME: we need add tempo before each note or so... */
387 long duration=60000000/Note->Tempo; 391 long duration=60000000/Note->Tempo;
388 392
389 midifile[current++] = (unsigned char)(duration >> 16); 393 midifile[current++] = (unsigned char)(duration >> 16);
390 midifile[current++] = (unsigned char)(duration >> 8); 394 midifile[current++] = (unsigned char)(duration >> 8);
391 midifile[current++] = (unsigned char)duration; 395 midifile[current++] = (unsigned char)duration;
392 396
393 started = true; 397 started = true;
394 } 398 }
395 } 399 }
396 if (!started) continue; 400 if (!started) continue;
397 duration = GSM_RingNoteGetFullDuration(*Note); 401 duration = GSM_RingNoteGetFullDuration(*Note);
398 if (Note->Note == Note_Pause) { 402 if (Note->Note == Note_Pause) {
399 pause += duration; 403 pause += duration;
400#ifdef singlepauses 404#ifdef singlepauses
401 WriteVarLen(midifile,&current,pause); 405 WriteVarLen(midifile,&current,pause);
402 pause=0; 406 pause=0;
403 midifile[current++]=0x00; // pause 407 midifile[current++]=0x00; // pause
404 midifile[current++]=0x00; 408 midifile[current++]=0x00;
405#endif 409#endif
406 } else { 410 } else {
407 if (Note->Note >= Note_C && Note->Note <= Note_H) { 411 if (Note->Note >= Note_C && Note->Note <= Note_H) {
408 note = Note->Note/16 + 12 * Note->Scale - 1; 412 note = Note->Note/16 + 12 * Note->Scale - 1;
409 } 413 }
410 414
411 WriteVarLen(midifile,&current,pause); 415 WriteVarLen(midifile,&current,pause);
412 pause=0; 416 pause=0;
413 midifile[current++]=0x90; // note on 417 midifile[current++]=0x90; // note on
414 midifile[current++]=note; 418 midifile[current++]=note;
415 midifile[current++]=0x64; // forte 419 midifile[current++]=0x64; // forte
416 420
417 WriteVarLen(midifile,&current,duration); 421 WriteVarLen(midifile,&current,duration);
418 midifile[current++]=0x80; // note off 422 midifile[current++]=0x80; // note off
419 midifile[current++]=note; 423 midifile[current++]=note;
420 midifile[current++]=0x64; 424 midifile[current++]=0x64;
421 } 425 }
422 } 426 }
423 } 427 }
424 if (pause) { 428 if (pause) {
425 WriteVarLen(midifile,&current,pause); 429 WriteVarLen(midifile,&current,pause);
426 midifile[current++]=0x00; // pause 430 midifile[current++]=0x00; // pause
427 midifile[current++]=0x00; // 431 midifile[current++]=0x00; //
428 } 432 }
429 midifile[current++] = 0x00; 433 midifile[current++] = 0x00;
430 midifile[current++] = 0xFF; // track end 434 midifile[current++] = 0xFF; // track end
431 midifile[current++] = 0x2F; 435 midifile[current++] = 0x2F;
432 midifile[current++] = 0x00; 436 midifile[current++] = 0x00;
433 midifile[length++] = (current-22) >> 8; 437 midifile[length++] = (current-22) >> 8;
434 midifile[length++] = current-22; 438 midifile[length++] = current-22;
435 439
436 fwrite(midifile,1,current,file); 440 fwrite(midifile,1,current,file);
437} 441}
438 442
439#endif 443#endif
440 444
441void saveott(FILE *file, GSM_Ringtone *ringtone) 445void saveott(FILE *file, GSM_Ringtone *ringtone)
442{ 446{
443 char Buffer[2000]; 447 char Buffer[2000];
444 int i=2000; 448 int i=2000;
445 449
446 GSM_EncodeNokiaRTTLRingtone(*ringtone, Buffer, &i); 450 GSM_EncodeNokiaRTTLRingtone(*ringtone, Buffer, &i);
447 451
448 fwrite(Buffer, 1, i, file); 452 fwrite(Buffer, 1, i, file);
449} 453}
450 454
451GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone) 455GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone)
452{ 456{
453 FILE *file; 457 FILE *file;
454 458
455 file = fopen(FileName, "wb"); 459 file = fopen(FileName, "wb");
456 if (file == NULL) return ERR_CANTOPENFILE; 460 if (file == NULL) return ERR_CANTOPENFILE;
457 461
458 switch (ringtone->Format) { 462 switch (ringtone->Format) {
459 case RING_NOTETONE: 463 case RING_NOTETONE:
460 if (strstr(FileName,".ott")) { 464 if (strstr(FileName,".ott")) {
461 saveott(file,ringtone); 465 saveott(file,ringtone);
462#ifndef ENABLE_LGPL 466#ifndef ENABLE_LGPL
463 } else if (strstr(FileName,".mid")) { 467 } else if (strstr(FileName,".mid")) {
464 savemid(file,ringtone); 468 savemid(file,ringtone);
465#endif 469#endif
466 } else if (strstr(FileName,".rng")) { 470 } else if (strstr(FileName,".rng")) {
467 saveott(file,ringtone); 471 saveott(file,ringtone);
468 } else if (strstr(FileName,".imy")) { 472 } else if (strstr(FileName,".imy")) {
469 saveimelody(file,ringtone); 473 saveimelody(file,ringtone);
470 } else if (strstr(FileName,".ime")) { 474 } else if (strstr(FileName,".ime")) {
471 saveimelody(file,ringtone); 475 saveimelody(file,ringtone);
472 } else if (strstr(FileName,".wav")) { 476 } else if (strstr(FileName,".wav")) {
473 savewav(file,ringtone); 477 savewav(file,ringtone);
474 } else { 478 } else {
475 saverttl(file, ringtone); 479 saverttl(file, ringtone);
476 } 480 }
477 break; 481 break;
478 case RING_NOKIABINARY: 482 case RING_NOKIABINARY:
479 savebin(file, ringtone); 483 savebin(file, ringtone);
480 break; 484 break;
481 case RING_MIDI: 485 case RING_MIDI:
482 savepuremidi(file, ringtone); 486 savepuremidi(file, ringtone);
483 break; 487 break;
484 } 488 }
485 489
486 fclose(file); 490 fclose(file);
487 491
488 return ERR_NONE; 492 return ERR_NONE;
489} 493}
490 494
491static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone) 495static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone)
492{ 496{
493 GSM_RingNoteScale DefNoteScale= Scale_880; 497 GSM_RingNoteScale DefNoteScale= Scale_880;
494 GSM_RingNoteDuration DefNoteDuration= Duration_1_4; 498 GSM_RingNoteDuration DefNoteDuration= Duration_1_4;
495 GSM_RingNoteStyle DefNoteStyle= NaturalStyle; 499 GSM_RingNoteStyle DefNoteStyle= NaturalStyle;
496 int DefNoteTempo= 63, i=0; 500 int DefNoteTempo= 63, i=0;
497 501
498 unsigned char buffer[2000],Name[100]; 502 unsigned char buffer[2000],Name[100];
499 GSM_RingNote *Note; 503 GSM_RingNote *Note;
500 504
501 fread(buffer, 2000, 1, file); 505 fread(buffer, 2000, 1, file);
502 506
503 ringtone->NoteTone.NrCommands = 0; 507 ringtone->NoteTone.NrCommands = 0;
504 508
505 /* -------------- name ---------------- */ 509 /* -------------- name ---------------- */
506 while (buffer[i] != ':') { 510 while (buffer[i] != ':') {
507 if (buffer[i] == 0x00) return ERR_NONE; 511 if (buffer[i] == 0x00) return ERR_NONE;
508 i++; 512 i++;
509 } 513 }
510 if (i == 0) { 514 if (i == 0) {
511 /* This is for RTTL ringtones without name. */ 515 /* This is for RTTL ringtones without name. */
512 EncodeUnicode(ringtone->Name,"Gammu",5); 516 EncodeUnicode(ringtone->Name,"Gammu",5);
513 } else { 517 } else {
514 memcpy(Name,buffer,i); 518 memcpy(Name,buffer,i);
515 Name[i] = 0x00; 519 Name[i] = 0x00;
516 EncodeUnicode(ringtone->Name,Name,strlen(Name)); 520 EncodeUnicode(ringtone->Name,Name,strlen(Name));
517 } 521 }
518 i++; 522 i++;
519 523
520 /* --------- section with default ringtone settings ----------- */ 524 /* --------- section with default ringtone settings ----------- */
521 while(1) { 525 while(1) {
522 switch (buffer[i]) { 526 switch (buffer[i]) {
523 case ':': 527 case ':':
524 break; 528 break;
525 case 0x00: 529 case 0x00:
526 return ERR_NONE; 530 return ERR_NONE;
527 case 'd': case 'D': 531 case 'd': case 'D':
528 switch (atoi(buffer+i+2)) { 532 switch (atoi(buffer+i+2)) {
529 case 1: DefNoteDuration = Duration_Full; break; 533 case 1: DefNoteDuration = Duration_Full; break;
530 case 2: DefNoteDuration = Duration_1_2 ; break; 534 case 2: DefNoteDuration = Duration_1_2 ; break;
531 case 4: DefNoteDuration = Duration_1_4 ; break; 535 case 4: DefNoteDuration = Duration_1_4 ; break;
532 case 8: DefNoteDuration = Duration_1_8 ; break; 536 case 8: DefNoteDuration = Duration_1_8 ; break;
533 case 16: DefNoteDuration = Duration_1_16; break; 537 case 16: DefNoteDuration = Duration_1_16; break;
534 case 32: DefNoteDuration = Duration_1_32; break; 538 case 32: DefNoteDuration = Duration_1_32; break;
535 } 539 }
536 break; 540 break;
537 case 'o': case 'O': 541 case 'o': case 'O':
538 switch (atoi(buffer+i+2)) { 542 switch (atoi(buffer+i+2)) {
539 case 4: DefNoteScale = Scale_440 ; break; 543 case 4: DefNoteScale = Scale_440 ; break;
540 case 5: DefNoteScale = Scale_880 ; break; 544 case 5: DefNoteScale = Scale_880 ; break;
541 case 6: DefNoteScale = Scale_1760; break; 545 case 6: DefNoteScale = Scale_1760; break;
542 case 7: DefNoteScale = Scale_3520; break; 546 case 7: DefNoteScale = Scale_3520; break;
543 } 547 }
544 break; 548 break;
545 case 'b': case 'B': 549 case 'b': case 'B':
546 DefNoteTempo=atoi(buffer+i+2); 550 DefNoteTempo=atoi(buffer+i+2);
547 dbgprintf("Tempo = %i\n",DefNoteTempo); 551 dbgprintf("Tempo = %i\n",DefNoteTempo);
548 break; 552 break;
549 case 's': case 'S': 553 case 's': case 'S':
550 switch (buffer[i+1]) { 554 switch (buffer[i+1]) {
551 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break; 555 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break;
552 case 'N': case 'n': DefNoteStyle=NaturalStyle; break; 556 case 'N': case 'n': DefNoteStyle=NaturalStyle; break;
553 case 'S': case 's': DefNoteStyle=StaccatoStyle; break; 557 case 'S': case 's': DefNoteStyle=StaccatoStyle; break;
554 } 558 }
555 switch (buffer[i+2]) { 559 switch (buffer[i+2]) {
556 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break; 560 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break;
557 case 'N': case 'n': DefNoteStyle=NaturalStyle; break; 561 case 'N': case 'n': DefNoteStyle=NaturalStyle; break;
558 case 'S': case 's': DefNoteStyle=StaccatoStyle; break; 562 case 'S': case 's': DefNoteStyle=StaccatoStyle; break;
559 } 563 }
560 break; 564 break;
561 } 565 }
562 while (buffer[i] != ':' && buffer[i] != ',') { 566 while (buffer[i] != ':' && buffer[i] != ',') {
563 if (buffer[i] == 0x00) return ERR_NONE; 567 if (buffer[i] == 0x00) return ERR_NONE;
564 i++; 568 i++;
565 } 569 }
566 if (buffer[i] == ',') i++; 570 if (buffer[i] == ',') i++;
567 if (buffer[i] == ':') break; 571 if (buffer[i] == ':') break;
568 } 572 }
569 dbgprintf("DefNoteDuration=%d\n", DefNoteDuration); 573 dbgprintf("DefNoteDuration=%d\n", DefNoteDuration);
570 dbgprintf("DefNoteScale=%d\n", DefNoteScale); 574 dbgprintf("DefNoteScale=%d\n", DefNoteScale);
571 i++; 575 i++;
572 576
573 /* ------------------------- notes ------------------------------ */ 577 /* ------------------------- notes ------------------------------ */
574 while (buffer[i] != 0x00 && ringtone->NoteTone.NrCommands != MAX_RINGTONE_NOTES) { 578 while (buffer[i] != 0x00 && ringtone->NoteTone.NrCommands != MAX_RINGTONE_NOTES) {
575 switch(buffer[i]) { 579 switch(buffer[i]) {
576 case 'z': case 'Z': 580 case 'z': case 'Z':
577 switch (buffer[i+1]) { 581 switch (buffer[i+1]) {
578 case 'd': 582 case 'd':
579 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_DisableLED; 583 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_DisableLED;
580 ringtone->NoteTone.NrCommands++; 584 ringtone->NoteTone.NrCommands++;
581 break; 585 break;
582 case 'D': 586 case 'D':
583 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_EnableLED; 587 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_EnableLED;
584 ringtone->NoteTone.NrCommands++; 588 ringtone->NoteTone.NrCommands++;
585 break; 589 break;
586 case 'v': 590 case 'v':
587 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_DisableVibra; 591 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_DisableVibra;
588 ringtone->NoteTone.NrCommands++; 592 ringtone->NoteTone.NrCommands++;
589 break; 593 break;
590 case 'V': 594 case 'V':
591 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_EnableVibra; 595 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_EnableVibra;
592 ringtone->NoteTone.NrCommands++; 596 ringtone->NoteTone.NrCommands++;
593 break; 597 break;
594 case 'l': 598 case 'l':
595 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_DisableLight; 599 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_DisableLight;
596 ringtone->NoteTone.NrCommands++; 600 ringtone->NoteTone.NrCommands++;
597 break; 601 break;
598 case 'L': 602 case 'L':
599 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_EnableLight; 603 ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_EnableLight;
600 ringtone->NoteTone.NrCommands++; 604 ringtone->NoteTone.NrCommands++;
601 } 605 }
602 break; 606 break;
603 case 'o': case 'O': 607 case 'o': case 'O':
604 switch (buffer[i+2]) { 608 switch (buffer[i+2]) {
605 case 4: DefNoteScale = Scale_440 ; break; 609 case 4: DefNoteScale = Scale_440 ; break;
606 case 5: DefNoteScale = Scale_880 ; break; 610 case 5: DefNoteScale = Scale_880 ; break;
607 case 6: DefNoteScale = Scale_1760; break; 611 case 6: DefNoteScale = Scale_1760; break;
608 case 7: DefNoteScale = Scale_3520; break; 612 case 7: DefNoteScale = Scale_3520; break;
609 } 613 }
610 break; 614 break;
611 case 's': case 'S': 615 case 's': case 'S':
612 switch (buffer[i+1]) { 616 switch (buffer[i+1]) {
613 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break; 617 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break;
614 case 'N': case 'n': DefNoteStyle=NaturalStyle; break; 618 case 'N': case 'n': DefNoteStyle=NaturalStyle; break;
615 case 'S': case 's': DefNoteStyle=StaccatoStyle; break; 619 case 'S': case 's': DefNoteStyle=StaccatoStyle; break;
616 } 620 }
617 switch (buffer[i+2]) { 621 switch (buffer[i+2]) {
618 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break; 622 case 'C': case 'c': DefNoteStyle=ContinuousStyle;break;
619 case 'N': case 'n': DefNoteStyle=NaturalStyle; break; 623 case 'N': case 'n': DefNoteStyle=NaturalStyle; break;
620 case 'S': case 's': DefNoteStyle=StaccatoStyle; break; 624 case 'S': case 's': DefNoteStyle=StaccatoStyle; break;