Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Audio seems overly complicated :(

This thread is locked; no one can reply to it. rss feed Print
 1   2   3   4 
Audio seems overly complicated :(
Niunio
Member #1,975
March 2002
avatar

Do you really need 7 channel sound?

I've wrote a PSG for my engine, and the only way I've found to do it easily was using a channel per wave generator. So if I want to emulate (say) MSX sound then I have no problem (3 channels). I can deal with NES sound too (5 channels). But I want to use PC-MIDI sound too (+16 channels) and I have no idea how to do that.

May be it is possible to do it differently (binding more than one stream per channel?) but I haven't found the way by just reading the documentation. May be I didn't understood it correctly. ???

-----------------
Current projects: Allegro.pas | MinGRo

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

nshade said:

OHMYGOD I FOUND THE BUG!

Surely you compiled in debug mode? Why didn't it fail any asserts? Also, if you look at the syntax highlighting on your pastebin code in the mentioned loading section, you can see several escape sequences. Yes, always use forward slashes, or ALLEGRO_NATIVE_PATH_SEP.

NiteHackr
Member #2,229
April 2002

That's pretty simple. Just like Allegro 4.

Yuppers, I did that in Deluxe Pacman 2. Play the game, it's 100% Allegro 5, uses sound etc... just certain things are more involved than they were in Allegro 4. Needlessly more involved in order to add in more features that most people just do not need.

But anyhow, I was able to make my game with it anyhow and I hacked my way around the A5 limitations.

Why comment? Because if this was fixed, and from what I remember from this conversation YEARS ago, it would not be a difficult thing to add in some defaults which would have remedied the problems I experienced. It would probably make Allegro 5 more attractive to those who just want to make a game up quickly without jumping through hoops to do simple things. Now as stated, I found another library that can do it easily, so why bother coming to these forums? Because I prefer Allegro, I have a long history with it. But there is also a long history of rude responses like what you give to anyone who dares to criticize something about it.

I would rather see the library improved and the complexities removed. It would help it gain in popularity again I think. If I had the skill to work on it myself I would. But one look at that source was scary. ;)

Chris Katko
Member #1,881
January 2002
avatar

Neil Roy said:

I would rather see the library improved and the complexities removed. It would help it gain in popularity again I think. If I had the skill to work on it myself I would. But one look at that source was scary. ;)

So write it and submit a pull request and we'll compare the two.

Quote:

But one look at that source was scary. ;)

Honestly, it's not so bad. You just keep staring and building notes and any large codebase eventually starts sinking in. Especially ones that weren't clobbered together by non-programmers / super-fast for a past-due job.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Basic structure of allegro is like this :

1. There's a system driver, determined at compile time.
2. There's different sub system drivers, again limited to those with support compiled in.

Each driver is basically a vtable, or a set of function pointers. The allegro functions call the system drivers vtable functions, so this allows for dynamic behavior, across platforms, and at run time if desired.

The best way to understand allegro is to use gdb and set a breakpoint on a function your curious about. It's as simple as 'break al_create_voice', then you step through the code with 'next' and 'step' to step into function calls. It tells you where you are as you go, listing source code line numbers. You can 'list' code, and you can 'print $VAR' variables to examine things. When you get something interesting like a system driver function call you can print the pointer to the system driver, and then print the function pointer it refers to to see which function it is actually calling. Then you can set a breakpoint inside that function, run the program again, and repeat until you find out what's wrong.

EDIT

I will say this about the audio API, it sucks that there is no companion function to al_play_sample for sample instances. You have to set all the things manually. al_play_sample_instance does not do the same thing, and doesn't allow you to modify the sound as it's created. I think it should create a new sample instance and set it's parameters and start it playing and return bool on success.

But it only took 5 secs to write one so, ... ;

ALLEGRO_SAMPLE_INSTANCE* Sound::Play(ALLEGRO_MIXER* mixer , float gain , float pan , float speed , ALLEGRO_PLAYMODE mode) {
   ALLEGRO_SAMPLE_INSTANCE* instance = al_create_sample_instance(sample);
   al_attach_sample_instance_to_mixer(instance , mixer);
   al_set_sample_instance_gain(instance , gain);
   al_set_sample_instance_pan(instance , pan);
   al_set_sample_instance_speed(instance , speed);
   al_set_sample_instance_playmode(instance , mode);
   al_set_sample_instance_playing(instance , true);
   instances.push_back(instance);
   return instance;
}

