After you know how server-side object creation works, what stereo effects are, and how you can get them running, it would be a nice idea to actually do this in an example. Next, let's write something similar to Example_ADD that works like a StereoEffect. First, what should it do? I thought it may be useful to emulate the standard options you have for balance at every amplifier: keep stereo as it is, keep left channel only, keep right channel only, reverse channels, and downmix stereo. First, you need a representation for these states. That is done best using an enumeration value. So you get the following: Then, you need to make the interface derive from StereoEffect. Thus, no streams need to be declared at all because StereoEffect already does this. The interface looks as simple as this: That's all. Put it into a file balance.idl and invoke mcopidl: | |
Now to the implementation. First to the attribute stuff; these are mapped, as I mentioned previously, to two functions: one that changes the value and one that queries it. They are both called balance. One gets a parameter to set a new value, and one returns the old value. You should also have an internal variable to store the current state (it's called _balance here), and initialize this properly in the C++ constructor. Up to now, you have the following: The method that is still missing is calculateBlock. The most important thing to watch here is that the volume doesn't change through our balance control. That means, for downmix (mixing the left and right stereo channels to mono output), you shouldn't simply add everything, but divide by two. The other cases shouldn't be hard to handle. Here is the rest of the code, then, while you are left with some cases to write, too: | |
Because you want to be able to load and use the effect inside the server, put it into a library that can be dynamically loaded. To do so, you'll also create a class definition called StereoBalanceControl.mcopclass, with the following content: Because making is a bit difficult, the following is a makefile again, for making the whole module: Thus, compilation and installation are simply done with although you may need to do the last as root (that is, su root -c 'make install'). Okay, now you have installed an effect, which should be dynamically loadable into the server. To try it out, Listing 14.4 is a test program:
Example 14.4. Running StereoBalanceControl on the Server 1
2 1: #include "balance.h"
3 2: #include <soundserver.h>
4 3: #include <stdio.h>
5 4:
6 5: using namespace Arts;
7 6:
8 7: void fail(char *why) { printf("%s\n",why); exit(1); }
9 8:
10 9: int main(int argc, char **argv)
11 10: {
12 11: if(argc != 2) fail("use two arguments");
13 12:
14 13: Dispatcher dispatcher;
15 14: SimpleSoundServer server(Reference("global:Arts_SimpleSoundServer"));
16 15: if(server.isNull()) fail("can't connect server");
17 16:
18 17: StereoBalanceControl bcontrol;
19 18: bcontrol = DynamicCast(server.createObject("StereoBalanceControl"));
20 19: if(bcontrol.isNull()) fail("can't create object");
21 20:
22 21: if(strcmp(argv[1],"downmix") == 0)
23 22: bcontrol.balance(sbDownMix);
24 23: if(strcmp(argv[1],"through") == 0)
25 24: bcontrol.balance(sbThrough);
26 25: /* add the others possibilities, if you like */
27 26: bcontrol.start();
28 27:
29 28: StereoEffectStack effectstack = server.outstack();
30 29: long id=effectstack.insertBottom(bcontrol,"Balance");
31 30: printf("type return to quit\n"); getchar();
32 31: effectstack.remove(id);
33 32: return 0;
34 33: }
35 |
Finally, to get that running, do the following: First compile That is everything in one line. Then call ldconfig as root (to get your freshly installed library registered): Make sure that something is running on the soundserver (for instance, listen to an MP3 or .wav), and then type That should downmix the stuff that is played. As you can see, running objects server side is really easy through MCOP. Imagine what the overhead would be like if you needed to transfer all data from the server to the setbalance program, which would do the calculations, and you had to transfer everything back again. | |
| |