freshfunkee

Spewing my thoughts online, so I don't forget them later

Month: December, 2012

Tempo control of wav files with pitch correction in FMOD and C++

There aren’t a lot of references for tempo control with pitch correction online for FMOD although it does have the ability to do so. This process is based on 2 functions in FMOD. setFrequency(), which is the tempo control and DSP_PITCHSHIFT, which by varying the pitch parameter, can correct the unintentional pitch change when changing the frequency.

The code gets the deafult frequency for the wav stream, (in most cases 44100Hz), takes a user input for a new tempo, and sets the pitch parameter as a fraction of the default frequency over the user input.


#include "stdafx.h"

void errchk(FMOD_RESULT r)
{
	if(r != FMOD_OK)
	{
		printf("FMOD_ERROR! (%d) %s\n", r, FMOD_ErrorString(r));
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	FMOD::System *system;
	FMOD::Channel *channel=0;
	FMOD::Sound *stream1;
	FMOD::DSP *pitch;

	unsigned int version;
	float defreq, spfreq, pit;
	bool done = false, active = true;

	FMOD_RESULT result;

	result = FMOD::System_Create(&system);
	errchk(result);

	result = system->getVersion(&version);
	errchk(result);

	if(version < FMOD_VERSION)
	{
		printf("Error! You are using an old version of FMOD %08x. Required: %08x.", version, FMOD_VERSION);
		return 0;
	}

	result = system->init(1, FMOD_INIT_NORMAL, 0);
	errchk(result);

	result = system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &pitch);
	errchk(result);

	result = system->createStream("C:/trackStreams/Balcony.wav", FMOD_HARDWARE | FMOD_LOOP_NORMAL| FMOD_2D, 0, &stream1);
	errchk(result);

	result = system->playSound(FMOD_CHANNEL_FREE, stream1, false, &channel);
	errchk(result);

	result = channel->getFrequency(&defreq);
	errchk(result);

	printf("\n Default freq is: %.2f\n\n", defreq);

	result = pitch->setParameter(FMOD_DSP_PITCHSHIFT_FFTSIZE, 4096);
	errchk(result);

	result = system->addDSP(pitch,0);
	errchk(result);

	result = pitch->setActive(active);
	errchk(result);

	while(!done)
	{
		printf("\rEnter frequency: ");
		scanf(" %f", &spfreq);

		if(spfreq > 0)
		{
			result = pitch->remove();
			errchk(result);

			result = channel->setFrequency(spfreq);
			errchk(result);

			result = pitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, (defreq/spfreq));
			errchk(result);

			result = system->addDSP(pitch, 0);
			errchk(result);

			result = pitch->getParameter(FMOD_DSP_PITCHSHIFT_PITCH, &pit, 0, 0);
			errchk(result);

			printf("\nCurrent Pitch: %f\n", pit);
		}
		else
			done = true;
	}
	result = stream1->release();
	errchk(result);
	result = system->close();
	errchk(result);
	result = system->release();
	errchk(result);

	return 0;
}

Direction Change monitor in C++ using SDL

This is the first step towards tempo control using a cursor for my music controller project. The example shows a message whenever the direction of Y has changed while the mouse is moving and displays how long it has taken in milliseconds to change.

The code displays a simple SDL window. The window waits for a mouse motion event and displays a message to the console when Y has changed direction containing what direction it is currently going and how long it took the previous change in direction to occur. Waiting for an event proved to be more efficient than polling the event.

This logic will be the user input for controlling the tempo in the final project but adapted to work with Kinect.

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    float x,y;
    int direction = -1;
    bool done = false;
    Uint32 now = 0, prev = 0, interval =0;

    SDL_Surface *screen = NULL;
    SDL_Event event;

    SDL_Init(SDL_INIT_EVERYTHING);

    screen = SDL_SetVideoMode( 500, 500, 32, SDL_SWSURFACE );
    SDL_Flip( screen );

    while((!done) && (SDL_WaitEvent(&amp;event)))
    {
        switch(event.type)
        {
            case SDL_MOUSEMOTION:
                y = event.motion.yrel;
 
                if(direction == -1)
                {
                    if(y < -1) 
                    { 
                        direction = 1; 
                        now = SDL_GetTicks(); 
                        interval = now - prev; 
                        prev = now; 
                        printf("Direction changed to 1. Y is decreasing(upscreen), 
                                    time interval %i\n",               
                                    interval); 
                    } 
                } else 
                { 
                    if(y > 1)
                    {
                        direction = -1;
                        now = SDL_GetTicks();
                        interval = now - prev;
                        prev = now;
                        printf("Direction changed to -1. Y is increasing(downscreen), 
                                      time interval %i\n", interval);
                    }
                }
                break;
            case SDL_QUIT:
                done = true;
                break;
        }
    }
    return 0;
}

Kinect Progress and Project Poster

I was able to get my hands on a Kinect for Windows. I’ve started doing tutorials for basic tracking such as sensor initialization and depth tracking. I practiced these techniques by following these tutorials:

http://channel9.msdn.com/Series/KinectQuickstart

For our presentation, at project poster is required to provide a overview of the project, so I spent the weekend doing a design of what I hope the final application should look like.

PosterText