-rw-r--r-- | core/applets/vmemo/vmemo.cpp | 182 |
1 files changed, 94 insertions, 88 deletions
diff --git a/core/applets/vmemo/vmemo.cpp b/core/applets/vmemo/vmemo.cpp index 73bd996..83f19f5 100644 --- a/core/applets/vmemo/vmemo.cpp +++ b/core/applets/vmemo/vmemo.cpp | |||
@@ -21,35 +21,37 @@ | |||
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <fcntl.h> | 23 | #include <fcntl.h> |
24 | #include <sys/ioctl.h> | 24 | #include <sys/ioctl.h> |
25 | #include <linux/soundcard.h> | 25 | #include <linux/soundcard.h> |
26 | #include <string.h> | 26 | #include <string.h> |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | 28 | ||
29 | typedef struct _waveheader { | 29 | typedef struct _waveheader { |
30 | u_long main_chunk; /* 'RIFF' */ | 30 | u_long main_chunk; /* 'RIFF' */ |
31 | u_long length; /* filelen */ | 31 | u_long length; /* filelen */ |
32 | u_long chunk_type; /* 'WAVE' */ | 32 | u_long chunk_type; /* 'WAVE' */ |
33 | |||
34 | u_long sub_chunk; /* 'fmt ' */ | 33 | u_long sub_chunk; /* 'fmt ' */ |
35 | u_long sc_len; /* length of sub_chunk, =16 (chunckSize) */ | 34 | u_long sc_len; /* length of sub_chunk, =16 |
35 | (chunckSize) format len */ | ||
36 | u_short format; /* should be 1 for PCM-code (formatTag) */ | 36 | u_short format; /* should be 1 for PCM-code (formatTag) */ |
37 | |||
37 | u_short modus; /* 1 Mono, 2 Stereo (channels) */ | 38 | u_short modus; /* 1 Mono, 2 Stereo (channels) */ |
38 | u_long sample_fq; /* samples per second (samplesPerSecond) */ | 39 | u_long sample_fq; /* samples per second (samplesPerSecond) */ |
39 | u_long byte_p_sec; /* avg bytes per second (avgBytePerSecond) */ | 40 | u_long byte_p_sec; /* avg bytes per second (avgBytePerSecond) */ |
40 | u_short byte_p_spl; /* samplesize; 1 or 2 bytes (blockAlign) */ | 41 | u_short byte_p_spl; /* samplesize; 1 or 2 bytes (blockAlign) */ |
41 | u_short bit_p_spl; /* 8, 12 or 16 bit (bitsPerSample) */ | 42 | u_short bit_p_spl; /* 8, 12 or 16 bit (bitsPerSample) */ |
42 | 43 | ||
43 | u_long data_chunk; /* 'data' */ | 44 | u_long data_chunk; /* 'data' */ |
45 | |||
44 | u_long data_length;/* samplecount */ | 46 | u_long data_length;/* samplecount */ |
45 | } WaveHeader; | 47 | } WaveHeader; |
46 | 48 | ||
47 | #define RIFF 0x46464952 | 49 | #define RIFF 0x46464952 |
48 | #define WAVE 0x45564157 | 50 | #define WAVE 0x45564157 |
49 | #define FMT 0x20746D66 | 51 | #define FMT 0x20746D66 |
50 | #define DATA 0x61746164 | 52 | #define DATA 0x61746164 |
51 | #define PCM_CODE 1 | 53 | #define PCM_CODE 1 |
52 | #define WAVE_MONO 1 | 54 | #define WAVE_MONO 1 |
53 | #define WAVE_STEREO 2 | 55 | #define WAVE_STEREO 2 |
54 | 56 | ||
55 | #include "vmemo.h" | 57 | #include "vmemo.h" |
@@ -131,97 +133,97 @@ static char * vmemo_xpm[] = { | |||
131 | " h0,!_;2@ ", | 133 | " h0,!_;2@ ", |
132 | " ))))) "}; | 134 | " ))))) "}; |
133 | 135 | ||
134 | VMemo::VMemo( QWidget *parent, const char *name ) | 136 | VMemo::VMemo( QWidget *parent, const char *name ) |
135 | : QWidget( parent, name ) | 137 | : QWidget( parent, name ) |
136 | { | 138 | { |
137 | setFixedHeight( 18 ); | 139 | setFixedHeight( 18 ); |
138 | setFixedWidth( 14 ); | 140 | setFixedWidth( 14 ); |
139 | 141 | ||
140 | recording = FALSE; | 142 | recording = FALSE; |
141 | 143 | ||
142 | struct utsname name; /* check for embedix kernel running on the zaurus, if | 144 | struct utsname name; /* check for embedix kernel running on the zaurus, if |
143 | lineo change string, this break | 145 | lineo change string, this break |
144 | */ | 146 | */ |
145 | if (uname(&name) != -1) | 147 | if (uname(&name) != -1) |
146 | { | 148 | { |
147 | QString release=name.release; | 149 | QString release=name.release; |
148 | qWarning("System release: %s\n", name.release); | 150 | qWarning("System release: %s\n", name.release); |
149 | if(release.find("embedix",0,TRUE) !=-1) | 151 | if(release.find("embedix",0,TRUE) !=-1) |
150 | systemZaurus=TRUE; | 152 | systemZaurus=TRUE; |
151 | else | 153 | else |
152 | systemZaurus=FALSE; | 154 | systemZaurus=FALSE; |
153 | } | 155 | } |
154 | 156 | ||
155 | } | 157 | } |
156 | 158 | ||
157 | VMemo::~VMemo() | 159 | VMemo::~VMemo() |
158 | { | 160 | { |
159 | } | 161 | } |
160 | 162 | ||
161 | void VMemo::paintEvent( QPaintEvent* ) | 163 | void VMemo::paintEvent( QPaintEvent* ) |
162 | { | 164 | { |
163 | QPainter p(this); | 165 | QPainter p(this); |
164 | p.drawPixmap( 0, 1,( const char** ) vmemo_xpm ); | 166 | p.drawPixmap( 0, 1,( const char** ) vmemo_xpm ); |
165 | } | 167 | } |
166 | 168 | ||
167 | void VMemo::mousePressEvent( QMouseEvent * ) | 169 | void VMemo::mousePressEvent( QMouseEvent * ) |
168 | { | 170 | { |
169 | // just to be safe | 171 | // just to be safe |
170 | if (recording) | 172 | if (recording) |
171 | { | 173 | { |
172 | recording = FALSE; | 174 | recording = FALSE; |
173 | return; | 175 | return; |
174 | } | 176 | } |
175 | 177 | ||
176 | qWarning("VMemo::mousePress()"); | 178 | qWarning("VMemo::mousePress()"); |
177 | QSound::play(Resource::findSound("vmemob")); | 179 | QSound::play(Resource::findSound("vmemob")); |
178 | 180 | ||
179 | recording = TRUE; | 181 | recording = TRUE; |
180 | qWarning("VMemo::mousePress() -> Starting to record"); | 182 | qWarning("VMemo::mousePress() -> Starting to record"); |
181 | if (openDSP() == -1) | 183 | if (openDSP() == -1) |
182 | { | 184 | { |
183 | // ### Display an error box | 185 | // ### Display an error box |
184 | QMessageBox::critical(0, "VMemo", "Could not open dsp device.", "Abort"); | 186 | QMessageBox::critical(0, "VMemo", "Could not open dsp device.", "Abort"); |
185 | recording = FALSE; | 187 | recording = FALSE; |
186 | return; | 188 | return; |
187 | } | 189 | } |
188 | 190 | ||
189 | Config vmCfg("VMemo"); | 191 | Config vmCfg("VMemo"); |
190 | vmCfg.setGroup("Defaults"); | 192 | vmCfg.setGroup("Defaults"); |
191 | 193 | ||
192 | QDateTime dt = QDateTime::currentDateTime(); | 194 | QDateTime dt = QDateTime::currentDateTime(); |
193 | QString fileName; | 195 | QString fileName; |
194 | if(systemZaurus) | 196 | if(systemZaurus) |
195 | fileName=vmCfg.readEntry("Dir", "/mnt/cf/"); // zaurus does not have /mnt/ramfs | 197 | fileName=vmCfg.readEntry("Dir", "/mnt/cf/"); // zaurus does not have /mnt/ramfs |
196 | else | 198 | else |
197 | fileName=vmCfg.readEntry("Dir", "/mnt/ramfs/"); | 199 | fileName=vmCfg.readEntry("Dir", "/mnt/ramfs/"); |
198 | 200 | ||
199 | fileName += "vm_"; | 201 | fileName += "vm_"; |
200 | fileName += dt.toString(); | 202 | fileName += dt.toString(); |
201 | fileName += ".wav"; | 203 | fileName += ".wav"; |
202 | 204 | ||
203 | // No spaces in the filename | 205 | // No spaces in the filename |
204 | fileName.replace(QRegExp("'"),""); | 206 | fileName.replace(QRegExp("'"),""); |
205 | fileName.replace(QRegExp(" "),"_"); | 207 | fileName.replace(QRegExp(" "),"_"); |
206 | fileName.replace(QRegExp(":"),"."); | 208 | fileName.replace(QRegExp(":"),"."); |
207 | fileName.replace(QRegExp(","),""); | 209 | fileName.replace(QRegExp(","),""); |
208 | 210 | ||
209 | if(openWAV(fileName.latin1()) == -1) | 211 | if(openWAV(fileName.latin1()) == -1) |
210 | { | 212 | { |
211 | // ### Display an error box | 213 | // ### Display an error box |
212 | qWarning("VMemo::mousePress() -> WAV error"); | 214 | qWarning("VMemo::mousePress() -> WAV error"); |
213 | close(dsp); | 215 | close(dsp); |
214 | return; | 216 | return; |
215 | } | 217 | } |
216 | 218 | ||
217 | QArray<int> cats(1); | 219 | QArray<int> cats(1); |
218 | cats[0] = vmCfg.readNumEntry("Category", 0); | 220 | cats[0] = vmCfg.readNumEntry("Category", 0); |
219 | 221 | ||
220 | QString dlName("vm_"); | 222 | QString dlName("vm_"); |
221 | dlName += dt.toString(); | 223 | dlName += dt.toString(); |
222 | DocLnk l; | 224 | DocLnk l; |
223 | l.setFile(fileName); | 225 | l.setFile(fileName); |
224 | l.setName(dlName); | 226 | l.setName(dlName); |
225 | l.setType("audio/x-wav"); | 227 | l.setType("audio/x-wav"); |
226 | l.setCategories(cats); | 228 | l.setCategories(cats); |
227 | l.writeLink(); | 229 | l.writeLink(); |
@@ -233,128 +235,132 @@ void VMemo::mouseReleaseEvent( QMouseEvent * ) | |||
233 | { | 235 | { |
234 | qWarning("VMemo::mouseRelese() -> Done recording"); | 236 | qWarning("VMemo::mouseRelese() -> Done recording"); |
235 | recording = FALSE; | 237 | recording = FALSE; |
236 | } | 238 | } |
237 | 239 | ||
238 | int VMemo::openDSP() | 240 | int VMemo::openDSP() |
239 | { | 241 | { |
240 | Config cfg("Sound"); | 242 | Config cfg("Sound"); |
241 | cfg.setGroup("Record"); | 243 | cfg.setGroup("Record"); |
242 | 244 | ||
243 | speed = cfg.readNumEntry("SampleRate", 11025); | 245 | speed = cfg.readNumEntry("SampleRate", 11025); |
244 | channels = cfg.readNumEntry("Stereo", 1) ? 2 : 1; // 1 = stereo(2), 0 = mono(1) | 246 | channels = cfg.readNumEntry("Stereo", 1) ? 2 : 1; // 1 = stereo(2), 0 = mono(1) |
245 | if (cfg.readNumEntry("SixteenBit", 1)) | 247 | if (cfg.readNumEntry("SixteenBit", 1)==1) |
246 | { | 248 | { |
247 | format = AFMT_S16_LE; | 249 | format = AFMT_S16_LE; |
248 | resolution = 16; | 250 | resolution = 16; |
249 | } | 251 | } |
250 | else | 252 | else |
251 | { | 253 | { |
252 | format = AFMT_U8; | 254 | format = AFMT_U8; |
253 | resolution = 8; | 255 | resolution = 8; |
254 | } | 256 | } |
255 | 257 | ||
256 | if(systemZaurus) | 258 | if(systemZaurus) |
257 | dsp = open("/dev/dsp1", O_RDWR); //Zaurus needs /dev/dsp1 | 259 | { |
260 | dsp = open("/dev/dsp1", O_RDWR); //Zaurus needs /dev/dsp1 | ||
261 | channels=1; //zaurus has one input channel | ||
262 | } | ||
258 | else | 263 | else |
259 | dsp = open("/dev/dsp", O_RDWR); | 264 | dsp = open("/dev/dsp", O_RDWR); |
260 | 265 | ||
261 | if(dsp == -1) | 266 | if(dsp == -1) |
262 | { | 267 | { |
263 | perror("open(\"/dev/dsp\")"); | 268 | perror("open(\"/dev/dsp\")"); |
264 | return -1; | 269 | return -1; |
265 | } | 270 | } |
266 | 271 | ||
267 | if(ioctl(dsp, SNDCTL_DSP_SETFMT , &format)==-1) | 272 | if(ioctl(dsp, SNDCTL_DSP_SETFMT , &format)==-1) |
268 | { | 273 | { |
269 | perror("ioctl(\"SNDCTL_DSP_SETFMT\")"); | 274 | perror("ioctl(\"SNDCTL_DSP_SETFMT\")"); |
270 | return -1; | 275 | return -1; |
271 | } | 276 | } |
272 | if(ioctl(dsp, SNDCTL_DSP_CHANNELS , &channels)==-1) | 277 | if(ioctl(dsp, SNDCTL_DSP_CHANNELS , &channels)==-1) |
273 | { | 278 | { |
274 | perror("ioctl(\"SNDCTL_DSP_CHANNELS\")"); | 279 | perror("ioctl(\"SNDCTL_DSP_CHANNELS\")"); |
275 | return -1; | 280 | return -1; |
276 | } | 281 | } |
277 | if(ioctl(dsp, SNDCTL_DSP_SPEED , &speed)==-1) | 282 | if(ioctl(dsp, SNDCTL_DSP_SPEED , &speed)==-1) |
278 | { | 283 | { |
279 | perror("ioctl(\"SNDCTL_DSP_SPEED\")"); | 284 | perror("ioctl(\"SNDCTL_DSP_SPEED\")"); |
280 | return -1; | 285 | return -1; |
281 | } | 286 | } |
282 | if(ioctl(dsp, SOUND_PCM_READ_RATE , &rate)==-1) | 287 | if(ioctl(dsp, SOUND_PCM_READ_RATE , &rate)==-1) |
283 | { | 288 | { |
284 | perror("ioctl(\"SOUND_PCM_READ_RATE\")"); | 289 | perror("ioctl(\"SOUND_PCM_READ_RATE\")"); |
285 | return -1; | 290 | return -1; |
286 | } | 291 | } |
287 | 292 | ||
288 | return 1; | 293 | return 1; |
289 | } | 294 | } |
290 | 295 | ||
291 | int VMemo::openWAV(const char *filename) | 296 | int VMemo::openWAV(const char *filename) |
292 | { | 297 | { |
293 | qDebug("Creating %s ",filename); | 298 | qDebug("Creating %s ",filename); |
294 | track.setName(filename); | 299 | track.setName(filename); |
295 | if(!track.open(IO_WriteOnly|IO_Truncate|IO_Raw)) | 300 | if(!track.open(IO_WriteOnly|IO_Truncate|IO_Raw)) |
296 | { | 301 | { |
297 | qDebug("Could not open file"); | 302 | qDebug("Could not open file"); |
298 | return -1; | 303 | return -1; |
299 | } | 304 | } |
300 | wav=track.handle(); | 305 | wav=track.handle(); |
301 | 306 | ||
302 | WaveHeader wh; | 307 | WaveHeader wh; |
303 | 308 | ||
304 | wh.main_chunk = RIFF; | 309 | wh.main_chunk = RIFF;// RIFF |
305 | wh.length = 0; | 310 | wh.chunk_type = WAVE;//WAVE |
306 | wh.chunk_type = WAVE; | 311 | wh.sub_chunk = FMT;// fmt |
307 | 312 | wh.sc_len = 16;// format length = 16 | |
308 | wh.sub_chunk = FMT; | 313 | wh.format = PCM_CODE;// PCM |
309 | wh.sc_len = 16; | 314 | wh.modus = channels;// channels |
310 | wh.format = PCM_CODE; | 315 | wh.sample_fq = speed;//samplerate |
311 | wh.modus = channels; | 316 | wh.byte_p_sec = speed * channels * resolution/8;// av bytes per second |
312 | wh.sample_fq = speed; | 317 | wh.byte_p_spl = channels * (resolution / 8); //block align |
313 | wh.bit_p_spl = resolution; | 318 | wh.bit_p_spl = resolution;//bits per sample 8, or 16 |
314 | wh.byte_p_sec = wh.sample_fq * wh.bit_p_spl; | ||
315 | wh.byte_p_spl = channels * (wh.bit_p_spl % 8); | ||
316 | |||
317 | wh.data_chunk = DATA; | 319 | wh.data_chunk = DATA; |
318 | wh.data_length= 0; | 320 | wh.data_length= 0; // <--- |
319 | 321 | // qDebug("Write header channels %d, speed %d, b/s %d, blockalign %d, bitrate %d" | |
322 | // , wh.modus, wh.sample_fq, wh.byte_p_sec, wh.byte_p_spl, wh.bit_p_spl ); | ||
320 | write (wav, &wh, sizeof(WaveHeader)); | 323 | write (wav, &wh, sizeof(WaveHeader)); |
321 | 324 | ||
322 | return 1; | 325 | return 1; |
323 | } | 326 | } |
324 | 327 | ||
325 | void VMemo::record(void) | 328 | void VMemo::record(void) |
326 | { | 329 | { |
327 | int length=0, result, value; | 330 | int length=0, result, value; |
328 | char sound[8192]; | 331 | char sound[8192]; |
329 | 332 | ||
330 | qWarning("VMemo::record()"); | 333 | qWarning("VMemo::record()"); |
331 | 334 | ||
332 | while(recording) | 335 | while(recording) |
333 | { | 336 | { |
334 | result = read(dsp, sound, 512); // 8192 | 337 | result = read(dsp, sound, 512); // 8192 |
335 | qApp->processEvents(); | 338 | qApp->processEvents(); |
336 | write(wav, sound, result); | 339 | write(wav, sound, result); |
337 | qApp->processEvents(); | 340 | qApp->processEvents(); |
338 | length += result; | 341 | length += result; |
339 | qApp->processEvents(); | 342 | qApp->processEvents(); |
340 | } | 343 | // printf("%d\r",length); |
344 | // fflush(stdout); | ||
345 | } | ||
341 | 346 | ||
342 | qWarning("VMemo::record() -> Done recording"); | 347 | qWarning("VMemo::record() -> Done recording"); |
343 | qWarning("VMemo::record() -> Closing dsp"); | 348 | qWarning("VMemo::record() -> Closing dsp"); |
344 | 349 | ||
345 | value = length+36; | 350 | value = length+36; |
346 | lseek(wav, 4, SEEK_SET); | 351 | lseek(wav, 4, SEEK_SET); |
347 | write(wav, &value, 4); | 352 | write(wav, &value, 4); |
348 | lseek(wav, 40, SEEK_SET); | 353 | lseek(wav, 40, SEEK_SET); |
349 | write(wav, &length, 4); | 354 | write(wav, &length, 4); |
355 | // qDebug("File length %d, samplecount %d", value, length); | ||
350 | track.close(); | 356 | track.close(); |
351 | 357 | ||
352 | if( ioctl( dsp, SNDCTL_DSP_RESET,0) == -1)// ); //tell driver to stop for a while | 358 | if( ioctl( dsp, SNDCTL_DSP_RESET,0) == -1)// ); //tell driver to stop for a while |
353 | perror("ioctl(\"SNDCTL_DSP_RESET\")"); | 359 | perror("ioctl(\"SNDCTL_DSP_RESET\")"); |
354 | ::close(dsp); | 360 | ::close(dsp); |
355 | 361 | ||
356 | qWarning("VMemo::record() -> playing done recording sound"); | 362 | qWarning("VMemo::record() -> playing done recording sound"); |
357 | QSound::play(Resource::findSound("vmemoe")); | 363 | QSound::play(Resource::findSound("vmemoe")); |
358 | qWarning("VMemo::record() -> terminating"); | 364 | qWarning("VMemo::record() -> terminating"); |
359 | QMessageBox::information(0, "VMemo", "Recording Done", 1); | 365 | QMessageBox::information(0, "VMemo", "Recording Done", 1); |
360 | } | 366 | } |