Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1085 pj 1
/* Project:     HARTIK 3.0                                      */
2
/* Description: Hard Real TIme Kernel for 386 & higher machines */
3
/* Author:      Paolo Gai <pgai@rsk.it>                         */
4
/*              Advanced Linux Sound Architecture (ALSA)        */
5
/*              Copyright (c) by Jaroslav Kysela <perex@jcu.cz> */
6
/*              Luca Abeni                                      */
7
/*              FFTW by M. Frigo and S. G. Johnson              */
8
 
9
/* Date:        08/09/1999                                      */
10
 
11
/* File:        fftplay.c                                       */
12
/* Revision:    1.00 (Kernel 0.1.4; Library 0.0.9; Util 0.0.4)  */
13
 
14
 
15
/*
16
 
17
FFTPlay 1.0
18
-----------
19
 
20
This application reads data from the audio microphone and then put it
21
to the screen in a graphical oscilloscope-like form (both standard Hartik
22
SB driver and Alsa driver can be used).
23
 
24
The application also calculate a FFT on the latest values, and displays
25
the power spectrum in tho ways, one like an equalizator, and the other in a
26
2D form.
27
 
28
A resolution of 1024x768, 64K colors is used.
29
 
30
The task set is composed by these tasks and functions:
31
 
32
Self buffering functions (SB only)
33
----------------------------------
34
this function takes the samples read by the mic and then makes a window
35
with the last WINDATA_NSAMPLES samples. The window is then put in
36
the CAB windata.
37
 
38
Task raw and task mixer (ALSA only)
39
-----------------------------------
40
These tasks are used with the Alsa driver; because it doesn't support the
41
self-buffering mode, we have to do a forever cycle in witch we have to read
42
all the data. Then the data are managed like the self-buffering functions of
43
the SB driver or sent to the mixer task (with a STREAM mailbox) which makes
44
the window.
45
(This approach is not good for realtime...)
46
 
47
Task wave
48
---------
49
This task read the last window and then put it on the screen in a wave form
50
on the top of the screen.
51
The task's period is set to 40 ms (25 fps).
52
 
53
Task fft
54
--------
55
This task read the last window and then it computes the FFT.
56
With the FFT data it computes the power spectrum, whitch is sent to the
57
CAB pwrdata.
58
The task's period is set to 10 ms (good for the 2D story task).
59
This task is the only Hard Task.
60
 
61
Task equ
62
--------
63
This task read the last power spectrum and displays it in a graphical
64
form, like a hi-fi equalizator.
65
The Histograms can be white or coloured like the equ2D task (see EQU_SHADE)
66
The task's period is set to 40 ms (25 fps).
67
 
68
Task equ2D
69
----------
70
This task read the lasf power spectrum and displays it in a graphical
71
one-line form. Each pixel is a power coefficient, and its colour shade
72
from black (no power) to red (high power) passing through green and blue.
73
The task display the last EQU2D_WIDTH power lines.
74
The task's period is set to 10 ms (good for the 2D story task).
75
 
76
****************************************************************************
77
TASK LOAD
78
****************************************************************************
79
 
80
                     period              wcet
81
task             tick     (ms)      us          %
82
--------------------------------------------------------
83
sound driver    24->3    12->1.5   200     0.016->0.133
84
wave              80       40     11500       0.2875
85
fft               20       10      3000       0.3000
86
equ               80       40      7000       0.1750
87
equ2D             20       10       500       0.0500
88
                                          -------------
89
                                              0.812 (last 4)
90
*/
91
 
92
#include <ll/ll.h>
93
 
94
#include <kernel/types.h>
95
#include <kernel/model.h>
96
#include <kernel/func.h>
97
 
98
#include <modules/cabs.h>
99
 
100
#include <string.h>
101
#include <stdlib.h>
102
#include <semaphore.h>
103
 
