Playing sound with variable frequency

hello

is this possible to play a patch with variable frequency (for example - car
engine. i want car engine sound to be played at higher rate, when car has
greater velocity) using sdl_mixer?
if not, is there any other library that would work with sdl without problems
(the best would be one with python bindings…), and would accomplish such
task?
i’ve been looking through libsdl.org site, but on the page with libraries i’m
always shown first 50 libraries (no matter of form options. i’ve even tried
to hack the query string, but with no luck). buggy php script?

greetz,
kuba

Hi,

I’ve (with extensive help from this mailing list!) written this piece of
code:

// Function expects a 16-bit Stereo Sample (4 Byte/Sample) and a scale
// factor (>1 means longer sample, thus lower pitch, <1 means shorter
// sample, thus higher pitch)
Mix_Chunk* Change_Pitch(Mix_Chunk *Input_Sample, float Factor) {
Mix_Chunk *Sample_Modified;

if (Input_Sample->allocated!=1) {
	throw 

CGenericException(std::string(“CSound::Change_Pitch”),std::string(“Input
sample not allocated.”));
}

Uint32 Number_Input_Samples=Input_Sample->alen/4;
Uint32 Number_Output_Samples=Uint32((float)Number_Input_Samples*Factor);
float Real_Factor = 

(float)Number_Output_Samples/(float)Number_Input_Samples;

Sample_Modified=(Mix_Chunk*)malloc(sizeof(Mix_Chunk));
Sample_Modified->allocated=1;			// Not yet, but will soon be
Sample_Modified->alen=Number_Output_Samples*4;
Sample_Modified->abuf=(Uint8*)malloc(Sample_Modified->alen*sizeof(Uint8));
Sample_Modified->volume=Input_Sample->volume;

Uint32 Begin, End;
Sint16 Left, Right;
Sint64 AverageL, AverageR;
Sint16 OutLeft, OutRight;
for (Uint32 i=0;i<Number_Output_Samples;i++) {
	Begin=(Uint32)((float)i/Real_Factor);
	End=(Uint32)((float)(i+1)/Real_Factor);
	AverageL=0;
	AverageR=0;
	// Destinataion i is the average of Begin-End of Input sample
	for (Uint32 j=Begin;j<=End;j++) {
		Left=(Input_Sample->abuf[(4*j)+1]<<8)|(Input_Sample->abuf[(4*j)+0]);
		Right=(Input_Sample->abuf[(4*j)+3]<<8)|(Input_Sample->abuf[(4*j)+2]);

		AverageL+=Left;
		AverageR+=Right;
	}
	OutLeft=Sint16((float)AverageL/(float)(End-Begin+1));
	OutRight=Sint16((float)AverageR/(float)(End-Begin+1));

	Sample_Modified->abuf[(4*i)+1]=(OutLeft>>8)&0xff;
	Sample_Modified->abuf[(4*i)+0]=(OutLeft)&0xff;
	Sample_Modified->abuf[(4*i)+3]=(OutRight>>8)&0xff;
	Sample_Modified->abuf[(4*i)+2]=(OutRight)&0xff;
}
return Sample_Modified;

}

You should be able to adapt it to samples or arbitrary type. Also, I’ve
tried changing the ugly things like the defintion of “Left” to

Left=((Sint16*)Input_Sample->abuf)[i];

(analog “Right” and “OutLeft”, “OutRight”), which would be a lot nicer
(and faster), yet it then sounded somewhat strange at some point. I
assume I’ve had an sign-error somewhere. If you find out how to do that
nicer, please post it here so I can fix mine (it took me so damn long to
figure that thing out, I’ve not had the nerves to do some more work with
it…).

This should probably part of the Wiki. I’ll enter it as soon as you guys
have figured out the technical stuff (like where to place it and so on).

Greetings,
Joe

Dnia pi? 11. czerwca 2004 14:43, Johannes Bauer napisa?:

Hi,

I’ve (with extensive help from this mailing list!) written this piece of
code:
resampling is one option i considered. this can be quite troublesome (i will
have to write python wrapper, etc), but above of all - possible to
accomplish :slight_smile:
i dont need very good quality, so sophisticated approximation algorithms wont
be necessary either…
despite that, i will try to find more convenient solution.

You should be able to adapt it to samples or arbitrary type. Also, I’ve

assume I’ve had an sign-error somewhere. If you find out how to do that
nicer, please post it here so I can fix mine (it took me so damn long to
i’ll try to. but i must say, this is last on my todo’s list :slight_smile:

big thanks for help
kuba

I don’t know about SDL_mixer. For our current project, I’m using OpenAL (we
need 3D sound), and once you get it running, it’s very simple to change the
pitch of samples, even on the fly - you just have to call a function which
sets the sample’s pitch parameter.

Works fine for our engine sounds.

hth,
Marian.On Friday 11 June 2004 13:25, kuba wrote:

is this possible to play a patch with variable frequency (for example - car
engine. i want car engine sound to be played at higher rate, when car has
greater velocity) using sdl_mixer?
if not, is there any other library that would work with sdl without
problems (the best would be one with python bindings…), and would
accomplish such task?