nshade
Member #4,372
February 2004

I don't have any asserts in my code as I'm dealing with 23 year old C code and I'm compiling in VS2015. It's not the first time My compiler silently just let it go. It also tends to gloss over functions with the wrong number of arguments too.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

See my edit.

As for your compiler, you should still be compiling against the debugging libs so that asserts in allegro will fail. That's what I was talking about.

EDIT
Here's a new demo. Same controls as before but now keys 1 thru 9 play a sound. Press repeatedly to spawn new instances.

Sound.zip (win32 binary + src + data)

Chris Katko
Member #1,881
January 2002
avatar

nshade said:

I don't have any asserts in my code as I'm dealing with 23 year old C code

Start adding them!!! Any of your assumptions for how code should work. If it constantly fails, it's either a bug... or... a mistaken assumption!

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Polybios
Member #12,293
October 2010

Just want to drop in to emphasize that al_reserve_samples is "the easy audio route" together with al_play_sample. See:
http://liballeg.org/a5docs/trunk/audio.html#al_reserve_samples
http://liballeg.org/a5docs/trunk/audio.html#al_play_sample

The former keeps a set of sample instances attached to the default mixer (attached to the default voice) that it reuses when you call the latter.

I don't think that mixing this with an individual complex setup is a good idea.
IIRC, the way to do it is to manage sample instances yourself and attaching them to a mixer.

I think I've contributed some of the introductory paragraphs (minus the nice illustration) to the manual for the audio addon. If there's something unclear or confusing (in the manual), please report.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I was trying to note earlier that you can still modify the sample instances at runtime, even if you use al_play_sample. You get back an ALLEGRO_SAMPLE_ID that you can use with al_lock_sample_id to get back an ALLEGRO_SAMPLE_INSTANCE*.

bamccaig
Member #7,536
July 2006
avatar

I don't have much to contribute here, other than to agree with the OP. I have never programmed audio into a program before (unless you count messing with text-to-speech in JavaScript) and I recall a few months ago I was trying to figure out how to generate sound in Allegro 5. I was completely lost and the documentation wasn't very helpful at all. I'm sure it's very useful to somebody that already knows how to do it, but that's kind of useless to the majority of people that are going to be reading it. The documentation for a library with the history of Allegro should be written for the complete beginner that has no idea what any of these things are, and just wants to make sounds come out of his headphones, whether it's from existing recordings or raw.

NiteHackr
Member #2,229
April 2002

In my Deluxe Pacman 2 game, which uses Allegro 5, playing sound effects and music; I use OGGs for both sound effects and music, so the only difference is I flag the sound samples to only be played once, and I flag the music to be looped. It's all pretty simple. My only complaint was that in order to do more, like gradually change the pitch of a looping sound sample, it was much more involved.

As it is, this is basically all you need to do in Allegro 5 to simply play a sound sample, whether once or looped. It IS very simple, for just this. It's just that if you want to do more, you will need to set up a lot more. Too much I felt when you consider that I could do the same in Allegro 4 with the gradual pitch change without any extra effort compared to Allegro 5.

But to be fair, here's all you need to do to play basic sounds and music...
(note: the a5_error() and shut_down() are my own personal functions I created)

#SelectExpand
1// Initialize audio 2if(!al_install_audio()) { 3 a5_error(AT, setting.screen, "al_install_audio() failed."); 4 shut_down(); 5 exit(1); 6} 7if(!al_init_acodec_addon()) { 8 a5_error(AT, setting.screen, "al_init_acodec_addon() failed."); 9 shut_down(); 10 exit(1); 11} 12 13if(!al_reserve_samples(16)) { 14 a5_error(AT, setting.screen, "al_reserve_samples() failed."); 15 shut_down(); 16 exit(1); 17} 18 19// Load in a sound sample 20ALLEGRO_SAMPLE *sfx_pill = NULL; 21sfx_pill = al_load_sample("Sound/Pill.ogg"); 22if(!sfx_pill) { 23 a5_error(AT, setting.screen, "Failed to load Pill.ogg"); 24 shut_down(); 25 exit(1); 26} 27 28// Play sound sample once 29al_play_sample(sfx_pill, setting.sound_volume, 0, 1, ALLEGRO_PLAYMODE_ONCE, NULL); 30 31 32// When done, clean up and shut it all down 33al_stop_samples(); 34 35al_destroy_sample(sfx_pill); 36sfx_pill = NULL; 37 38al_uninstall_audio();