104
#include <drivers/keyb.h>
105
#include <drivers/crtwin.h>
106
#include <drivers/glib.h>
107
#include <drivers/sound.h>
108
#include <ports/rfftw.h>
109
 
110
/* now the load constants... */
111
 
112
#define WCET_WAVE   11500
113
#define WCET_FFT    3000
114
#define WCET_EQU    500
115
#define WCET_EQU2D  500
116
 
117
#define PERIOD_WAVE  40000
118
#define PERIOD_FFT   10000
119
#define PERIOD_EQU   40000
120
#define PERIOD_EQU2D 10000
121
 
122
/* define if shorts critical sections wanted */
123
#define SHORT_CRITICAL_SECTIONS(x) \
124
  if (!((x)%64))                   \
125
    {                              \
126
      sem_post(&mutex);            \
127
      sem_wait(&mutex);            \
128
    }
129
 
130
/* define if you want NRT or SOFT... */
131
#define TASK_TYPE SOFT
132
//#define TASK_TYPE NRT
133
 
134
 
135
 
136
/* Only 4 Debug... */
137
/*#define NO_GRX */
138
 
139
/* Samples are 16-bit signed integers */
140
typedef short SAMPLE;
141
#define MAX_SAMPLE 32768
142
 
143
/* Informations about the sampling rate and buffers */
144
WORD rawdata_nsamples;
145
WORD rawdata_buffer_size;
146
WORD rawdata_freq;
147
 
148
/* Numbers of samples of the sample window */
149
#define WINDATA_NSAMPLES  1024
150
 
151
/* task WAVE */
152
/* the point (wave_x,wave_y) is on the center left of the area... */
153
#define WAVE_NSAMPLES 1024
154
#define WAVE_X        0
155
#define WAVE_Y        130
156
#define WAVE_HEIGHT   80
157
 
158
/* task FFT */
159
#define FFT_NSAMPLES  WINDATA_NSAMPLES
160
#define PWR_NSAMPLES  (FFT_NSAMPLES/2+1)
161
 
162
/* task EQU */
163
/* the point (equ_x, equ_y) is the top right corner */
164
#define EQU_NSAMPLES  PWR_NSAMPLES
165
#define EQU_X         170
166
#define EQU_Y         255
167
#define EQU_HEIGHT    170
168
#define EQU_SHADE
169
 
170
/* task EQU2D */
171
/* the point (equ2d_x, equ2d_y) is the top left corner */
172
#define EQU2D_NSAMPLES  EQU_NSAMPLES
173
#define EQU2D_X         255
174
#define EQU2D_Y         EQU_Y
175
#define EQU2D_WIDTH     768
176
#define EQU2D_CLIP      255
177
 
178
/* scenario */
179
#define SCENARIO_NLABEL 16
180
 
181
/* Scale factors */
182
#define FFT_SCALE   (16384.0)
183
#define EQU_SCALE   (32.0)
184
#define EQU2D_SCALE (8.0)
185
//#define EQU_SCALE   (64.0)
186
//#define EQU2D_SCALE (16.0)
187
 
188
 
189
/* CAB ports... */
190
CAB cab_windata;   /* a window on the last WINDATA_DIM samples */
191
CAB cab_pwrdata;   /* the last power spectrum                  */
192
 
193
/* for the cab_windata */
194
typedef struct {
195
  int start;
196
  SAMPLE sample[WINDATA_NSAMPLES];
197
} window;
198
 
199
/* for the cab_pwrdata */
200
typedef struct {
201
  fftw_real p[PWR_NSAMPLES];
202
} power;
203
 
204
/* graphic mutex... */
205
sem_t mutex;
206
 
207
// win is global... because is used by raw_infun...
208
window win;
209
 
210
 
211
 
212
/* useful colors... */
213
int white;
214
int black;
215
int red;
216
 
