summaryrefslogtreecommitdiff
path: root/core/applets/vmemo/vmemo.cpp
Unidiff
Diffstat (limited to 'core/applets/vmemo/vmemo.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/applets/vmemo/vmemo.cpp262
1 files changed, 157 insertions, 105 deletions
diff --git a/core/applets/vmemo/vmemo.cpp b/core/applets/vmemo/vmemo.cpp
index 48dd193..9d69130 100644
--- a/core/applets/vmemo/vmemo.cpp
+++ b/core/applets/vmemo/vmemo.cpp
@@ -1,64 +1,64 @@
1/************************************************************************************ 1/************************************************************************************
2** 2**
3** This file may be distributed and/or modified under the terms of the 3** This file may be distributed and/or modified under the terms of the
4** GNU General Public License version 2 as published by the Free Software 4** GNU General Public License version 2 as published by the Free Software
5** Foundation and appearing in the file LICENSE.GPL included in the 5** Foundation and appearing in the file LICENSE.GPL included in the
6** packaging of this file. 6** packaging of this file.
7** 7**
8** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 8** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
9** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 9** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
10** 10**
11************************************************************************************/ 11************************************************************************************/
12 12
13/* 13/*
14 * $Id$ 14 * $Id$
15 */ 15 */
16 16// Sun 03-17-2002 L.J.Potter <ljp@llornkcor.com>
17#include <sys/utsname.h> 17#include <sys/utsname.h>
18#include <sys/time.h> 18#include <sys/time.h>
19#include <sys/types.h> 19#include <sys/types.h>
20#include <unistd.h> 20#include <unistd.h>
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
29typedef struct _waveheader { 29typedef 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 u_long sub_chunk; /* 'fmt ' */ 33 u_long sub_chunk; /* 'fmt ' */
34 u_long sc_len; /* length of sub_chunk, =16 34 u_long sc_len; /* length of sub_chunk, =16
35 (chunckSize) format len */ 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
38 u_short modus; /* 1 Mono, 2 Stereo (channels) */ 38 u_short modus; /* 1 Mono, 2 Stereo (channels) */
39 u_long sample_fq; /* samples per second (samplesPerSecond) */ 39 u_long sample_fq; /* samples per second (samplesPerSecond) */
40 u_long byte_p_sec; /* avg bytes per second (avgBytePerSecond) */ 40 u_long byte_p_sec; /* avg bytes per second (avgBytePerSecond) */
41 u_short byte_p_spl; /* samplesize; 1 or 2 bytes (blockAlign) */ 41 u_short byte_p_spl; /* samplesize; 1 or 2 bytes (blockAlign) */
42 u_short bit_p_spl; /* 8, 12 or 16 bit (bitsPerSample) */ 42 u_short bit_p_spl; /* 8, 12 or 16 bit (bitsPerSample) */
43 43
44 u_long data_chunk; /* 'data' */ 44 u_long data_chunk; /* 'data' */
45 45
46 u_long data_length;/* samplecount */ 46 u_long data_length;/* samplecount */
47} WaveHeader; 47} WaveHeader;
48 48
49#define RIFF 0x46464952 49#define RIFF 0x46464952
50#define WAVE 0x45564157 50#define WAVE 0x45564157
51#define FMT 0x20746D66 51#define FMT 0x20746D66
52#define DATA 0x61746164 52#define DATA 0x61746164
53#define PCM_CODE 1 53#define PCM_CODE 1
54#define WAVE_MONO 1 54#define WAVE_MONO 1
55#define WAVE_STEREO 2 55#define WAVE_STEREO 2
56 56
57#include "vmemo.h" 57#include "vmemo.h"
58 58
59#include <qpe/qpeapplication.h> 59#include <qpe/qpeapplication.h>
60#include <qpe/resource.h> 60#include <qpe/resource.h>
61#include <qpe/config.h> 61#include <qpe/config.h>
62 62
63#include <qpainter.h> 63#include <qpainter.h>
64#include <qdatetime.h> 64#include <qdatetime.h>
@@ -96,287 +96,339 @@ static char * vmemo_xpm[] = {
96"( c #4C4C4C", 96"( c #4C4C4C",
97"_ c #353535", 97"_ c #353535",
98": c #0E0E0E", 98": c #0E0E0E",
99"< c #080808", 99"< c #080808",
100"[ c #262626", 100"[ c #262626",
101"} c #121212", 101"} c #121212",
102"| c #7F7F7F", 102"| c #7F7F7F",
103"1 c #464646", 103"1 c #464646",
104"2 c #0C0C0C", 104"2 c #0C0C0C",
105"3 c #727272", 105"3 c #727272",
106"4 c #292929", 106"4 c #292929",
107"5 c #656565", 107"5 c #656565",
108"6 c #565656", 108"6 c #565656",
109"7 c #434343", 109"7 c #434343",
110"8 c #272727", 110"8 c #272727",
111"9 c #0F0F0F", 111"9 c #0F0F0F",
112"0 c #3A3A3A", 112"0 c #3A3A3A",
113"a c #090909", 113"a c #090909",
114"b c #535353", 114"b c #535353",
115"c c #545454", 115"c c #545454",
116"d c #494949", 116"d c #494949",
117"e c #7A7A7A", 117"e c #7A7A7A",
118"f c #202020", 118"f c #202020",
119"g c #3D3D3D", 119"g c #3D3D3D",
120"h c #1F1F1F", 120"h c #1F1F1F",
121" .+@ ", 121" .+@ ",
122" #$%&* ", 122" #$%&* ",
123" =-;>,')", 123" =-;>,')",
124" .$;!~,)", 124" .$;!~,)",
125" ;#{]!)", 125" ;#{]!)",
126" ^~/(_)", 126" ^~/(_)",
127" ./:@<[)", 127" ./:@<[)",
128" }. .|]1;;2 ", 128" }. .|]1;;2 ",
129" #-$;^/3&;;4@ ", 129" #-$;^/3&;;4@ ",
130".$;;#5:67;89 ", 130".$;;#5:67;89 ",
131":%;0%&ab;8. ", 131":%;0%&ab;8. ",
132"@cd%e!fg49 ", 132"@cd%e!fg49 ",
133" h0,!_;2@ ", 133" h0,!_;2@ ",
134" ))))) "}; 134" ))))) "};
135 135
136VMemo::VMemo( QWidget *parent, const char *name ) 136VMemo::VMemo( QWidget *parent, const char *name )
137 : QWidget( parent, name ) 137 : QWidget( parent, name )
138{ 138{
139 setFixedHeight( 18 ); 139 setFixedHeight( 18 );
140 setFixedWidth( 14 ); 140 setFixedWidth( 14 );
141 141
142 recording = FALSE; 142 recording = FALSE;
143 143
144 myChannel = new QCopChannel( "QPE/VMemo", this ); 144 struct utsname name; /* check for embedix kernel running on the zaurus*/
145 connect( myChannel, SIGNAL(received(const QCString&, const QByteArray&)), 145 if (uname(&name) != -1) {
146 this, SLOT(receive(const QCString&, const QByteArray&)) ); 146 QString release=name.release;
147 147 if(release.find("embedix",0,TRUE) !=-1)
148 struct utsname name; /* check for embedix kernel running on the zaurus, if 148 systemZaurus=TRUE;
149 lineo change string, this break 149 else {
150 */ 150 systemZaurus=FALSE;
151 if (uname(&name) != -1) 151// myChannel = new QCopChannel( "QPE/VMemo", this );
152 { 152// connect( myChannel, SIGNAL(received(const QCString&, const QByteArray&)),
153 QString release=name.release; 153// this, SLOT(receive(const QCString&, const QByteArray&)) );
154 if(release.find("embedix",0,TRUE) !=-1) 154
155 systemZaurus=TRUE; 155// // Register the REC key press, for ipaq only
156 else 156// QCopEnvelope e("QPE/Desktop", "keyRegister(int key, QString channel, QString message)");
157 { 157// e << 4096;
158 systemZaurus=FALSE; 158// e << QString("QPE/VMemo");
159 159// e << QString("toggleRecord()");
160 // Register the REC key press. 160 }
161 QCopEnvelope e("QPE/Desktop", "keyRegister(int key, QString channel, QString message)"); 161 }
162 e << 4096;
163 e << QString("QPE/VMemo");
164 e << QString("toggleRecord()");
165 }
166 }
167} 162}
168 163
169VMemo::~VMemo() 164VMemo::~VMemo()
170{ 165{
171} 166}
172 167
173void VMemo::receive( const QCString &msg, const QByteArray &data ) 168void VMemo::receive( const QCString &msg, const QByteArray &data )
174{ 169{
175 QDataStream stream( data, IO_ReadOnly ); 170 QDataStream stream( data, IO_ReadOnly );
176 if (msg == "toggleRecord()") 171 if (msg == "toggleRecord()")
177 { 172 {
178 if (recording) 173 if (recording)
179 mouseReleaseEvent(NULL); 174 mouseReleaseEvent(NULL);
180 else 175 else
181 mousePressEvent(NULL); 176 mousePressEvent(NULL);
182 } 177 }
183} 178}
184 179
185void VMemo::paintEvent( QPaintEvent* ) 180void VMemo::paintEvent( QPaintEvent* )
186{ 181{
187 QPainter p(this); 182 QPainter p(this);
188 p.drawPixmap( 0, 1,( const char** ) vmemo_xpm ); 183 p.drawPixmap( 0, 1,( const char** ) vmemo_xpm );
189} 184}
190 185
191void VMemo::mousePressEvent( QMouseEvent *me ) 186void VMemo::mousePressEvent( QMouseEvent *me )
192{ 187{
193 // just to be safe 188 // just to be safe
194 if (recording) 189 if (recording)
195 { 190 {
196 recording = FALSE; 191 recording = FALSE;
197 return; 192 return;
198 } 193 }
199 194
200 /* 195 /*
201 No mousePress/mouseRelease recording on the iPAQ. The REC button on the iPAQ calls these functions 196 No mousePress/mouseRelease recording on the iPAQ. The REC button on the iPAQ calls these functions
202 mousePressEvent and mouseReleaseEvent with a NULL parameter. 197 mousePressEvent and mouseReleaseEvent with a NULL parameter.
203 */ 198 */
204 if (!systemZaurus && me != NULL) 199// if (!systemZaurus && me != NULL)
205 return; 200// return;
206 201
207 QSound::play(Resource::findSound("vmemob")); 202 QSound::play(Resource::findSound("vmemob"));
208 203 qDebug("Start recording");
209 recording = TRUE; 204 recording = TRUE;
210 if (openDSP() == -1) 205 if (openDSP() == -1)
211 { 206 {
212 QMessageBox::critical(0, "VMemo", "Could not open dsp device.", "Abort"); 207 QMessageBox::critical(0, "VMemo", "Could not open dsp device.", "Abort");
213 recording = FALSE; 208 recording = FALSE;
214 return; 209 return;
215 } 210 }
216 211
217 Config vmCfg("VMemo"); 212 Config vmCfg("VMemo");
218 vmCfg.setGroup("Defaults"); 213 vmCfg.setGroup("Defaults");
219 214
220 QDateTime dt = QDateTime::currentDateTime(); 215 QDateTime dt = QDateTime::currentDateTime();
221 QString fileName; 216 QString fileName;
222 217
223 if(systemZaurus) 218 if(systemZaurus)
224 fileName=vmCfg.readEntry("Dir", "/mnt/cf/"); // zaurus does not have /mnt/ramfs 219 fileName=vmCfg.readEntry("Dir", "/mnt/cf/"); // zaurus does not have /mnt/ramfs
225 else 220 else
226 fileName=vmCfg.readEntry("Dir", "/mnt/ramfs/"); 221 fileName=vmCfg.readEntry("Dir", "/mnt/ramfs/");
227 222
228 fileName += "vm_"; 223 fileName += "vm_";
229 fileName += dt.toString(); 224 fileName += dt.toString();
230 fileName += ".wav"; 225 fileName += ".wav";
231 226
232 // No spaces in the filename 227 // No spaces in the filename
233 fileName.replace(QRegExp("'"),""); 228 fileName.replace(QRegExp("'"),"");
234 fileName.replace(QRegExp(" "),"_"); 229 fileName.replace(QRegExp(" "),"_");
235 fileName.replace(QRegExp(":"),"."); 230 fileName.replace(QRegExp(":"),".");
236 fileName.replace(QRegExp(","),""); 231 fileName.replace(QRegExp(","),"");
237 232
238 if(openWAV(fileName.latin1()) == -1) 233 if(openWAV(fileName.latin1()) == -1)
239 { 234 {
240 QString err("Could not open the output file: "); 235 QString err("Could not open the output file: ");
241 err += fileName; 236 err += fileName;
242 237
243 QMessageBox::critical(0, "VMemo", err, "Abort"); 238 QMessageBox::critical(0, "VMemo", err, "Abort");
244 close(dsp); 239 close(dsp);
245 return; 240 return;
246 } 241 }
247 242
248 QArray<int> cats(1); 243 QArray<int> cats(1);
249 cats[0] = vmCfg.readNumEntry("Category", 0); 244 cats[0] = vmCfg.readNumEntry("Category", 0);
250 245
251 QString dlName("vm_"); 246 QString dlName("vm_");
252 dlName += dt.toString(); 247 dlName += dt.toString();
253 DocLnk l; 248 DocLnk l;
254 l.setFile(fileName); 249 l.setFile(fileName);
255 l.setName(dlName); 250 l.setName(dlName);
256 l.setType("audio/x-wav"); 251 l.setType("audio/x-wav");
257 l.setCategories(cats); 252 l.setCategories(cats);
258 l.writeLink(); 253 l.writeLink();
259 254
260 record(); 255 record();
261} 256}
262 257
263void VMemo::mouseReleaseEvent( QMouseEvent * ) 258void VMemo::mouseReleaseEvent( QMouseEvent * )
264{ 259{
265 recording = FALSE; 260 recording = FALSE;
266} 261}
267 262
268int VMemo::openDSP() 263int VMemo::openDSP()
269{ 264{
270 Config cfg("Sound"); 265 Config cfg("Sound");
271 cfg.setGroup("Record"); 266 cfg.setGroup("Record");
272 267
273 speed = cfg.readNumEntry("SampleRate", 22050); 268 speed = cfg.readNumEntry("SampleRate", 22050);
274 channels = cfg.readNumEntry("Stereo", 1) ? 2 : 1; // 1 = stereo(2), 0 = mono(1) 269 channels = cfg.readNumEntry("Stereo", 1) ? 2 : 1; // 1 = stereo(2), 0 = mono(1)
275 if (cfg.readNumEntry("SixteenBit", 1)==1) 270 if (cfg.readNumEntry("SixteenBit", 1)==1) {
276 { 271 format = AFMT_S16_LE;
277 format = AFMT_S16_LE; 272 resolution = 16;
278 resolution = 16; 273 }
279 } 274// else {
280 else 275// format = AFMT_U8;
281 { 276// resolution = 8;
282 format = AFMT_U8; 277// }
283 resolution = 8;
284 }
285 278
286 if(systemZaurus) 279 if(systemZaurus) {
287 { 280 dsp = open("/dev/dsp1", O_RDWR); //Zaurus needs /dev/dsp1
288 dsp = open("/dev/dsp1", O_RDWR); //Zaurus needs /dev/dsp1 281 channels=1; //zaurus has one input channel
289 channels=1; //zaurus has one input channel 282 } else {
290 } 283 dsp = open("/dev/dsp", O_RDWR);
291 else 284 }
292 dsp = open("/dev/dsp", O_RDWR);
293 285
294 if(dsp == -1) 286 if(dsp == -1) {
295 {
296 perror("open(\"/dev/dsp\")"); 287 perror("open(\"/dev/dsp\")");
297 return -1; 288 return -1;
298 } 289 }
299 290
300 if(ioctl(dsp, SNDCTL_DSP_SETFMT , &format)==-1) 291 if(ioctl(dsp, SNDCTL_DSP_SETFMT , &format)==-1) {
301 { 292 perror("ioctl(\"SNDCTL_DSP_SETFMT\")");
302 perror("ioctl(\"SNDCTL_DSP_SETFMT\")"); 293 return -1;
303 return -1; 294 }
304 } 295 if(ioctl(dsp, SNDCTL_DSP_CHANNELS , &channels)==-1) {
305 if(ioctl(dsp, SNDCTL_DSP_CHANNELS , &channels)==-1) 296 perror("ioctl(\"SNDCTL_DSP_CHANNELS\")");
306 { 297 return -1;
307 perror("ioctl(\"SNDCTL_DSP_CHANNELS\")"); 298 }
308 return -1; 299 if(ioctl(dsp, SNDCTL_DSP_SPEED , &speed)==-1) {
309 } 300 perror("ioctl(\"SNDCTL_DSP_SPEED\")");
310 if(ioctl(dsp, SNDCTL_DSP_SPEED , &speed)==-1) 301 return -1;
311 { 302 }
312 perror("ioctl(\"SNDCTL_DSP_SPEED\")"); 303 if(ioctl(dsp, SOUND_PCM_READ_RATE , &rate)==-1) {
313 return -1; 304 perror("ioctl(\"SOUND_PCM_READ_RATE\")");
314 } 305 return -1;
315 if(ioctl(dsp, SOUND_PCM_READ_RATE , &rate)==-1) 306 }
316 {
317 perror("ioctl(\"SOUND_PCM_READ_RATE\")");
318 return -1;
319 }
320 307
321 return 1; 308 return 1;
322} 309}
323 310
324int VMemo::openWAV(const char *filename) 311int VMemo::openWAV(const char *filename)
325{ 312{
326 track.setName(filename); 313 track.setName(filename);
327 if(!track.open(IO_WriteOnly|IO_Truncate|IO_Raw)) 314 if(!track.open(IO_WriteOnly|IO_Truncate|IO_Raw))
328 return -1; 315 return -1;
329 316
330 wav=track.handle(); 317 wav=track.handle();
331 318
332 WaveHeader wh; 319 WaveHeader wh;
333 320
334 wh.main_chunk = RIFF; 321 wh.main_chunk = RIFF;
335 wh.length=0; 322 wh.length=0;
336 wh.chunk_type = WAVE; 323 wh.chunk_type = WAVE;
337 wh.sub_chunk = FMT; 324 wh.sub_chunk = FMT;
338 wh.sc_len = 16; 325 wh.sc_len = 16;
339 wh.format = PCM_CODE; 326 wh.format = PCM_CODE;
340 wh.modus = channels; 327 wh.modus = channels;
341 wh.sample_fq = speed; 328 wh.sample_fq = speed;
342 wh.byte_p_sec = speed * channels * resolution/8; 329 wh.byte_p_sec = speed * channels * resolution/8;
343 wh.byte_p_spl = channels * (resolution / 8); 330 wh.byte_p_spl = channels * (resolution / 8);
344 wh.bit_p_spl = resolution; 331 wh.bit_p_spl = resolution;
345 wh.data_chunk = DATA; 332 wh.data_chunk = DATA;
346 wh.data_length= 0; 333 wh.data_length= 0;
347 // qDebug("Write header channels %d, speed %d, b/s %d, blockalign %d, bitrate %d" 334 // qDebug("Write header channels %d, speed %d, b/s %d, blockalign %d, bitrate %d"
348 // , wh.modus, wh.sample_fq, wh.byte_p_sec, wh.byte_p_spl, wh.bit_p_spl ); 335 // , wh.modus, wh.sample_fq, wh.byte_p_sec, wh.byte_p_spl, wh.bit_p_spl );
349 write (wav, &wh, sizeof(WaveHeader)); 336 write (wav, &wh, sizeof(WaveHeader));
350 337
351 return 1; 338 return 1;
352} 339}
353 340
354void VMemo::record(void) 341void VMemo::record(void)
355{ 342{
356 int length=0, result, value; 343 int length=0, result, value;
357 char sound[512]; 344 qDebug("Recording");
345
346 if(format==AFMT_S16_LE) {
347 signed short sound[512], monoBuffer[512];
348 while(recording) {
349 result = read(dsp, sound, 512); // 8192
350 qApp->processEvents();
351 int j=0;
352 if(systemZaurus) {
353 for (int i = 0; i < result; i++) { //since Z is mono do normally
354 monoBuffer[i] = sound[i];
355 }
356 qApp->processEvents();
357 length+=write(wav, monoBuffer, result);
358 } else { //ipaq /stereo inputs
359 for (int i = 0; i < result; i+=2) {
360 monoBuffer[j] = (sound[i]+sound[i+1])/2;
361 j++;
362 }
363 qApp->processEvents();
364 length+=write(wav, monoBuffer, result/2);
365 }
366 printf("%d\r",length);
367 fflush(stdout);
368 }
369 }
370 // else { //AFMT_U8 // don't try this yet.. as player doesn't understand
371// 8bit unsigned
372 // unsigned short sound[512], monoBuffer[512];
373// while(recording)
374// {
375// result = read(dsp, sound, 512); // 8192
376// qApp->processEvents();
377// int j=0;
378// if(systemZaurus)
379// {
380// for (int i = 0; i < result; i++) { //since Z is mono do normally
381// monoBuffer[i] = sound[i];
382// }
383// qApp->processEvents();
384// length+=write(wav, monoBuffer, result);
385// } else { //ipaq /stereo inputs
386// for (int i = 0; i < result; i+=2) {
387// monoBuffer[j] = (sound[i]+sound[i+1])/2;
388// j++;
389// }
390// qApp->processEvents();
391// length+=write(wav, monoBuffer, result/2);
392// }
393// // length += result;
394// printf("%d\r",length);
395// fflush(stdout);
396
397// qApp->processEvents();
398// }
399// }
400
401
358 402
359 while(recording) 403// char sound[512]; //char is 8 bit
360 { 404
361 result = read(dsp, sound, 512); // 8192 405// while(recording)
362 qApp->processEvents(); 406// {
407// result = read(dsp, sound, 512); // 8192
408// qApp->processEvents();
363 409
364 write(wav, sound, result); 410// write(wav, sound, result);
365 length += result; 411// length += result;
366 412
367 qApp->processEvents(); 413// qApp->processEvents();
368 } 414// }
415// qDebug("file has length of %d lasting %d seconds",
416// length, (( length / speed) / channels) / 2 );
417// medialplayer states wrong length in secs
418
369 419
370 value = length+36; 420 value = length+36;
371 lseek(wav, 4, SEEK_SET); 421 lseek(wav, 4, SEEK_SET);
372 write(wav, &value, 4); 422 write(wav, &value, 4);
373 lseek(wav, 40, SEEK_SET); 423 lseek(wav, 40, SEEK_SET);
374 write(wav, &length, 4); 424 write(wav, &length, 4);
375 track.close(); 425 track.close();
376 426
377 if( ioctl( dsp, SNDCTL_DSP_RESET,0) == -1) 427 if( ioctl( dsp, SNDCTL_DSP_RESET,0) == -1)
378 perror("ioctl(\"SNDCTL_DSP_RESET\")"); 428 perror("ioctl(\"SNDCTL_DSP_RESET\")");
379 ::close(dsp); 429 ::close(dsp);
430// if(systemZaurus)
431 QMessageBox::message("Vmemo"," Done recording");
380 432
381 QSound::play(Resource::findSound("vmemoe")); 433 QSound::play(Resource::findSound("vmemoe"));
382} 434}