...this was pulled out of my DP2 game.

The pitch does change at regular intervals in my game, but not constantly like DP1. To do this, I regularly check the number of pills left and based on the percentage, I will actually stop the background sample from playing and restart it at a new pitch. This was my work around as I could not change it while it played without doing a lot more, and while I probably could have done it, I felt it was a lot of extra work for JUST changing the pitch.

Now it was pointed out that I could have "simply" used al_set_sample_instance_speed().

But that requires ALLEGRO_SAMPLE_INSTANCE.

To quote the docs:
“To be played, an ALLEGRO_SAMPLE_INSTANCE object must be attached to an ALLEGRO_VOICE object, or to an ALLEGRO_MIXER object which is itself attached to an ALLEGRO_VOICE object (or to another ALLEGRO_MIXER object which is attached to an ALLEGRO_VOICE object, etc).”

When all I wanted to do was change the pitch on one sample, you can see why I didn't want to go through setting all the rest of that up JUST to change the pitch. I opted instead to change it less frequently, basically it changes in DP2 when 75%, 50%, and 25% of the pills are left. As stated, I shut down the sample and restart it with the new pitch setting. Which ironically, is more like how the original arcade game does it.

When searching for some information about this, I found in mildly amusing that I came across this post from Edgar back in 2015 when he had problems with Allegro's audio in t his thread...

https://www.allegro.cc/forums/thread/615723

His final post in that thread was: "Yeah, that's pretty confusing" :) No offence Edgar but even you found all of it confusing when you tried it.

bamccaig
Member #7,536
July 2006
avatar

This is the program that I tried.

