player volume is adjusted in software

This commit is contained in:
badaix 2015-09-08 21:26:30 +02:00
parent 11a45d3508
commit 0893f40fd1
3 changed files with 42 additions and 39 deletions

View file

@ -27,7 +27,14 @@
using namespace std;
Player::Player(const PcmDevice& pcmDevice, Stream* stream) : handle_(NULL), buff_(NULL), active_(false), stream_(stream), pcmDevice_(pcmDevice)
Player::Player(const PcmDevice& pcmDevice, Stream* stream) :
handle_(NULL),
buff_(NULL),
active_(false),
stream_(stream),
pcmDevice_(pcmDevice),
volume_(1.0),
muted_(false)
{
}
@ -184,9 +191,22 @@ void Player::worker()
snd_pcm_delay(handle_, &framesDelay);
chronos::usec delay((chronos::usec::rep) (1000 * (double) framesDelay / stream_->getFormat().msRate()));
// logO << "delay: " << framesDelay << ", delay[ms]: " << delay.count() / 1000 << "\n";
double volume = volume_;
if (muted_)
volume = 0.;
const msg::SampleFormat& sampleFormat = stream_->getFormat();
if (stream_->getPlayerChunk(buff_, delay, frames_))
{
if (volume < 1.0)
{
if (sampleFormat.bits == 8)
adjustVolume<int8_t>(buff_, frames_*sampleFormat.channels, volume);
else if (sampleFormat.bits == 16)
adjustVolume<int16_t>(buff_, frames_*sampleFormat.channels, volume);
else if (sampleFormat.bits == 32)
adjustVolume<int32_t>(buff_, frames_*sampleFormat.channels, volume);
}
if ((pcm = snd_pcm_writei(handle_, buff_, frames_)) == -EPIPE)
{
logE << "XRUN\n";
@ -211,49 +231,14 @@ void Player::worker()
void Player::setVolume(double volume)
{
long min, max;
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
const char *selem_name = "Master";
snd_mixer_open(&handle, 0);
snd_mixer_attach(handle, pcmDevice_.name.c_str());
snd_mixer_selem_register(handle, NULL, NULL);
snd_mixer_load(handle);
snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, selem_name);
snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
snd_mixer_selem_set_playback_volume_all(elem, volume * max);
snd_mixer_close(handle);
volume_ = volume;
}
void Player::setMute(bool mute)
{
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
const char *selem_name = "Master";
snd_mixer_open(&handle, 0);
snd_mixer_attach(handle, pcmDevice_.name.c_str());
snd_mixer_selem_register(handle, NULL, NULL);
snd_mixer_load(handle);
snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, selem_name);
snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
if (snd_mixer_selem_has_playback_switch(elem))
snd_mixer_selem_set_playback_switch_all(elem, mute?0:1);
snd_mixer_close(handle);
muted_ = mute;
}

View file

@ -28,15 +28,23 @@
#include "pcmDevice.h"
/// Audio Player
/**
* Audio player implementation using Alsa
*/
class Player
{
public:
Player(const PcmDevice& pcmDevice, Stream* stream);
virtual ~Player();
/// Set audio volume in range [0..1]
void setVolume(double volume);
void setMute(bool mute);
void start();
void stop();
/// List the system's audio output devices
static std::vector<PcmDevice> pcm_list(void);
private:
@ -44,6 +52,14 @@ private:
void uninitAlsa();
void worker();
template <typename T>
void adjustVolume(char *buffer, size_t count, double volume)
{
T* bufferT = (T*)buffer;
for (size_t n=0; n<count; ++n)
bufferT[n] *= volume;
}
snd_pcm_t* handle_;
snd_pcm_uframes_t frames_;
@ -52,6 +68,8 @@ private:
Stream* stream_;
std::thread playerThread_;
PcmDevice pcmDevice_;
double volume_;
bool muted_;
};

View file

@ -180,7 +180,7 @@ void Controller::worker()
stream_->setBufferLen(serverSettings->bufferMs - latency_);
player_.reset(new Player(pcmDevice_, stream_));
player_->setVolume(serverSettings->volume);
player_->setVolume(serverSettings->volume / 100.);
player_->start();
msg::Command startStream("startStream");