mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-11 16:16:42 +02:00
player volume is adjusted in software
This commit is contained in:
parent
11a45d3508
commit
0893f40fd1
3 changed files with 42 additions and 39 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue