Permalink
Browse files

[pulse] Virtualize volume and limit it to device max

AKA support for pulseaudio flat volumes
  • Loading branch information...
alexp-sssup committed May 27, 2012
1 parent 7731a1c commit 8409aee2f3f60afa7097c66b829d5e5d45bc3ab4
@@ -310,7 +310,8 @@ void PulsePlugin::unmuteAll()
Stream's functions
****************************/
PulseAudioStream::PulseAudioStream ( PulsePlugin* m ) :
AudioStream(NULL), paused(false), stream ( NULL ), manager ( m ), streamStatus ( STREAM_STARTING )
AudioStream(NULL), paused(false), stream ( NULL ), manager ( m ), streamStatus ( STREAM_STARTING ),
streamVolume(0.0)
{

}
@@ -411,20 +412,39 @@ void PulseAudioStream::unmute()
);
}

void PulseAudioStream::setVolume(double vol)
void PulseAudioStream::sinkInfoForSettingVolumeCB(pa_context* context, const pa_sink_info* i, int eol, PulseAudioStream* stream)
{
if(eol)
{
//The callback is called multiple times even if querying a single device
return;
}
struct pa_cvolume volume;
pa_cvolume_set(&volume, pa_stream_get_sample_spec(stream)->channels,
vol*PA_VOLUME_NORM);
pa_sw_cvolume_multiply_scalar(&volume, &i->volume, stream->streamVolume*PA_VOLUME_NORM);

pa_context_set_sink_input_volume(
pa_stream_get_context(stream),
pa_stream_get_index(stream),
context,
pa_stream_get_index(stream->stream),
&volume,
NULL,
NULL
);
}

void PulseAudioStream::setVolume(double vol)
{
if(vol==streamVolume)
return;
streamVolume=vol;
uint32_t deviceIndex = pa_stream_get_device_index(stream);
pa_operation* op=pa_context_get_sink_info_by_index(
pa_stream_get_context(stream),
deviceIndex,
(pa_sink_info_cb_t)sinkInfoForSettingVolumeCB,
this);
pa_operation_unref(op);
}

// Plugin factory function
extern "C" DLL_PUBLIC IPlugin *create()
{
@@ -40,7 +40,6 @@ friend class PulseAudioStream;
void stop();
static void playbackListCB ( pa_context *context, const pa_sink_info *list, int eol, void *th );
static void captureListCB ( pa_context *context, const pa_source_info *list, int eol, void *th );
void addDeviceToList ( std::vector<std::string *> *devicesList, std::string *deviceName );
//To populate the devices lists, devicesType must be playback or capture
void generateDevicesList ( std::vector<std::string *> *devicesList, DEVICE_TYPES desiredType );
static void streamStatusCB ( pa_stream *stream, PulseAudioStream *th );
@@ -78,12 +77,14 @@ friend class PulsePlugin;
bool isValid();
void pause();
void resume();
static void sinkInfoForSettingVolumeCB(pa_context* context, const pa_sink_info* i, int eol, PulseAudioStream* stream);
~PulseAudioStream();
private:
bool paused;
pa_stream *stream;
PulsePlugin *manager;
volatile STREAM_STATUS streamStatus;
double streamVolume;

void mute();
void unmute();

0 comments on commit 8409aee

Please sign in to comment.