Example #1
0
void processSound() {

  uint8_t  i, x, L, *data, nBins, binNum;
  uint16_t minLvl, maxLvl;
  int      level, sum;

  fft_input(capture, bfly_buff);   // Samples -> complex #s
  samplePos = 0;                   // Reset sample counter
  ADCSRA |= _BV(ADIE);             // Resume sampling interrupt
  fft_execute(bfly_buff);          // Process complex data
  fft_output(bfly_buff, spectrum); // Complex -> spectrum

  // Remove noise and apply EQ levels
  for (x=0; x < FFT_N / 2; x++) {
    L = pgm_read_byte(&noise[x]);
    spectrum[x] = (spectrum[x] <= L) ? 0 :
      (((spectrum[x] - L) * (256L - pgm_read_byte(&eq[x]))) >> 8);
  }

  colCount = (colCount + 1) % 10;

  // Downsample spectrum output to 8 columns:
  for(x = 0; x < NUM_COLUMNS; x++) {
    data   = (uint8_t *)pgm_read_word(&colData[x]);
    nBins  = pgm_read_byte(&data[0]);
    binNum = pgm_read_byte(&data[1]);
    for(sum = 0, i = 0; i < nBins; i++)
      sum += spectrum[binNum++] * pgm_read_byte(&data[i + 2]); // Weighted
    col[x][colCount] = sum / colDiv[x];                    // Average
    minLvl = maxLvl = col[x][0];
    for(i = 1; i < 10; i++) { // Get range of prior 10 frames
      if(col[x][i] < minLvl)      minLvl = col[x][i];
      else if(col[x][i] > maxLvl) maxLvl = col[x][i];
    }
    // minLvl and maxLvl indicate the extents of the FFT output, used
    // for vertically scaling the output graph (so it looks interesting
    // regardless of volume level).  If they're too close together though
    // (e.g. at very low volume levels) the graph becomes super coarse
    // and 'jumpy'...so keep some minimum distance between them (this
    // also lets the graph go to zero when no sound is playing):
    if((maxLvl - minLvl) < 8) maxLvl = minLvl + 8;
    minLvlAvg[x] = (minLvlAvg[x] * 7 + minLvl) >> 3; // Dampen min/max levels
    maxLvlAvg[x] = (maxLvlAvg[x] * 7 + maxLvl) >> 3; // (fake rolling average)

    // Second fixed-point scale based on dynamic min/max levels:
    level = 10L * (col[x][colCount] - minLvlAvg[x]) /
      (long)(maxLvlAvg[x] - minLvlAvg[x]);

    // Clip output and convert to byte:
    if(level < 0L)      colLeveled[x] = 0;
    else if(level > 10) colLeveled[x] = 10; // Allow dot to go a couple pixels off top
    else                colLeveled[x] = (uint8_t)level;

    // XXX - The leveled columns could probably be improved
  }
}
Example #2
0
int main (void)
{
	char *cp;
	uint16_t m, n, s;
	uint16_t t1,t2,t3;


	DDRE = 0b00000010;	/* PE1:<conout>, PE0:<conin> in N81 38.4kbps */
	TCCR1B = 3;	/* clk/64 */

	xmitstr(PSTR("\r\nFFT sample program\r\n"));

	for(;;) {
		xmitstr(PSTR("\r\n>"));			/* Prompt */
		rcvrstr(pool, sizeof(pool));	/* Console input */
		cp = pool;

		switch (*cp++) {	/* Pick a header char (command) */
			case '\0' :		/* Blank line */
				break;

			case 'w' :		/* w: show waveform */
				capture_wave(capture, FFT_N);
				for (n = 0; n < FFT_N; n++) {
					s = capture[n];
					xmitf(PSTR("\r\n%4u:%6d "), n, s);
					s = (s + 32768) / 1024;
					for (m = 0; m < s; m++) xmit(' ');
					xmit('*');
				}
				break;

			case 's' :		/* s: show spectrum */
				capture_wave(capture, FFT_N);
				TCNT1 = 0;	/* performance counter */
				fft_input(capture, bfly_buff);
				t1 = TCNT1; TCNT1 = 0;
				fft_execute(bfly_buff);
				t2 = TCNT1; TCNT1 = 0;
				fft_output(bfly_buff, spektrum);
				t3 = TCNT1;
				for (n = 0; n < FFT_N / 2; n++) {
					s = spektrum[n];
					xmitf(PSTR("\r\n%4u:%5u "), n, s);
					s /= 512;
					for (m = 0; m < s; m++) xmit('*');
				}
				xmitf(PSTR("\r\ninput=%u, execute=%u, output=%u (x64clk)"), t1,t2,t3);
				break;

			default :		/* Unknown command */
				xmitstr(PSTR("\n???"));
		}
	}
}
Example #3
0
int main (void)
{
	initTimer();
	initLeds();


	loggerInit();
	loggerWriteToMarker((LogMesT)"\r\nFFT sample program\r\n*", '*');
	loggerWriteToMarker((LogMesT)"\r\n>*", '*');			/* Prompt */
	for(;;) {
		
		capture_wave(capture, FFT_N);
				
		fft_input(capture, bfly_buff);
		fft_execute(bfly_buff);
		fft_output(bfly_buff, spektrum);
		
		_delay_ms(50);
	}
}
Example #4
0
int main(void)
{
	memset( spectrum, 0, sizeof(spectrum) );
	memset( spectrum_history, 0, sizeof(spectrum) );

	init();

	uint16_t cycles_till_reset_x = LCD_RESET_ADDR_CYCLES;

	while(1)
	{
		if( sleeping )
		{
			sleepcycles++;

			if( backlight_task_scaler++ >= 75 )
			{
				backlight_task(-1);
				backlight_task_scaler = 0;
			}

			if( sleeping == 3 )
				go_to_sleep();
			else if( sleeping == 2 )
				wake_up();
			else // sleeping == 1
			{
				SMCR = _BV(SM0) | _BV(SE);
				asm volatile( "sleep\n\t" );
			}
		}
		else
		{
			backlight_task_scaler = 0;
			backlight_task(-1);

			// Apply window function and store in butterfly array
			fft_input( capture, bfly );

			// Execute forier transform
			fft_execute( bfly );

			// Bit reversal algorithm from butterfly array to output array
			fft_output( bfly, spectrum );

			// Do exponential/FIR filtering with history data
			exp_average( spectrum, spectrum_history );

#ifdef DISPLAY_TEST_PATTERN
			uint8_t *sp = spectrum;
			uint8_t v = 5;
			uint8_t k = sizeof(spectrum)/sizeof(uint8_t);
			while( k-- )
			{
				*sp = v;
				v++;
				if( v > 38 )
					v = 5;
				sp++;
			}

			long t = 100000;
			while(t--)
			{
				asm volatile("nop");
			}

#else

#ifdef BLANK_LEFT_TWO_BARS
			spectrum[0] = spectrum[1] = 0;
#endif
#endif
			avc_task( spectrum );

			if( --cycles_till_reset_x <= 0 )
			{
				cycles_till_reset_x = LCD_RESET_ADDR_CYCLES;
				lcd_write_instruction( LCD_ADDR | 0, CHIP1 );
				lcd_write_instruction( LCD_ADDR | 0, CHIP2 );
			}
			fastlcd( spectrum );
			
			loopnum++;
		}
	}