src/main.c#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_acodec.h> 3#include <allegro5/allegro_audio.h> 4#include <allegro5/allegro_font.h> 5#include <allegro5/allegro_ttf.h> 6#include <stdio.h> 7#include <stdlib.h> 8 9#define notes_length (sizeof(notes) / sizeof(ALLEGRO_SAMPLE *)) 10 11#define say_center(w, h, text) \ 12 (al_draw_text(musicals, white, w, h, ALLEGRO_ALIGN_CENTRE, text)) 13 14#define play_note(i) \ 15 (al_play_sample( \ 16 notes[i], \ 17 3.0, 0.0, 1.0, \ 18 ALLEGRO_PLAYMODE_ONCE, \ 19 &sample_ids[i])) 20 21static const char abcdefg[] = "abcdefg"; 22 23int main(int argc, char * argv[]) 24{ 25 char tmp[8] = " "; 26 int i = 0, l = -1; 27 int playing[7] = {0}; 28 int status = 0; 29 ALLEGRO_COLOR black, white; 30 ALLEGRO_DISPLAY * display = NULL; 31 ALLEGRO_EVENT_QUEUE * event_queue = NULL; 32 ALLEGRO_FONT * musicals = NULL; 33 ALLEGRO_SAMPLE * notes[7] = {0}; 34 ALLEGRO_SAMPLE_ID sample_ids[7] = {0}; 35 ALLEGRO_TIMEOUT timeout; 36 37 if (!al_init()) { 38 fprintf(stderr, "al_init failed\n"); 39 goto error; 40 } 41 42 if (!al_install_keyboard()) { 43 fprintf(stderr, "al_install_keyboard failed\n"); 44 goto error; 45 } 46 47 if (!al_install_audio()) { 48 fprintf(stderr, "al_install_audio failed\n"); 49 goto error; 50 } 51 52 if (!al_init_acodec_addon()) { 53 fprintf(stderr, "al_init_acodec_addon failed\n"); 54 goto error; 55 } 56 57 if (!al_init_font_addon()) { 58 fprintf(stderr, "al_init_font_addon failed\n"); 59 goto error; 60 } 61 62 if (!al_init_ttf_addon()) { 63 fprintf(stderr, "al_init_ttf_addon failed\n"); 64 goto error; 65 } 66 67 display = al_create_display(1440, 900); 68 69 if (display == NULL) { 70 fprintf(stderr, "al_create_display failed\n"); 71 goto error; 72 } 73 74 event_queue = al_create_event_queue(); 75 76 if (event_queue == NULL) { 77 fprintf(stderr, "al_create_event_queue failed\n"); 78 goto error; 79 } 80 81 if (!al_reserve_samples(7 * 7)) { 82 fprintf(stderr, "al_reserve_samples failed\n"); 83 goto error; 84 } 85 86 for (i=0,l=notes_length; i<l; i++) { 87 char filename[22] = "media/Piano.pp.A3.ogg"; 88 89 filename[15] = 'A' + i; 90 91 if (filename[15] > 'B') { 92 filename[16] = '4'; 93 } 94 95 notes[i] = al_load_sample(filename); 96 97 if (notes[i] == NULL) { 98 fprintf(stderr, "al_load_sample %s failed\n", filename); 99 goto error; 100 } 101 } 102 103 musicals = al_load_ttf_font("musicals.ttf", 72, 0); 104 105 if (musicals == NULL) { 106 fprintf(stderr, "al_load_ttf_font failed\n"); 107 goto error; 108 } 109 110 al_register_event_source(event_queue, 111 al_get_display_event_source(display)); 112 113 al_register_event_source(event_queue, 114 al_get_keyboard_event_source()); 115 116 black = al_map_rgb(0, 0, 0); 117 white = al_map_rgb(255, 255, 255); 118 119 al_init_timeout(&timeout, 0.06); 120 121 while (1) { 122 int w = al_get_display_width(display); 123 int h = al_get_display_height(display); 124 ALLEGRO_EVENT ev; 125 126 if (al_wait_for_event_until(event_queue, &ev, &timeout)) { 127 switch (ev.type) { 128 case ALLEGRO_EVENT_DISPLAY_CLOSE: 129 goto clean; 130 break; 131 case ALLEGRO_EVENT_KEY_DOWN: 132 if (ev.keyboard.keycode >= ALLEGRO_KEY_A && 133 ev.keyboard.keycode <= ALLEGRO_KEY_G) { 134 i = ev.keyboard.keycode - ALLEGRO_KEY_A; 135 tmp[i] = abcdefg[i]; 136 137 if (playing[i] == 0) { 138 playing[i] = play_note(i); 139 } 140 } else { 141 switch (ev.keyboard.keycode) { 142 case ALLEGRO_KEY_ESCAPE: 143 case ALLEGRO_KEY_Q: 144 goto clean; 145 } 146 } 147 148 break; 149 case ALLEGRO_EVENT_KEY_UP: 150 if (ev.keyboard.keycode >= ALLEGRO_KEY_A && 151 ev.keyboard.keycode <= ALLEGRO_KEY_G) { 152 i = ev.keyboard.keycode - ALLEGRO_KEY_A; 153 tmp[i] = ' '; 154 155 if (playing[i] != 0) { 156 al_stop_sample(&sample_ids[i]); 157 playing[i] = 0; 158 } 159 } 160 break; 161 } 162 } 163 164 al_clear_to_color(black); 165 166 say_center(w / 2.0, h / 2.0, "abcdefg ABCDEFG"); 167 say_center(w / 2.0, h / 2.0 + 100, tmp); 168 169 al_flip_display(); 170 } 171 172clean: 173 for (i=0,l=notes_length; i<l; i++) { 174 if (notes[i]) al_destroy_sample(notes[i]); 175 } 176 if (musicals) al_destroy_font(musicals); 177 if (event_queue) al_destroy_event_queue(event_queue); 178 if (display) al_destroy_display(display); 179 180 return status; 181 182error: 183 status = 1; 184 goto clean; 185}

I don't remember where I got the sound files from, but Google suggested here. That seems likely. At the very least, it'll probably suffice. That appears to be MIT licensed.

The font appears to be available from here (but you can probably substitute any other font). It should be free for personal use.