217
static void version( void )
218
{
219
  cprintf( "Hartik FFT Play 1.0\n"     );
220
  cprintf( "-----------------------\n" );
221
  cprintf( "by Paolo Gai 1999\n"       );
222
  cprintf( "   <pj@hartik.sssup.it>\n" );
223
  cprintf( "-----------------------\n" );
224
}
225
 
226
void reverse(char s[])
227
{
228
  int c, i, j;
229
 
230
  for (i = 0, j = strlen(s)-1; i<j; i++, j--)
231
  {
232
    c = s[i];
233
    s[i] = s[j];
234
    s[j] = c;
235
  }
236
}
237
 
238
char * itoa(int n, char *s)
239
{
240
  int i, sign;
241
 
242
  if ((sign = n) < 0)
243
    n = -n;
244
 
245
  i = 0;
246
 
247
  do
248
  {
249
    s[i++] = n % 10 + '0';
250
  } while ((n /= 10) > 0);
251
 
252
  if (sign < 0)
253
    s[i++] = '-';
254
 
255
  s[i] = 0;
256
 
257
  reverse(s);
258
 
259
  return s;
260
}
261
 
262
 
263
 
264
/*
265
   This is the self-buffering function: read the samples and put their mean
266
   value in a CAB
267
*/
268
int raw_infun(void *b)
269
{
270
    int i;
271
    char *w;
272
    SAMPLE *audiobuf = (SAMPLE *)b;
273
 
274
    for (i=0; i<rawdata_nsamples/2; i++) {
275
      win.sample[win.start] = audiobuf[i];
276
      win.start = (win.start+1) % WINDATA_NSAMPLES;
277
    }
278
 
279
    w = cab_reserve(cab_windata);
280
    memcpy(w, &win, sizeof(window));
281
    cab_putmes(cab_windata,w);
282
 
283
  #if defined(NO_GRX)
284
    cprintf("X"); //"XXX%d\n",win.sample[win.start]);
285
  #endif
286
    return 0;
287
}
288
 
289
 
290
 
291
void init_rawdata()
292
{
293
  int i;
294
  char *w;
295
 
296
  win.start = 0;
297
  for (i=0; i<WINDATA_NSAMPLES; i++)
298
    win.sample[i] = 0;
299
 
300
  w = cab_reserve(cab_windata);
301
  memcpy(w, &win, sizeof(window));
302
  cab_putmes(cab_windata,w);
303
}
304
 
305
 
306
 
307
 
308
 
309
TASK wave_task()
310
{
311
  window *p;
312
  int x,y;
313
  int s;
314
 
315
  while(1)
316
  {
317
    p = (window *)cab_getmes(cab_windata);
318
 
319
    /* let's print the wave */
320
    sem_wait(&mutex);
321
    for(x = WAVE_X, s = p->start;
322
        x < WAVE_X+WAVE_NSAMPLES;
323
        x++, s = (s+1)%WINDATA_NSAMPLES )
324
    {
325
      y = WAVE_Y + (WAVE_HEIGHT * p->sample[s]) / MAX_SAMPLE;
326
      SHORT_CRITICAL_SECTIONS(x);
327
      grx_plot(x,y,white);
328
    }
329
    sem_post(&mutex);
330
 
331
    task_endcycle();
332
 
333
    /* let's erase the wave */
334
    sem_wait(&mutex);
335
    for(x = WAVE_X, s = p->start;
336
        x < WAVE_X+WAVE_NSAMPLES;
337
        x++, s = (s+1)%WINDATA_NSAMPLES )
338
    {
339
      y = WAVE_Y + (WAVE_HEIGHT * p->sample[s]) / MAX_SAMPLE;
340
      SHORT_CRITICAL_SECTIONS(x);
341
      grx_plot(x,y,black);
342
    }
343
    sem_post(&mutex);
344
 
345
    cab_unget(cab_windata,(char *)p);
346
 
347
  }
348
}
349
 
350
 
351
rfftw_plan plan;
352
 
