22 February 2007

matlab session on pitch detection, but more about ring modulator etc.

Also today I do a little warming up: I'd like to give a it a shot and implement a ring modulator (DAFX p76). The ring modulator of my yamaha MO8 has the following parameters:
    • oscillator frequency coarse (0.5 - 5 kHz)
    • oscillator frequency fine (0 - 127)
    • LFO wave (tri, sine)
    • LFO depth (0 - 127)
    • LFO speed (0.0 - 39.70 Hz)
    • HPF cutoff frequency
    • LPF cutoff frequency
    • dry/wet balance
    • EQ low frequency
    • EQ low gain
    • EQ high frequency
    • EQ high gain
Only the first five comprise the ring modulation, 6 and 7 are filter parameters, 8 is a mixer parameter and the rest are EQ parameters.
Some remarks:
  1. I used
    modSound = sin(2*pi*OSCfreq*[0:1/Fs:Nbits]);
    but the Nbits indicates the quantization depth (16 bits when used with the wave file flute2.wav in my folder). Instead I have to use the length of the sound vector (as seen in the algorithm) when I want the modulating signal to be as long as the soundFile input.
    What I still don't get is why I have to divide the length of the vector sound with Fs. It is a kind of normalization, and if I don't do it, it wouldn't work. But I don't know why.
    solution: Try it with a ridiculous 2Hz sampling frequency and 10 seconds music sample. You'll see that if you want as many samples on the sine wave as on the input sample you'll have to divide the length of your input minus 1 through 2 to get to the 10 seconds.
  2. I spent a reasonable amount of time in generating different signals to be used as modulators; sine wave, triangular wave (special case of:), sawtooth, square wave. Everything works allright and the explanations are to be found in the m-file.
  3. The algorithm:
    function [output] = ringmod(soundFile, OSCfreq, LFOwave, LFOdepth, LFOspeed)
    % ring modulator
    % y(n) = x(n).m(n)
    % OSCfreq: oscillator frequency (best between )
    % LFOwave: type of wave that modulates the audio signal (sine, triangle, square, sawtooth with standard width)

    [sound,Fs,Nbits] = wavread(soundFile);

    % defining the modulating wave type 'LFOwave'
    % SINE
    if (strcmp(LFOwave, 'sine')) % use strcmp instead of == to compare strings
    % sampled taking steps of Ts or 1/Fs and this until length(sound)/Fs samples are
    % calculated
    % number of vector values 'length(sound)' must be normalized by Fs
    % because ... (?)
    modSound = sin(2*pi*OSCfreq*[0:1/Fs:(length(sound)-1)/Fs]);
    end
    % SAWTOOTH
    if (strcmp(LFOwave, 'sawtooth'))
    width = 0.9 % this defines where the max of the wave is situated in the interval between 0 and 2*pi
    modSound = sawtooth(2*pi*OSCfreq*[0:1/Fs:(length(sound)-1)/Fs],width);
    end
    % TRIANGLE
    if (strcmp(LFOwave, 'triangle'))
    %triangle wave (width = 0.5)
    modSound = sawtooth(2*pi*OSCfreq*[0:1/Fs:(length(sound)-1)/Fs],0.5);
    end
    % SQUARE
    if (strcmp(LFOwave, 'square'))
    modSound = square(2*pi*OSCfreq*[0:1/Fs:(length(sound)-1)/Fs]);
    end

    %wavplay(modSound, Fs); %for testing
    %sound(1:100)
    %modSound(1:100)
    %length(sound)
    %length(modSound)
    output = sound .* modSound';

    wavplay(output, Fs);
  4. This effect is perceived as nice eg. when using a voice as input, sine or other wave as modulation and low frequencies (~50Hz)
  5. I had some problems with the multiplication, but after trying it with small matrices I saw why:
    • I had to use a dot-product for elementwise multiplication .*
    • I had to have two columnmatrices or vectors. The modSound waves are on the contrary row matrices, so I had to transpose them: modSound'

OK, a warmup during 3 hours, typical...
So now a little bite and then: pitch extraction!

Hm, another two hours spent on surfing the internet and finding sites we could use. Look at the posts involved: Links, just links , some links for beat extraction.
Also I started a post that will contain ideas we have during our work. This way we have a leading trail when experimenting later on.
OK, another try towards pitch detection.

I'll talk about pages 336 and further in DAFX.
Pitch extraction is the same as estimating the fundamental frequency f0 and then possible postprocessing like pitch tracking and taking into account frequency relationships.
I'll be reading the interesting things and tomorrow I'll try the matlab code.

No comments: