Making a guitar tuner in pixilang

Pixilang programming language
Post Reply
philipbergwerf
Posts: 136
Joined: Sat Mar 17, 2018 4:23 pm

Making a guitar tuner in pixilang

Post by philipbergwerf »

Because I am curious how this works I want to create a guitar tuner app in pixilang! :Yahoo!: My approache is to first create a spectrum analyser because that's generating data that can be used for pitch detection. I know a little about programming but this is new to me so I want to ask: Is a spectrum visualiser a good direction to go? However I will make the spectrum analyser first because it will be a learn-full experience and it's cool :) Any questions about this project will go in this topic because otherwise I need to create countless topics and that would be a little unclear.
philipbergwerf
Posts: 136
Joined: Sat Mar 17, 2018 4:23 pm

fft()?

Post by philipbergwerf »

Ah I was looking to make fft() but I see in the documentation that there is an built-in fft() function. The documentation is a little concise. What do the parameters mean exactly? Parameters ( inverse, im, re, size )
  • Inverse; What kind of value is expected?
  • im; what does it mean?
  • re; what does it mean?
  • size; I suppose it is the size of the size of my audio stream buffer?
User avatar
NightRadio
Site Admin
Posts: 3574
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Making a guitar tuner in pixilang

Post by NightRadio »

inverse: 0 - direct FFT; 1 - inverse transform;
im - imaginary part
re - real part
size - FFT size

From sound to spectrum:

Code: Select all

fft_size = 1024 //must be a power of two
im = new( fft_size, 1, FLOAT )
re = new( fft_size, 1, FLOAT )
//put your signal to the re[] array
clean( im )
fft( 0, im, re )
//now im[x] and re[x] contain your signal in the frequency domain
//x: 0...fft_size/2
//   0 = 0 Hz (DC)
//   1 = sample rate / 2 / fft_size
//   2 = sample rate / 2 / fft_size * 2
//   ...
//   fft_size / 2 = sample rate / 2
Back to sound (time domain):

Code: Select all

fft( 1, im, re )
//now you can find your original audio signal in the re[0...fft_size-1] array
philipbergwerf
Posts: 136
Joined: Sat Mar 17, 2018 4:23 pm

Re: Making a guitar tuner in pixilang

Post by philipbergwerf »

Thanks for the examples alexander!

I have searched trough the documentation but couldn't find a way to take the whole screen and move every pixel one pixel upwards. Is this possible in an easy way? The effector has some function that does this approximately but I need something that does exactly this.

Code: Select all

set_pixel_size( WINDOW_XSIZE / 4096 )
resize( get_screen(), WINDOW_XSIZE, WINDOW_YSIZE )

fn audio_callback(
    $stream, 
    $userdata, 
    $channels, 
    $frames, 
    $output_time_in_system_ticks, 
    $in_channels, 
    $latency_in_frames )
{
    if $in_channels >= 0
    {
	copy( visual_buf, $in_channels[ 0 ] )
    }
    ret( 0 ) //output is empty
}

fft_size = 4096
visual_buf = new( fft_size, 1, INT16 )
clean( visual_buf )

// create lists for fft
im = new( fft_size, 1, FLOAT )
re = new( fft_size, 1, FLOAT )

set_audio_callback( audio_callback, 0, 44100, INT16, 2 )
enable_audio_input( 1 )

while 1
{
    // position variables
    scr = get_screen()
    xsize = WINDOW_XSIZE
    ysize = WINDOW_YSIZE
    left = -xsize/2
    right = xsize/2
    top = -ysize/2
    bottom = ysize/2

    x = 0 while x < fft_size
    {
        re[x] = visual_buf[x]
        x + 1
    }
    
    clean(im)
    fft(0, im, re)

    x = 0 while x < fft_size
    {
        $freq = interpolation(0,fft_size/2,re[x])
        dot(left+x,bottom-1,get_color($freq,$freq/2,100))
        x + 1
    }

    // I want all pixels to go upwards one step each frame

    while( get_event() ) { if EVT[ EVT_TYPE ] == EVT_QUIT { halt } }

    frame()
}

fn interpolation($x, $y, $z) {ret(($z - $x) / ($y - $x))}
User avatar
NightRadio
Site Admin
Posts: 3574
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Making a guitar tuner in pixilang

Post by NightRadio »

take the whole screen and move every pixel one pixel upwards
Here is the trick:
pixi( get_screen(), 0, -1 )
But that doesn't work for moving down...
If you need to move the screen down, use more correct code:

Code: Select all

//Program init:
scr = get_screen()
scr2 = clone(scr)
//...
//Frame drawing:
copy(scr2,scr)
pixi(scr2,0,1)
Post Reply