353
void fft_close(void *arg)
354
{
355
  rfftw_destroy_plan(plan);
356
}
357
 
358
 
359
TASK fft_task()
360
{
361
  fftw_real in[FFT_NSAMPLES], out[FFT_NSAMPLES];
362
  power power_spectrum;
363
 
364
  #if defined(NO_GRX)
365
    fftw_real max = 0.0;
366
  #endif
367
 
368
  char *m;
369
 
370
  int k, i;
371
 
372
  window *p;
373
 
374
  plan = rfftw_create_plan(FFT_NSAMPLES, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
375
 
376
  sys_atrunlevel(fft_close, NULL, RUNLEVEL_BEFORE_EXIT);
377
 
378
  while(1)
379
  {
380
    /* Let's prepare the intput FFT data */
381
    p = (window *)cab_getmes(cab_windata);
382
 
383
    for (k = 0, i = p->start;
384
        k < FFT_NSAMPLES;
385
        k++, i = (i+1)%WINDATA_NSAMPLES)
386
      in[k] = p->sample[i]/FFT_SCALE;
387
 
388
    cab_unget(cab_windata,(char *)p);
389
 
390
    /* zero-padding if needed */
391
    for (k=WINDATA_NSAMPLES; k < FFT_NSAMPLES; k++)
392
      in[k] = 0.0;
393
 
394
    rfftw_one(plan, in, out);
395
 
396
    /* power spectrum computation */
397
    power_spectrum.p[0] = out[0]*out[0];  /* DC component */
398
    for (k = 1; k < PWR_NSAMPLES; ++k)  /* (k < N/2 rounded up) */
399
          power_spectrum.p[k] = out[k]*out[k] + out[FFT_NSAMPLES-k]*out[FFT_NSAMPLES-k];
400
    if (FFT_NSAMPLES % 2 == 0) /* N is even */
401
          power_spectrum.p[FFT_NSAMPLES/2] = out[FFT_NSAMPLES/2]*out[FFT_NSAMPLES/2];  /* Nyquist freq. */
402
 
403
    m = cab_reserve(cab_pwrdata);
404
    memcpy(m, &power_spectrum, sizeof(power));
405
    cab_putmes(cab_pwrdata,m);
406
 
407
    #if defined(NO_GRX)
408
    max = 0.0;
409
    for (k=0; k<PWR_NSAMPLES; k++)
410
      if (power_spectrum.p[k] > max)
411
        max = power_spectrum.p[k];
412
 
413
    //cprintf("%f %f\n",max,(max / EQU_SCALE) );
414
    #endif
415
 
416
    task_endcycle();
417
 
418
  }
419
}
420
 
421
/* structure is like the wave task... */
422
TASK equ_task()
423
{
424
  power *p;
425
 
426
  int x[PWR_NSAMPLES];
427
  int y;
428
  int s;
429
 
430
  int r,g,b;
431
 
432
  while(1)
433
  {
434
    p = (power *)cab_getmes(cab_pwrdata);
435
 
436
    /* print the lines */
437
    sem_wait(&mutex);
438
    for(y = EQU_Y, s = 0;
439
        s < EQU_NSAMPLES;
440
        y++, s++ )
441
    {
442
      x[s] = (int)(p->p[s] / EQU_SCALE);
443
 
444
      if (x[s] > EQU_HEIGHT)
445
        x[s] = EQU_HEIGHT;
446
 
447
      x[s] = EQU_X - x[s];
448
 
449
 
450
      #if defined(EQU_SHADE)
451
 
452
       /* like the task equ2d... */
453
       r = (int)(p->p[s] / EQU2D_SCALE);
454
       if (r > EQU2D_CLIP)
455
         r = EQU2D_CLIP;
456
 
457
            if (r< 64)  g = r * 4;
458
       else if (r<128)  g = (128-r) * 4;
459
       else             g = 0;
460
 
461
            if (r<128)  b = 0;
462
       else if (r<192)  b = (r-128) * 4;
463
       else             b = (256-r) * 4;
464
 
465
       SHORT_CRITICAL_SECTIONS(y);
466
       grx_line(EQU_X,y,x[s],y,rgb16(r,g,b));
467
      #else
468
       SHORT_CRITICAL_SECTIONS(y);
469
       grx_line(EQU_X,y,x[s],y,white);
470
      #endif
471
    }
472
    sem_post(&mutex);
473
 
474
    task_endcycle();
475
 
476
    /* erase the lines... */
477
    sem_wait(&mutex);
478
    for(y = EQU_Y, s = 0;
479
        s < EQU_NSAMPLES;
480
        y++, s++ )
481
    {
482
      SHORT_CRITICAL_SECTIONS(y);
483
      grx_line(EQU_X,y,x[s],y,black);
484
    }
485
    sem_post(&mutex);
486
 
487
    cab_unget(cab_pwrdata,(char *)p);
488
 
489
  }
490
}
491
 
492
TASK equ2d_task()
493
{
494
  power *p;
495
 
496
  int pwrint;
497
 
498
  int x = 0;
499
 
500
  int y,s;
501
 
502
  int r,g,b;
503
 
504
  while(1)
505
  {
506
 
507
    p = (power *)cab_getmes(cab_pwrdata);
508
 
509
    /* print the line */
510
    sem_wait(&mutex);
511
 
512
    for(y = EQU2D_Y, s = 0;
513
        s < EQU2D_NSAMPLES;
514
        y++, s++ )
515
    {
516
      pwrint = (int)(p->p[s] / EQU2D_SCALE);
517
 
518
      if (pwrint > EQU2D_CLIP)
519
        pwrint = EQU2D_CLIP;
520
 
521
      r = pwrint;
522
 
523
           if (pwrint< 64)  g = pwrint * 4;
524
      else if (pwrint<128)  g = (128-pwrint) * 4;
525
      else                  g = 0;
526
 
527
           if (pwrint<128)  b = 0;
528
      else if (pwrint<192)  b = (pwrint-128) * 4;
529
      else                  b = (256-pwrint) * 4;
530
 
531
      SHORT_CRITICAL_SECTIONS(y);
532
      grx_plot(EQU2D_X+x,y,rgb16(r,g,b));
533
    }
534
 
535
    x = (x+1) % EQU2D_WIDTH;
536
    grx_line(EQU2D_X+x,EQU2D_Y,EQU2D_X+x,EQU2D_Y+EQU2D_NSAMPLES,white);
537
 
538
    sem_post(&mutex);
539
 
540
    cab_unget(cab_pwrdata,(char *)p);
541
 
542
    task_endcycle();
543
  }
544
}
545
 
546
TASK prova_task()
547
{
548
  window *p;
549
 
550
  while(1)
551
  {
552
    p = (window *)cab_getmes(cab_windata);
553
    cprintf("%d %d %d\t", p->start /*sample[0]*/,p->sample[1],p->sample[2]);
554
    cab_unget(cab_windata,(char *)p);
555
 
556
    task_endcycle();
557
  }
558
}
559
 
560
 
561
void scenario(int f)
562
{
563
  int i,y;
564
  char s[6];
565
 
566
  grx_line(0,WAVE_Y-WAVE_HEIGHT-1,1023,WAVE_Y-WAVE_HEIGHT-1,red);
567
  grx_line(0,WAVE_Y+WAVE_HEIGHT+1,1023,WAVE_Y+WAVE_HEIGHT+1,red);
568
  grx_line(0,EQU_Y-11            ,1023,EQU_Y-11            ,red);
569
 
570
 
571
 
572
  /* lines near the frequencies */
573
  grx_line(EQU_X  +1,EQU_Y,EQU_X  +1,EQU_Y+EQU_NSAMPLES,red);
574
  grx_line(EQU2D_X-1,EQU_Y,EQU2D_X-1,EQU_Y+EQU_NSAMPLES,red);
575
 
576
  for (i=0; i<SCENARIO_NLABEL; i++)
577
  {
578
    y = (i*EQU_NSAMPLES)/(SCENARIO_NLABEL-1);
579
    if (i == SCENARIO_NLABEL-1) y--;
580
    grx_line(EQU_X  +1,EQU_Y+y,EQU_X  +10,EQU_Y+y,red);
581
    grx_line(EQU2D_X-1,EQU_Y+y,EQU2D_X-10,EQU_Y+y,red);
582
 
583
    itoa((i*f)/(SCENARIO_NLABEL-1),s);
584
    grx_text(s,EQU_X+20,EQU_Y+y-8,white,black);
585
  }
586
 
587
  grx_text("FFTPlay 1.0 - by Paolo Gai 1999 <pj@hartik.sssup.it>", 0,8, rgb16(0,255,0), black );
588
  grx_text("...press ENTER key to exit..."  , 0,24, rgb16(0,255,0), black );
589
 
590
  grx_text("FFT Power Spectrum", 0      , EQU_Y-21, rgb16(0,0,255), black);
591
  grx_text("FFT Power Story", EQU2D_X+16, EQU_Y-21, rgb16(0,0,255), black);
592
  grx_text("Waveform"   , 0, WAVE_Y-WAVE_HEIGHT-10, rgb16(0,0,255), black);
593
 
594
}
595
 
596
 
597
 
598
 
599
void compute_params(int *freq,WORD *nsamp, WORD *per)
600
{
601
  if (*freq< 2000)
602
  {
603
    cprintf("WARNING: frequency less than 2000Hz\n  ---> frequency set to 2000Hz\n");
604
    *freq = 2000;
605
  }
606
  if (*freq<= 8000) { *nsamp = 128; *per = 10; return; }
607
  if (*freq<=16000) { *nsamp = 256; *per = 10; return; }
608
  if (*freq<=24000) { *nsamp = 512; *per = 10; return; }
609
  if (*freq>48000)
610
  {
611
    cprintf("WARNING: frequency greather than 48000Hz\n  ---> frequency set to 48000Hz\n");
612
    *freq = 48000;
613
  }
614
  if (*freq<=48000) { *nsamp = 1024;*per = 10; return; }
615
}
616
 
617
 
618
 
619
void my_close(void *arg)
620
{
621
        grx_close();
622
        sys_status(3);
623
}
624
 
625
 
626
void endfun(KEY_EVT *k)
627
{
628
    cprintf("Ctrl-Brk pressed! Ending...\n");
629
    sys_end();
630
}
631
 
632
int main(int argc, char **argv)
633
{
634
    int modenum;
635
 
636
    int f;
637
 
638
    /* irq period... */
639
    WORD period;
640
 
641
    KEY_EVT k;
642
 
643
    SOFT_TASK_MODEL m3, m4, m5, m6;
644
 
645
    PID p3,p4,p5,p6;
646
 
647
    version();
648
 
649
    if (argc == 1)
650
    {
651
      cprintf("type x fftplay <freq>");
652
      return 0;
653
    }
654
 
655
    f = atoi(argv[1]);
656
    compute_params(&f,&rawdata_nsamples,&period);
657
 
658
    keyb_set_map(itaMap);
659
    k.flag = CNTR_BIT;
660
    k.scan = KEY_C;
661
    k.ascii = 'c';
662
    keyb_hook(k,endfun);
663
    k.flag = CNTL_BIT;
664
    k.scan = KEY_C;
665
    k.ascii = 'c';
666
    keyb_hook(k,endfun);
667
 
668
    cab_windata = cab_create("windata", sizeof(window), 4);
669
    cab_pwrdata = cab_create("pwr", sizeof(power), 4);
670
 
671
    /* Init the sound lib */
672
    sound_init((rawdata_nsamples * sizeof(SAMPLE)), NULL);
673
    sound_info();
674
 
675
    /* Init the data used by the raw_infun */
676
    init_rawdata();
677
 
678
    /* Start the self-buffering sampling operation */
679
    sound_setfun(raw_infun, (int (*)(void *))-1);
680
    sound_sample(NULL, f, 0, DMA_OP | PCM16 | MYFUN, NULL);
681
 
682
    cprintf("Press Enter...");
683
    while (keyb_getchar() != 13);
684
 
685
    sys_atrunlevel(my_close, NULL, RUNLEVEL_BEFORE_EXIT);
686
 
687
    #if !defined(NO_GRX)
688
    grx_init();
689
    modenum = grx_getmode(1024, 768, 16);
690
    grx_setmode(modenum);
691
 
692
    /* init the graphic mutex */
693
    sem_init(&mutex, 0, 1);
694
 
695
    /* useful colors ... */
696
    white = rgb16(255,255,255);
697
    black = rgb16(0,0,0);
698
    red   = rgb16(255,0,0);
699
 
700
    scenario(f/2);
701
 
702
    #endif
703
 
704
    #if !defined(NO_GRX)
705
    soft_task_default_model(m3);
706
    soft_task_def_period(m3, PERIOD_WAVE);
707
    soft_task_def_met(m3, WCET_WAVE);
708
    soft_task_def_group(m3, 1);
709
    p3 = task_create("wave", wave_task, &m3, NULL);
710
    if (p3 == -1) {
711
        perror("FFTPlay: Could not create task <wave>\n");
712
        sys_end();
713
    }
714
    #endif
715
 
716
    soft_task_default_model(m4);
717
    soft_task_def_period(m4, PERIOD_FFT);
718
    soft_task_def_met(m4, WCET_FFT);
719
    soft_task_def_group(m4, 1);
720
    soft_task_def_stack(m4,32*1024);
721
    soft_task_def_usemath(m4);
722
    p4 = task_create("fft", fft_task, &m4, NULL);
723
    if (p4 == -1) {
724
        perror("FFTPlay: Could not create task <fft>\n");
725
        sys_end();
726
    }
727
 
728
    #if !defined(NO_GRX)
729
    soft_task_default_model(m5);
730
    soft_task_def_period(m5, PERIOD_EQU);
731
    soft_task_def_met(m5, WCET_EQU);
732
    soft_task_def_group(m5, 1);
733
    soft_task_def_stack(m5,32*1024);
734
    soft_task_def_usemath(m5);
735
    p5 = task_create("equ", equ_task, &m5, NULL);
736
    if (p5 == -1) {
737
        perror("FFTPlay: Could not create task <equ>\n");
738
        sys_end();
739
    }
740
    #endif
741
 
742
    #if !defined(NO_GRX)
743
    soft_task_default_model(m6);
744
    soft_task_def_period(m6, PERIOD_EQU2D);
745
    soft_task_def_met(m6, WCET_EQU2D);
746
    soft_task_def_group(m6, 1);
747
    soft_task_def_stack(m6,32*1024);
748
    soft_task_def_usemath(m6);
749
    p6 = task_create("equ2D", equ2d_task, &m5, NULL);
750
    if (p6 == -1) {
751
        perror("FFTPlay: Could not create task <equ2D>\n");
752
        sys_end();
753
    }
754
    #else
755
    /* Start the prova task */
756
    //task_def_wcet(m6,1000);
757
    //task_activate(task_create("prova",prova_task,TASK_TYPE,PERIODIC,200,&m6));
758
    #endif
759
 
760
    group_activate(1);
761
 
762
    /* Wait until the user get bored */
763
    while (keyb_getchar() != 13);
764
 
765
    sys_end();
766
 
767
    return 0;
768
}
769
 
770