Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Control multiple versions of the same sound

This thread is locked; no one can reply to it. rss feed Print
Control multiple versions of the same sound
DavyKager
Member #8,299
February 2007

Hi!

I am building an audiogame based on Allegro, but I encounter some problems during the process. As I've said before, I'm an absolute beginner, so excuse me for asking this stupid things. :)

I'd like to have multiple versions of the same sound playing, which I can control seperately. The last is possible with Voice Control, but I need to specify a voice so I can adjust it.
Now I'm trying to make a function like this:
place_objet(x_position, y_position, ID);
The ID will name the voice where the sound is playing, but these are automatically asigned. Thus I can't do things like:
asigned. Thus I can't do things like:
place_objet(20, 30, 1); // Object #1
place_objet(50, 90, 2); // Object #2

So, I have to obtain the voice where the sound is playing with allocate_voice, but at the same time I already need this voicenumber, because it should be my ID.

I know this is not very common, but does someone get my point and maybe can provide some help?

Tobias Dammers
Member #2,604
August 2002
avatar

First allocate, then adjust. Store the ID in a member var of your object.
The hard part is not this, but dealing with "too many" objects (that is, when you can't allocate enough voices for all your objects).

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

DavyKager
Member #8,299
February 2007

I just don't know how to do this in another way.

My problem is that I want to make multiple objects at the same time. And if Allegro gives me a voicenumber, and I store that, and then build up a new object (from the same function) it'll override the original one, isn't it?

Tobias Dammers
Member #2,604
August 2002
avatar

No.
You keep the same object, and initialize its voice to "undefined" (0 or -1, don't remember, please read the manual). As soon as you allocate a voice, store its index in the object, and after that, use the stored id to access the sound. When you free the sound, set the stored id back to undefined.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

gnolam
Member #2,030
March 2002
avatar

Quote:

So, I have to obtain the voice where the sound is playing with allocate_voice

Or just use the value returned by play_sample().

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

DavyKager
Member #8,299
February 2007

So you think it's possible to place objets (stones, cars, whatever) with just one function which will manage all the objects simultaniously?

Dustin Dettmer
Member #3,935
October 2003
avatar

Better to allow only 1 instance of a sound to play at once.

The more sounds you play the lower the sound quality. If you get too many playing at once it will sound awful and you lose the point of playing sounds in the first place.

Also remember the old saying KISS, Keep It Simple, Stupid.

DavyKager
Member #8,299
February 2007

Alright, but this is going to be an audiogame... :)

Tomorrow I'll try classes and arrays (good practice!).

Audric
Member #907
January 2001

You don't select the voices number yourself... If you have any sound program running (Winamp), you could have ANY voices busy and unavailable to Allegro - and it probably won't be as simple as voices 0 and 1.
You'll have to uniquely identify your objects, without relying on the voices numbers.
Something like:

1typedef struct
2{
3 int x_position;
4 int y_position;
5 int voice; // allegro voice
6} SOUND_OBJECT;
7 
8// SOUND_OBJECT allocator and "constructor"
9SOUND_OBJECT *place_object(int _x, int _y, const SAMPLE *spl)
10{
11 SOUND_OBJECT *ob;
12 ob = malloc(sizeof(SOUND_OBJECT));
13
14 ob->x_position = _x;
15 ob->y_position = _y;
16 // allegro gives the voice number
17 ob->voice = allocate_voice(spl);
18 // should check for -1 here (no more voices available)
19 
20 return ob;
21}
22 
23(...main program...)
24 
25engine_noise = load_sample("engine.wav");
26 
27SOUND_OBJECT * sounds[8]; // games uses 8 voices, for example
28 
29sounds[0] = place_object(10, 30, engine_noise);
30// etc.

edit: argh, I just saw the word "classes" in your post.. I should have made it C++ instead of C++-like.

DavyKager
Member #8,299
February 2007

I have made a class where a function runs that places objects. Now I'm able to do this:

object ob1;
ob1.x_position = 30;
ob1.y_position = 20;
ob1.place(); // Do it!

I can play one object, and I think I can also make it adjust the sample. And this afternoon I'll try to make it working for multiple objects (won't be too hard using classes I hope).

Richard Phipps
Member #1,632
November 2001
avatar

