-rw-r--r-- | gammu/emb/common/common.pro | 1 | ||||
-rw-r--r-- | gammu/emb/common/service/gsmring.c | 6 |
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 | ||
5 | TEMPLATE = lib | 5 | TEMPLATE = lib |
6 | DEPENDPATH += device \ | 6 | DEPENDPATH += 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 |
29 | INCLUDEPATH += . \ | 29 | INCLUDEPATH += . \ |
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 |
55 | HEADERS += config.h \ | 55 | HEADERS += 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 |
119 | SOURCES +=gsmcomon.c \ | 119 | SOURCES +=gsmcomon.c \ |
120 | gsmstate.c \ | 120 | gsmstate.c \ |
121 | misc/misc.c \ | 121 | misc/misc.c \ |
122 | misc/cfg.c \ | 122 | misc/cfg.c \ |
123 | misc/coding/coding.c \ | 123 | misc/coding/coding.c \ |
124 | misc/coding/md5.c \ | 124 | misc/coding/md5.c \ |
125 | service/sms/gsmsms.c \ | 125 | service/sms/gsmsms.c \ |
126 | service/sms/gsmems.c \ | 126 | service/sms/gsmems.c \ |
127 | service/sms/gsmmulti.c \ | 127 | service/sms/gsmmulti.c \ |
128 | service/gsmcal.c \ | 128 | service/gsmcal.c \ |
129 | service/gsmdata.c \ | 129 | service/gsmdata.c \ |
130 | service/gsmpbk.c \ | 130 | service/gsmpbk.c \ |
131 | service/gsmring.c \ | 131 | service/gsmring.c \ |
132 | service/gsmlogo.c \ | 132 | service/gsmlogo.c \ |
133 | service/gsmmisc.c \ | 133 | service/gsmmisc.c \ |
134 | service/gsmnet.c \ | 134 | service/gsmnet.c \ |
135 | service/backup/gsmback.c \ | 135 | service/backup/gsmback.c \ |
136 | service/backup/backldif.c \ | 136 | service/backup/backldif.c \ |
137 | service/backup/backlmb.c \ | 137 | service/backup/backlmb.c \ |
138 | service/backup/backtext.c \ | 138 | service/backup/backtext.c \ |
139 | service/backup/backvcs.c \ | 139 | service/backup/backvcs.c \ |
140 | service/backup/backvcf.c \ | 140 | service/backup/backvcf.c \ |
141 | service/backup/backics.c \ | 141 | service/backup/backics.c \ |
142 | device/bluetoth/affix.c \ | 142 | device/bluetoth/affix.c \ |
143 | device/bluetoth/bluez.c \ | 143 | device/bluetoth/bluez.c \ |
144 | device/bluetoth/blue_w32.c \ | 144 | device/bluetoth/blue_w32.c \ |
145 | device/bluetoth/bluetoth.c \ | 145 | device/bluetoth/bluetoth.c \ |
146 | device/serial/ser_djg.c \ | 146 | device/serial/ser_djg.c \ |
147 | device/irda/irda.c \ | 147 | device/irda/irda.c \ |
148 | device/devfunc.c \ | 148 | device/devfunc.c \ |
149 | protocol/at/at.c \ | 149 | protocol/at/at.c \ |
150 | protocol/alcatel/alcabus.c \ | 150 | protocol/alcatel/alcabus.c \ |
151 | protocol/nokia/mbus2.c \ | 151 | protocol/nokia/mbus2.c \ |
152 | protocol/nokia/fbus2.c \ | 152 | protocol/nokia/fbus2.c \ |
153 | protocol/nokia/phonet.c \ | 153 | protocol/nokia/phonet.c \ |
154 | protocol/obex/obex.c \ | 154 | protocol/obex/obex.c \ |
155 | protocol/symbian/mrouter.c \ | 155 | protocol/symbian/mrouter.c \ |
156 | phone/pfunc.c \ | 156 | phone/pfunc.c \ |
157 | phone/at/atgen.c \ | 157 | phone/at/atgen.c \ |
158 | phone/at/siemens.c \ | 158 | phone/at/siemens.c \ |
159 | phone/at/sonyeric.c \ | 159 | phone/at/sonyeric.c \ |
160 | phone/alcatel/alcatel.c \ | 160 | phone/alcatel/alcatel.c \ |
161 | phone/nokia/dct3/n6110.c \ | 161 | phone/nokia/dct3/n6110.c \ |
162 | phone/nokia/dct3/n7110.c \ | 162 | phone/nokia/dct3/n7110.c \ |
163 | phone/nokia/dct3/n9210.c \ | 163 | phone/nokia/dct3/n9210.c \ |
164 | phone/nokia/dct3/dct3func.c \ | 164 | phone/nokia/dct3/dct3func.c \ |
165 | phone/nokia/dct4/n3320.c \ | 165 | phone/nokia/dct4/n3320.c \ |
166 | phone/nokia/dct4/n3650.c \ | 166 | phone/nokia/dct4/n3650.c \ |
167 | phone/nokia/dct4/n6510.c \ | 167 | phone/nokia/dct4/n6510.c \ |
168 | phone/nokia/dct4/dct4func.c \ | 168 | phone/nokia/dct4/dct4func.c \ |
169 | phone/nokia/nauto.c \ | 169 | phone/nokia/nauto.c \ |
170 | phone/nokia/nfunc.c \ | 170 | phone/nokia/nfunc.c \ |
171 | phone/nokia/nfuncold.c \ | 171 | phone/nokia/nfuncold.c \ |
172 | phone/obex/obexgen.c \ | 172 | phone/obex/obexgen.c \ |
173 | phone/symbian/mroutgen.c | 173 | phone/symbian/mroutgen.c |
174 | 174 | ||
175 | DEFINES += DESKTOP_VERSION | ||
175 | TARGET = microgammu | 176 | TARGET = microgammu |
176 | CONFIG = warn_off release console | 177 | CONFIG = warn_off release console |
177 | DESTDIR = ../../../bin | 178 | DESTDIR = ../../../bin |
178 | OBJECTS_DIR = obj/unix | 179 | OBJECTS_DIR = obj/unix |
179 | MOC_DIR = moc/unix | 180 | MOC_DIR = moc/unix |
180 | 181 | ||
181 | unix: { | 182 | unix: { |
182 | SOURCES += device/serial/ser_unx.c | 183 | SOURCES += device/serial/ser_unx.c |
183 | } | 184 | } |
184 | win32:{ | 185 | win32:{ |
185 | SOURCES += device/serial/ser_w32.c | 186 | SOURCES += 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 | ||
20 | int GSM_RingNoteGetFrequency(GSM_RingNote Note) | 20 | int 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 | ||
53 | int GSM_RingNoteGetFullDuration(GSM_RingNote Note) | 53 | int 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 | ||
80 | GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone) | 80 | GSM_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 | ||
135 | static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone) | 139 | static 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 | ||
149 | static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone) | 153 | static 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 | ||
155 | GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone) | 159 | GSM_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 | ||
327 | void saveimelody(FILE *file, GSM_Ringtone *ringtone) | 331 | void 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 | ||
339 | static void WriteVarLen(unsigned char* midifile, int* current, long value) | 343 | static 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 ? */ |
364 | void savemid(FILE* file, GSM_Ringtone *ringtone) | 368 | void 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,¤t,pause); | 405 | WriteVarLen(midifile,¤t,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,¤t,pause); | 415 | WriteVarLen(midifile,¤t,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,¤t,duration); | 421 | WriteVarLen(midifile,¤t,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,¤t,pause); | 429 | WriteVarLen(midifile,¤t,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 | ||
441 | void saveott(FILE *file, GSM_Ringtone *ringtone) | 445 | void 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 | ||
451 | GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone) | 455 | GSM_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 | ||
491 | static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone) | 495 | static 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; |