Anyway, the initial intent was a sort of QWERTY piano. This was the first experiment. What I found is that typing doesn't produce consistent sounds. It seems very limited in what it can do and I couldn't figure out why. Can you spot my errors?

NiteHackr
Member #2,229
April 2002

I found my old post from 2013 where I tried to figure this out. Read Matthew's reply and you will see why I didn't bother. When you wish to loop your sound, or adjust it, you have to manage every aspect of it playing yourself, even loops which is nuts.

It's been five years, but after reading his reply to me back then, it all came back to me. It was more than simply adjusting the pitch, it was also looping a sound. If you want to play a sample more than once, you have to manage that on your own which seems to me to be a tad much. And back then this was not documented and I still don't think it is from what I have seen.

https://www.allegro.cc/forums/thread/613153

bamccaig said:

Can you spot my errors?

This is all you need to play a sample: al_play_sample(sample, volume, 0, 1, ALLEGRO_PLAYMODE_ONCE, NULL);

I noticed you store a sample id, but if you're only playing it once, there's no need, just use NULL as I have above. Unless there is something you wish to track about it (like in my game I used the id so I could stop the sample later on and change the pitch then restart it, otherwise I didn't need an id). Your code looks fine honestly. I reserve 16 samples in my own code and that works, not sure why you have 7*7? I don't know what the maximums are, but if that passes okay...

I honestly don't know what your problem could be. :/

bamccaig
Member #7,536
July 2006
avatar

It actually sounds like your thread from 5 years ago is needed for my purpose. From the sounds of it, you cannot replay a sample until it stops unless you instantiate many sample "instances" off of it and play those instead... But to do that I have to define a voice and a mixer myself? I have a confession to make. I have no idea what a voice or a mixer is. ;) The docs don't help me with that problem. Here's the thing: TFM doesn't seem to say anything about audio unless I'm bypassing the wordy bit. It's just a list of symbols. That's useless to everybody that didn't write the addon and has never used it before.

From the sounds of it a "voice" is supposed to represent the hardware or a virtual device provided by the OS, and a "mixer" is a mechanism to combine several buffers into a single buffer. This is starting to almost make sense, no thanks to TFM, but I haven't actually attempted to translate this so called knowledge into code yet. That's usually the hard part.

Append:

I get lost on the "frequency" hint that you're supposed to pass to a voice/mixer. I'm not a sound engineer. I can attempt to lookup frequencies for the various notes I intend my program to support, but why does the "device" or "buffer combiner" need or want to know about what frequencies I'm going to play? Is that for surround sound setups or what? Supposing the user did have a 7.1 surround system does that mean my program needs to be different for them than for me using just headphones? This is the complexity I think we're talking about. I shouldn't need to think about the hardware here. I don't think I should need to think about what sounds I'll be playing. I should just be able to play sounds, goddamnit.

Audric
Member #907
January 2001

This frequency indicates the sound quality that this mixer will operate. 44100 will make this mixer output 44100 values per second, the same as a CD.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

It really isn't hard to get your sound to pan and change pitch and all that. All you need is an ALLEGRO_SAMPLE_INSTANCE*. I showed you a function to easily create a sound and attach it to a mixer earlier :

ALLEGRO_SAMPLE_INSTANCE* PlaySample(ALLEGRO_SAMPLE* sample , ALLEGRO_MIXER* mixer , float gain , float pan , float speed , ALLEGRO_PLAYMODE mode) {
   ALLEGRO_SAMPLE_INSTANCE* instance = al_create_sample_instance(sample);
   al_attach_sample_instance_to_mixer(instance , mixer);
   al_set_sample_instance_gain(instance , gain);
   al_set_sample_instance_pan(instance , pan);
   al_set_sample_instance_speed(instance , speed);
   al_set_sample_instance_playmode(instance , mode);
   al_set_sample_instance_playing(instance , true);
   return instance;
}

I made a simple example as well that demonstrates changing the pan and speed of the sound using the mouse here :

Mixer2.zip (win32 src + binary + data)

As for bambams, al_reserve_samples takes the maximum number of samples that you want to play at a time. You'd probably be best off with 4, or 8 if you don't want to manage sample instances yourself. Using a large number here makes your sounds quieter since they all have to be mixed together.

