summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/applets/vmemo/vmemo.cpp182
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
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
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
134VMemo::VMemo( QWidget *parent, const char *name ) 136VMemo::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
157VMemo::~VMemo() 159VMemo::~VMemo()
158{ 160{
159} 161}
160 162
161void VMemo::paintEvent( QPaintEvent* ) 163void 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
167void VMemo::mousePressEvent( QMouseEvent * ) 169void 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
238int VMemo::openDSP() 240int 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
291int VMemo::openWAV(const char *filename) 296int 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
325void VMemo::record(void) 328void 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}