There is a design flaw (IMHO) in Allegro's sound handling which makes it difficult to play a sample using a specific voice. You have to let Allegro find a voice and then manipulate that voice channel.

Tobias Dammers
Member #2,604
August 2002
avatar

This is not a design flaw, it's how the api works. It is similar to when you allocate a pointer or a handle: you will get whatever free space the memory allocation algorithm finds for you. You can't say, for example:

int* p = new int at 0x00AA1234;

Allegro's voices work exactly the same, only that the address space is "a little" smaller.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

DavyKager
Member #8,299
February 2007

By the way, am I right that adjust_sample(*spl); adjusts the first one that it finds. So, if you make two samples, the first one is always adjusted, even if you call adjust_sample() multiple times?

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

Allegro's voices work exactly the same, only that the address space is "a little" smaller.

If you want to keep a voice number, you can use reallocate_voice. Just make sure it isn't set to deallocate automatically. Then you also have to worry about running out of voices.

Quote:

the first one is always adjusted, even if you call adjust_sample() multiple times?

It seems it might only modify the last one you played. Which seems to jive with the api, play_sample makes a voice that auto deallocates when finished, so you can't rely on the voice id existing and being usefull at all for any length of time.

For more complex sound using games, you MUST use the voice functions and ignore the play_sample function all together. play_sample is a fire and forget type interface.

edit: Actually play_sample returns the voice number for the voice it allocated, so you can use the voice functions with that if you wish. But its all the same really.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

DavyKager
Member #8,299
February 2007

If I play one sound with my own created class all is fine, but when I try to play two sounds, they're played at the far left side of the stereofield.
And now I wonder why that's happening. I thought that it maybe had something to do with the play_sample-function. But after reading this I guess that it is a problem in my class or something.

Thomas Fjellstrom
Member #476
June 2000
avatar

Maybe you're passing the pan value in wrong?

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

DavyKager
Member #8,299
February 2007

The pan variable is currently declared in the function itself (which is declared in the class), but that seems to trouble.

I know that this stuff isn't really common, although I hope to find a good solution quite soon. :)

Thomas Fjellstrom
Member #476
June 2000
avatar

Post the play_sample code you have. as well as some of the code arround it, so we can see how you're using it.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

DavyKager
Member #8,299
February 2007

I don't know if someone is able to understand it, but here we go...

The class:

class rock {
public:
       
       int rock_x;
       int rock_y;
       rock();
       ~rock();
       void adjust_rock(void);
};

1rock::rock() {
2 play_sample(rocky, 255, 128, 1000, TRUE);
3}
4rock::~rock() {
5 stop_sample(rocky);
6}
7void rock::adjust_rock(void) {
8
9 /* Declare local variables */
10 int left = rock_x - 128;
11 int right = rock_x + 128;
12 int back = rock_y - 128;
13 int front = rock_y + 128;
14 int pan;
15 int vol;
16
17 /* Calculate variables */
18 pan = 128 - (x - rock_x);
19
20 /* Adjust the sound */
21 adjust_sample(rocky, 255, pan, 1000, TRUE);
22}
23 
24And in the main-function:
25 rock rock1;
26 rock1.rock_x = 750;
27 rock1.rock_y = 0;
28while (!key[KEY_ESC]) {
29 rock1.adjust_rock();
30}

  • The variables that are not declared in this piece of code are declared globally.

  • I duplicate the code from the main-function to obtain a new sound (all in one loop).

Thomas Fjellstrom
Member #476
June 2000
avatar

Please use the

<code>code here</code>

tags :)

The only thing I can think at this point is the pan variable is getting to large or too small. try printf'ing or cout'ing the value of it when you modify it.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

DavyKager
Member #8,299
February 2007

One last question: Is it true that Allegro adjusts the volume when you pan a sound, and if so, can I prevent Allegro from doing that?

GullRaDriel
Member #3,861
September 2003
avatar

Do you really realize what pan mean ?

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

DavyKager
Member #8,299
February 2007

I meant: are there differences between the way adjust_sample and voice_set_pan works?

Some programs/mixers/whatever boost the volume of the left channel when you pan to the left. But others just cut down the volume of the right side (which is better in my opinion).

Edit: I found it! I needed set_volume_per_voice().

Go to: