// Demo: White noise & band-pass filter with variable Q-factor // samplerate = 44100 lowfreq = 64 highfreq = 2048 xsize = get_xsize(get_screen()) ysize = get_ysize(get_screen()) xsize2 = xsize div 2 ysize2 = ysize div 2 noise = new(xsize, 1, FLOAT32) // Input signal: white noise out = new(xsize, 1, FLOAT32) // Resulting signal amp = 0 freq = 440 pi4 = M_PI * M_PI * 4 qn = 1.0 // This is normalised Q factor, not depending on the frequency lowqn = highfreq / samplerate highqn = 300.0 v = 0.0 vi = 0.0 a = 0.0 ai = 0.0 y0 = 0 y1 = 0 set_audio_callback(audio_callback, 0, samplerate, INT16, 1) fn audio_callback( $stream, $userdata, $channels, $frames, $output_time_in_system_ticks, $in_channels, $latency_in_frames ) { if amp {generator(OP_RAND, $channels[0], 0, 32767, 0, 0, 0, $frames)} else {clean($channels[0])} copy(noise, $channels[0]) op_cn(OP_MUL, noise, 1 / 32767, 0, xsize) n = 0 while n < $frames { v + $channels[0][n] / 262144 / sqrt(qn) * freq / samplerate v - a * freq * freq * pi4 / samplerate / samplerate a + v a * (1 - 1 / qn * freq / samplerate) $channels[0][n] = a * 32767 n + 1 } copy(out, $channels[0]) ret(1) } while 1 { while(get_event()) { if EVT[ EVT_TYPE ] == EVT_QUIT {halt} if EVT[ EVT_TYPE ] == EVT_MOUSEBUTTONDOWN || EVT[ EVT_TYPE ] == EVT_MOUSEMOVE { freq = lowfreq * pow(highfreq / lowfreq, (EVT[EVT_X] + xsize2) / xsize) qn = lowqn * pow(highqn / lowqn, (ysize2 - EVT[EVT_Y]) / ysize) amp = 1 } if EVT[ EVT_TYPE ] == EVT_MOUSEBUTTONUP { amp = 0 } } clear() fbox(-xsize2, -ysize2, xsize, ysize2 div 2, #3F0000) i = 1 y0 = ysize2 div 4 - ysize2 while i < xsize { y1 = (-3 - noise[i]) * ysize2 / 4 line(i - xsize2 - 1, y0, i - xsize2, y1, #FF0000) y0 = y1 i + 1 } fbox(-xsize2, ysize2 div 2, xsize, ysize2 div 2, #003F00) i = 1 y0 = ysize2 div 2 vi = 0 ai = 1 while i < xsize { vi - ai * freq * freq * pi4 / samplerate / samplerate ai + vi ai * (1 - 1 / qn * freq / samplerate) y1 = ysize2 * 0.75 - ai * ysize2 * 0.25 line(i - xsize2 - 1, y0, i - xsize2, y1, #00FF00) y0 = y1 i + 1 } fbox(-xsize2, -ysize2 div 2, xsize, ysize2, #3F3F00) i = 1 y0 = 0 while i < xsize { y1 = -out[i] / 32767 * ysize2 / 2 line(i - xsize2 - 1, y0, i - xsize2, y1, #FFFF00) y0 = y1 i + 1 } frame() }