Also, as I noted earlier, you can get an ALLEGRO_SAMPLE_INSTANCE* from an ALLEGRO_SAMPLE_ID, and adjust playing sounds.

NiteHackr
Member #2,229
April 2002

I made a simple example as well that demonstrates changing the pan and speed of the sound using the mouse here

I'll take a look at that.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

bamccaig
Member #7,536
July 2006
avatar

Niunio
Member #1,975
March 2002
avatar

bamccaig said:

I don't have much to contribute here, other than to agree with the OP. I have never programmed audio into a program before (unless you count messing with text-to-speech in JavaScript) and I recall a few months ago I was trying to figure out how to generate sound in Allegro 5. I was completely lost and the documentation wasn't very helpful at all. I'm sure it's very useful to somebody that already knows how to do it, but that's kind of useless to the majority of people that are going to be reading it. The documentation for a library with the history of Allegro should be written for the complete beginner that has no idea what any of these things are, and just wants to make sounds come out of his headphones, whether it's from existing recordings or raw.

Thank you! :-*

I hope somebody updated the documentation and adds all this seemingly* useful information of yours.
______________________

* I didn't test it yet and not sure I've understood it.

-----------------
Current projects: Allegro.pas | MinGRo

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

He was also reading documentation from over 3 years ago. :P

Niunio said:

I hope somebody updated the documentation and adds all this seemingly* useful information of yours.

This is why nothing ever gets done. I hope somebody updated the docs for me...

If there are changes you want to see made to the documentation, post them! If you have questions, ask them! I am more than glad to make the corresponding edits for you, and submit a pull request, but you have to give me content!!!

So this doesn't degenerate into a "it's too complicated" "no, it's not" again, for all of those who find the manual or the audio system in allegro to be too complicated, post specific concerns, and I will address them one by one. You have to be specific though.

I will start.

1. I don't understand how sample instances are 'reserved'. Sure, al_reserve_samples will generate empty sample instances and attach them to the default mixer, but what about mixers that you create yourself? How are the number of sample instances 'attached' to a mixer? Does the mixer scale the sound automatically based on how many sample instances are attached? Or do we need to manage that ourselves? Is there something akin to al_reserve_samples that we need to do for custom mixers?

Audric
Member #907
January 2001

I'm a bit surprised that the recommended setup is a single voice, because if I understand correctly, it means the mixing is made in software. But soundcards have dozens of channels dedicated to hardware mixing (151 on the venerable Sounblaster Live) ?
I understand that on a multitasking system I can't count on grabbing all hardware resources, but 8 or 16 sound channels on a "main task" videogame doesn't sound overkill.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I'm not a sound guru so I don't really know how these things work. It definitely seems to me that you should be able to create multiple voices, or install sound across multiple devices, but I have no idea how hard that is. The windows audio interface is not the best anymore. I used to be able to record sound directly from hardware, so I could record a song playing live via the radio and a double ended stereo plug. I don't know how to do that anymore. I used it to great effect to dub some of my old cassette tapes onto the HDD.

Elias
Member #358
May 2000

Sure, al_reserve_samples will generate empty sample instances and attach them to the default mixer, but what about mixers that you create yourself?

There is basically two sound APIs, the al_reserve_samples/al_play_sample one and the complicated one. In the former one you use al_install_audio(), al_reserve_samples(), al_load_sample() and al_play_sample() for playing samples. You cannot use anything else. You would especially not use any mixer or voice functions at all. As simple as it gets really. al_play_sample() allows you to set volume, pan and speed for each sample so there even is some limited control.

Most games also need to play music, so to do that in addition to the above you would use al_create_mixer(), al_load_audio_stream(), al_attach_audio_stream_to_mixer() and al_attach_mixer_to_mixer. This will give you music which can play in parallel to your samples above and with a separate volume control for just the music.

For anything else, like using samples on a mixer other than the default mixer, you would not use al_reserve_samples() or al_play_sample() at all. Those two functions are unnecessary and are basically a separate audio addon which was added much later because the normal audio is way too complicated :P

--
"Either help out or stop whining" - Evert

 1   2   3   4 


Go to: