Sign in to follow this  
mindrot

SDL_Mixer sound chunk queue? - menu rollover help-

Recommended Posts

Hi game dev experts and hobbists, hopefully a quick question thats been giving me a bit of trouble. how would one go about starting a sound chunk then interrupt that sound and replay it from the beginning an example would be a menu system roll over button 1 - play sound roll over button 2 - interrupt first button sound and begin sound again from start roll over button 3 - interrupt second button sound and begin sound again from start currently my menu system does the following roll over - play sound roll over 2 - play sound roll over 3 - play sound the results are - i quickly roll over buttons 1,2 & 3 my mouse is at rest on button 3 button 1 sound plays when it is complete button 2 sound plays when it is complete button 3 sound plays another interesting aspect is if i continue to quickly roll my mouse over buttons it would seem that the sounds layer on top of each other in the channel and amplify the volume level, and it can get quite loud! ive removed code that doesnt apply. if requested, will post full source.
//menubuttons is a vector full of my sprite class, its functions are simple enough
//mouseX and mouseY are ints filled during the event poll (not listed)
//set frame simply makes the button have a rollover
//rollsound is a dumb hack i did to keep the sound from repeating when remaining on top of the same button

#include <SDL/SDL.h>
#include <SDL/SDL_Mixer.h>

int main(int argc, char* argv[])
{
	int audio_rate = 22050;
	Uint16 audio_format = AUDIO_S16SYS;
	int audio_channels = 2;
	int audio_buffers = 4096;
	Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers);
	Mix_Chunk *roll = NULL;
	roll = Mix_LoadWAV("sounds/roll.wav");
	int rollSound = -1;

	for (x = 0; x < menuButtons.size(); x++)
	{
		if(menuButtons[x]->withinMe(mouseX, mouseY))
		{
			menuButtons[x]->setFrame(1);
			if(rollSound != x)
			{
				channel = Mix_PlayChannel(-1, roll, 0);
				rollSound=x;
			}
		}
		else
		{
			menuButtons[x]->setFrame(0);
			if(x==rollSound)
				rollSound = -1;
		}
	}

	Mix_FreeChunk(roll);
	Mix_CloseAudio();	
	return 0;
}





[Edited by - mindrot on August 3, 2007 1:18:46 PM]

Share this post


Link to post
Share on other sites
hrm
perhaps i need to clarify the results a bit

when i roll over a button
it seems to 'queue' the sound up
then play them in order
so if i roll over 10 buttons
and move mouse away
i still have to wait for all 10 sounds to play to completion, in order
so my mouse is still, 10 seconds latter my rollover sound chunks finish

do i need to include each sound on its own channel?

Share this post


Link to post
Share on other sites
I think the main problem you're running into is in the line " channel = Mix_PlayChannel(-1, roll, 0); ". If you look at the documentation Wiki for SDL_mixer it says "SDL_Mixer will choose a channel for you if you pass -1 for channel." If you don't want it to pick an unused channel and play more than one instance of the sound at a time, you need to specify a specific a channel, such as channel 0. This way the sound will be interrupted if you encounter another instance of a menu rollover.

Share this post


Link to post
Share on other sites
hrm that didnt seem to work.
its still seems to queue the results so if you quickly mouse over all the three buttons, then hover off them - it will play the sound several times before there is silence.
placing a halt(-1) in front of the play doesnt work either. same results.
i dont bother storing the channel play returns because i manually assign it
and i should be overwriting it. anyways.
sorry to ressurect a post but i wanted to post a sample program i did
anyone should be able to post think into a new project and execute it.
linker options:
-lmingw32
-lSDLmain
-lSDL
-lSDL_mixer
-mwindows

SDL.dll
SDL_mixer.dll
in local directory.
youll need to fill sounds/roll.wav with something
:)



#include <SDL/SDL.h>
#include <SDL/SDL_Mixer.h>
#include <vector>

#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 786
#define SCREEN_BPP 32

#define BLACK SDL_MapRGB(screen->format, 0, 0, 0)
#define GREY SDL_MapRGB(screen->format, 100, 100, 100)
#define WHITE SDL_MapRGB(screen->format, 255, 255, 255)
#define RED SDL_MapRGB(screen->format, 255, 0, 0)
#define GREEN SDL_MapRGB(screen->format, 0, 255, 0)
#define BLUE SDL_MapRGB(screen->format, 0, 0, 255)
#define YELLOW SDL_MapRGB(screen->format, 255, 255, 0)
#define MENUBLUE SDL_MapRGB(screen->format, 0, 0, 15)
#define TRANS SDL_MapRGB(screen->format, 255, 0, 255)

void init();
void input();
void draw();

bool done = false;
SDL_Surface* screen = NULL;
int mouseX = 0;
int mouseY = 0;

class button
{
public:
SDL_Rect me;
bool newRoll;
bool withinMe(int x, int y)
{
if((x > me.x) && (y > me.y))
if((x < me.x + me.w) && (y < me.y + me.h))
return true;
return false;
}
void drawMe(SDL_Surface* dest)
{
SDL_FillRect(dest, &me, RED);
}
};
button a;
button b;
button c;

Mix_Chunk *sound1 = NULL;

std::vector<button> buttons;

int main(int argc, char *argv[])
{
int x = 0;
init();
while(!done)
{
input();
for(x=0; x<buttons.size();x++)
{
if(buttons[x].withinMe(mouseX, mouseY))
{
if(buttons[x].newRoll)
{
buttons[x].newRoll = false;
Mix_PlayChannel(0, sound1, 0);
}
}
else
{
buttons[x].newRoll = true;
}
}

draw();
}
Mix_FreeChunk(sound1);
Mix_CloseAudio();
return 0;
}

void init()
{
atexit(SDL_Quit);
SDL_Init (SDL_INIT_EVERYTHING);
SDL_WM_SetCaption ("Sound Test", NULL);
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_ANYFORMAT);

buttons.push_back(a);
buttons.push_back(b);
buttons.push_back(c);
int x;
for(x=0; x<buttons.size(); x++)
{
buttons[x].newRoll = true;
buttons[x].me.w = 200;
buttons[x].me.h = 50;
buttons[x].me.x=100;
buttons[x].me.y=50+ x*buttons[x].me.h + (x*10);

}

int audio_rate = 22050;
Uint16 audio_format = AUDIO_S16SYS;
int audio_channels = 2;
int audio_buffers = 4096;
if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0)
{
printf("Unable to initialize audio: %s\n", Mix_GetError());
exit(1);
}


sound1 = Mix_LoadWAV("sounds/roll.wav");
}

void input()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN: done = 1; break;
case SDL_MOUSEMOTION: mouseX = event.motion.x; mouseY = event.motion.y; break;
case SDL_MOUSEBUTTONDOWN: break;
case SDL_MOUSEBUTTONUP: break;
case SDL_QUIT: done=1; break;
default: break;
}
}
}

void draw()
{
SDL_FillRect (screen, NULL, WHITE);
int x;
for(x=0; x<buttons.size(); x++)
buttons[x].drawMe(screen);
SDL_Flip(screen);
}




Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this