Change/Control volume of current application.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

Change/Control volume of current application.

Weps
Hi there,

is there a way to control the volume of the current application?

Just to clarify, I have like 60 or so players, all

 uos_CreatePlayer( aPlayer);
 in_index := uos_AddFromMemoryStream( aPlayer, ms, 1, 0, -1, -1);
 output_index := uos_AddIntoDevOut( aPlayer, -1, 0.03, uos_InputGetSampleRate( aPlayer, in_index), -1, 0, -1, -1);

These functions seem to control the volume:
 uos_InputAddDSPVolume
 uos_OutputAddDSPVolume

but they require a player...

Isn't there a way to control just/only the volume of the device-out?




Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
Hello Weps and welcome to uos forum.

> but they require a player...

Not sure to understand.
Of course if you want to change the volume of a player you need that the player was created.

If the players are created, you may use a general slider associated to volume of each player.

Something like this:

procedure changevolumeallplayers ;
begin
  uos_InputSetDSPVolume(player1, Inputindex1,
        volumeleftplayer1 * volumeleftgeneral, volumerightplayer1 * volumerightlgeneral, true;

uos_InputSetDSPVolume(player2, Inputindex2,
        volumeleftplayer2 * volumeleftgeneral, volumerightplayer2 * volumerightlgeneral, true;

uos_InputSetDSPVolume(player3, Inputindex3,
        volumeleftplayer3 * volumeleftgeneral, volumerightplayer3 * volumerightlgeneral, true;

etc...

end;

Now if you want to control the general volume of the sound card, you may take a look at this:

For Linux: https://github.com/fredvs/alsa_mixer

For Windows: https://github.com/fredvs/win_mixer

There is a program that uses uos that does what you want, maybe you may take a look at source:
https://github.com/fredvs/strumpract

Fre;D
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

Weps
Hi Fred,

thanks for the response.


What I would like to know is whether there is a simple way to adjust the volume of ALL/ANY output produced by my program. Other programs that run on my computer should keep their current volume.

I understand that there is way to change the volume for a single uos_player, as you showed.

However, I have got something like 60 players. It seemd a bit strange I'ld have to change the volume of all players instead of just the one 'output-channel' that those 60 players go through.

I had a quick look at the links you gave, strumprac changes the volume of all sound on the computer, and also does win_mixer.

Now win_mixer seems to be able to change just the output of a single application (I have to check this, could be I see it wrong).

I just had hopes that this could be done directly via uos, instead of having to use yet another 'component'.




Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
Hello.

> What I would like to know is whether there is a simple way to adjust the volume of ALL/ANY output produced by my program.

If you take a look at StrumPract, on the left side of commander-form there are 3 sliders.



The first is for general volume of sound-card and uses "win_mixer" and the 2 others the general volume (left-right) of the application, like you asked.

> Now win_mixer seems to be able to change just the output of a single application (I have to check this, could be I see it wrong).

No, win_mixer can change only the volume of the sound-card and this will change the volume of all applications.

> I just had hopes that this could be done directly via uos, instead of having to use yet another 'component'.

Yes it can be done by uos see my first post ( or check the code of Strumpract ).

Fre;D


Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
In reply to this post by Weps
Re-hello.

> However, I have got something like 60 players. It seemd a bit strange I'ld have to change the volume of all players instead of just the one 'output-channel' that those 60 players go through.

If you have created 60 players with 1 input / 1 output  for each one, indeed you have to change the volume of  'output-channel' of each player.

I dont know your project but you may also create only one player with 60 inputs / 1 output and then only change  the volume of  'output-channel' used by each input.

For demo of multi-input player, please take a look at demo /uos/examples/multiinput.lpi.

Fre;D
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
Re-re hello.

>  in_index := uos_AddFromMemoryStream( aPlayer, ms, 1, 0, -1, -1);

Ha, your input is from memorystream.
I never try it with multi-input demo but it should work too.

Fred
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

Weps
I can't keep up with your replies, so forgive me if don't address everything :-)

So, I basically have 60 mp3's / waves that I load from memory, these are for sound effects, I'm not playing a list of songs!.

For each I do this:

      uos_CreatePlayer( aPlayer);
      in_index := uos_AddFromMemoryStream( aPlayer, ms, 1, 0, -1, -1);
      output_index := uos_AddIntoDevOut( aPlayer, -1, ....

so now I can
 uos_PlayNoFree (with or without repeat) each of them quickly.

Enfin, output_index seems to be 0 for each call. So, I assume that they all go to the same output.

How do I then change the volume of that output? All method calls that I found seem to require a player-index.

If I try these

uos_OutputAddDSPVolume( MyPlayer1, output_index, left, right);
uos_OutputSetDSPVolume( MyPlayer1, output_index, left, right, true);

then something definitly changes ( the 'sound' attached to MyPlayer1 changes, it goes from left to right and soft to load randomly).

But all others stay the same.

I'm still looking in your code, but I cannot find the one line that changes the volume of the output.


(Also, Lazarus + Windows environment).
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
This post was updated on .
> Enfin, output_index seems to be 0 for each call. So, I assume that they all go to the same output.

Yes, it is the index of the input or output
If you have only one input and one output, it will be = 0

Something like this (ms should be in a array):

var
i : integer;

   for i := 0 to 59 do // creation of players and assign input-output + DSP volume
    begin
      // create the player
      uos_CreatePlayer(i);

      // the result is the index of input, so = 0
      uos_AddFromMemoryStream( i, ms[i], 1, 0, -1, -1);

      // the result is the index of output, so = 0
      uos_AddIntoDevOut( i, -1, ....

     // assign volume ( you may also use uos_InputAddDSPVolume )
      uos_OutputAddDSPVolume( i, 0, left, right);
    end;

    // play it
     uos_PlayNoFree ( someone );


    // When you want to change the volume of all:
      for i := 0 to 59 do
        uos_OutputSetDSPVolume( i, 0, left, right, true);  

////////

PS: You will maybe have better result using uos_InputSetDSPVolume() because it will not affect the output-card and you will have the same result.

Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

Weps
In reply to this post by Weps

Alright, so if I load from file directly, then I can change the volume of that player with os_OutputAddDSPVolume( MyPlayer1, output_index, left, right);

If from memory, it fails, it doesn't work correctly.

Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
> Alright, so if I load from file directly, then I can change the volume of that player with os_OutputAddDSPVolume( MyPlayer1, output_index, left, right);

No, OutputAddDSPVolume( ) is only at creation of the player, do it only once.

When the player is playing, use OutputSetDSPVolume() to adjust the volume and this how many time you want.



Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
In reply to this post by Weps
> If from memory, it fails, it doesn't work correctly.

Here it works perfectly ( Windows / Linux ).
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

Weps
This post was updated on .
uos_distor_src.zip

I made a small sample project.
choose to init from file/mem/resource, then click play.

When picking 'file', eveyrthing is fine. Volume goes up and down nice.

When picking 'mem' or 'resource', you should hear, at least I do, that when reading from mem, the sound is distorted. The volume is not adjusted.


I narrowed it a bit down, for WAV files everything seems ok. The distortion only happens with mp3 files.
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
Hello.

Yes, it is normal, you did not assign the same SampleFormat for input and output for the 2 memory buttons.

Just use those parameter (look at 3 th parameter before end):

 output_index := uos_AddIntoDevOut( aPlayer, -1, 0.03, uos_InputGetSampleRate( aPlayer, in_index), -1, -1, -1, -1);
 
Do this for LoadFromMemory() and LoadFromResource().

Here it works ok.

Fred
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
Re-hello.

In my previous post, the SampleFormat is 16 bit integer for the memory cases.

If you want SampleFormat 32 bit float, just use those parameter:

.      in_index := uos_AddFromMemoryStream( aPlayer, ms, 1, 0, 0, -1);
      output_index := uos_AddIntoDevOut( aPlayer, -1, 0.03, uos_InputGetSampleRate( aPlayer, in_index), -1, 0, -1, -1);

Now up to you to choose the SampleFormat, personally I dont feel difference 16 bit int vs 32 bit float, it needs very good headphones that I dont have ( good speakers dont show difference, imho ).

Fre;D
 
Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

Weps
In reply to this post by fredvs
Ah great, yes, that solves that.

So, to sum up, there is no way to have one call to set the volume on the output / channel / whatever.

Instead, as you wrote above, i'ld have to call setdspvolume on each 'player'.

Ok, got that, made it too. And it works. Thanks for the quick assistance!

Reply | Threaded
Open this post in threaded view
|

Re: Change/Control volume of current application.

fredvs
Administrator
> So, to sum up, there is no way to have one call to set the volume on the output / channel / whatever.

Each player is a independent thread, each has his own input and output.
Even if each player share the same output ( the one from the sound-card ) it has no contact with the output of other threads.

Then you have to deal with the output of each thread ( player ) .

Like explained before, you may create only one player with one output and several inputs.
In this case you will have only one call.

This is good for multi-recording/editing ( each input is a track )  but for what you want ( jingles to play ) it will be much more tricky to do the synchro of the inputs ( tracks ) to play.
 
Fred