mirror of https://gitee.com/openkylin/qemu.git
audio: support more than two channels in volume setting
Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com> Message-id: 5d3dd2ee3baaa62805e79c3901abb7415ae32461.1570996490.git.DirtY.iCE.hu@gmail.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
337e8de6fb
commit
cecc1e79bf
|
@ -1891,31 +1891,45 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
|
|||
}
|
||||
|
||||
void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
|
||||
{
|
||||
Volume vol = { .mute = mute, .channels = 2, .vol = { lvol, rvol } };
|
||||
audio_set_volume_out(sw, &vol);
|
||||
}
|
||||
|
||||
void audio_set_volume_out(SWVoiceOut *sw, Volume *vol)
|
||||
{
|
||||
if (sw) {
|
||||
HWVoiceOut *hw = sw->hw;
|
||||
|
||||
sw->vol.mute = mute;
|
||||
sw->vol.l = nominal_volume.l * lvol / 255;
|
||||
sw->vol.r = nominal_volume.r * rvol / 255;
|
||||
sw->vol.mute = vol->mute;
|
||||
sw->vol.l = nominal_volume.l * vol->vol[0] / 255;
|
||||
sw->vol.r = nominal_volume.l * vol->vol[vol->channels > 1 ? 1 : 0] /
|
||||
255;
|
||||
|
||||
if (hw->pcm_ops->volume_out) {
|
||||
hw->pcm_ops->volume_out(hw, &sw->vol);
|
||||
hw->pcm_ops->volume_out(hw, vol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
|
||||
{
|
||||
Volume vol = { .mute = mute, .channels = 2, .vol = { lvol, rvol } };
|
||||
audio_set_volume_in(sw, &vol);
|
||||
}
|
||||
|
||||
void audio_set_volume_in(SWVoiceIn *sw, Volume *vol)
|
||||
{
|
||||
if (sw) {
|
||||
HWVoiceIn *hw = sw->hw;
|
||||
|
||||
sw->vol.mute = mute;
|
||||
sw->vol.l = nominal_volume.l * lvol / 255;
|
||||
sw->vol.r = nominal_volume.r * rvol / 255;
|
||||
sw->vol.mute = vol->mute;
|
||||
sw->vol.l = nominal_volume.l * vol->vol[0] / 255;
|
||||
sw->vol.r = nominal_volume.r * vol->vol[vol->channels > 1 ? 1 : 0] /
|
||||
255;
|
||||
|
||||
if (hw->pcm_ops->volume_in) {
|
||||
hw->pcm_ops->volume_in(hw, &sw->vol);
|
||||
hw->pcm_ops->volume_in(hw, vol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,16 @@ uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
|
|||
void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol);
|
||||
void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol);
|
||||
|
||||
#define AUDIO_MAX_CHANNELS 16
|
||||
typedef struct Volume {
|
||||
bool mute;
|
||||
int channels;
|
||||
uint8_t vol[AUDIO_MAX_CHANNELS];
|
||||
} Volume;
|
||||
|
||||
void audio_set_volume_out(SWVoiceOut *sw, Volume *vol);
|
||||
void audio_set_volume_in(SWVoiceIn *sw, Volume *vol);
|
||||
|
||||
SWVoiceIn *AUD_open_in (
|
||||
QEMUSoundCard *card,
|
||||
SWVoiceIn *sw,
|
||||
|
|
|
@ -166,7 +166,7 @@ struct audio_pcm_ops {
|
|||
*/
|
||||
size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size);
|
||||
void (*enable_out)(HWVoiceOut *hw, bool enable);
|
||||
void (*volume_out)(HWVoiceOut *hw, struct mixeng_volume *vol);
|
||||
void (*volume_out)(HWVoiceOut *hw, Volume *vol);
|
||||
|
||||
int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque);
|
||||
void (*fini_in) (HWVoiceIn *hw);
|
||||
|
@ -174,7 +174,7 @@ struct audio_pcm_ops {
|
|||
void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size);
|
||||
void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size);
|
||||
void (*enable_in)(HWVoiceIn *hw, bool enable);
|
||||
void (*volume_in)(HWVoiceIn *hw, struct mixeng_volume *vol);
|
||||
void (*volume_in)(HWVoiceIn *hw, Volume *vol);
|
||||
};
|
||||
|
||||
void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
|
||||
|
|
|
@ -532,20 +532,22 @@ static void qpa_fini_in (HWVoiceIn *hw)
|
|||
}
|
||||
}
|
||||
|
||||
static void qpa_volume_out(HWVoiceOut *hw, struct mixeng_volume *vol)
|
||||
static void qpa_volume_out(HWVoiceOut *hw, Volume *vol)
|
||||
{
|
||||
PAVoiceOut *pa = (PAVoiceOut *) hw;
|
||||
pa_operation *op;
|
||||
pa_cvolume v;
|
||||
PAConnection *c = pa->g->conn;
|
||||
int i;
|
||||
|
||||
#ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */
|
||||
pa_cvolume_init (&v); /* function is present in 0.9.13+ */
|
||||
#endif
|
||||
|
||||
v.channels = 2;
|
||||
v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32_MAX;
|
||||
v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32_MAX;
|
||||
v.channels = vol->channels;
|
||||
for (i = 0; i < vol->channels; ++i) {
|
||||
v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255;
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_lock(c->mainloop);
|
||||
|
||||
|
@ -572,20 +574,22 @@ static void qpa_volume_out(HWVoiceOut *hw, struct mixeng_volume *vol)
|
|||
pa_threaded_mainloop_unlock(c->mainloop);
|
||||
}
|
||||
|
||||
static void qpa_volume_in(HWVoiceIn *hw, struct mixeng_volume *vol)
|
||||
static void qpa_volume_in(HWVoiceIn *hw, Volume *vol)
|
||||
{
|
||||
PAVoiceIn *pa = (PAVoiceIn *) hw;
|
||||
pa_operation *op;
|
||||
pa_cvolume v;
|
||||
PAConnection *c = pa->g->conn;
|
||||
int i;
|
||||
|
||||
#ifdef PA_CHECK_VERSION
|
||||
pa_cvolume_init (&v);
|
||||
#endif
|
||||
|
||||
v.channels = 2;
|
||||
v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32_MAX;
|
||||
v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32_MAX;
|
||||
v.channels = vol->channels;
|
||||
for (i = 0; i < vol->channels; ++i) {
|
||||
v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255;
|
||||
}
|
||||
|
||||
pa_threaded_mainloop_lock(c->mainloop);
|
||||
|
||||
|
|
|
@ -179,13 +179,14 @@ static void line_out_enable(HWVoiceOut *hw, bool enable)
|
|||
}
|
||||
|
||||
#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
|
||||
static void line_out_volume(HWVoiceOut *hw, struct mixeng_volume *vol)
|
||||
static void line_out_volume(HWVoiceOut *hw, Volume *vol)
|
||||
{
|
||||
SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
|
||||
uint16_t svol[2];
|
||||
|
||||
svol[0] = vol->l / ((1ULL << 16) + 1);
|
||||
svol[1] = vol->r / ((1ULL << 16) + 1);
|
||||
assert(vol->channels == 2);
|
||||
svol[0] = vol->vol[0] * 257;
|
||||
svol[1] = vol->vol[1] * 257;
|
||||
spice_server_playback_set_volume(&out->sin, 2, svol);
|
||||
spice_server_playback_set_mute(&out->sin, vol->mute);
|
||||
}
|
||||
|
@ -262,13 +263,14 @@ static void line_in_enable(HWVoiceIn *hw, bool enable)
|
|||
}
|
||||
|
||||
#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2))
|
||||
static void line_in_volume(HWVoiceIn *hw, struct mixeng_volume *vol)
|
||||
static void line_in_volume(HWVoiceIn *hw, Volume *vol)
|
||||
{
|
||||
SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
|
||||
uint16_t svol[2];
|
||||
|
||||
svol[0] = vol->l / ((1ULL << 16) + 1);
|
||||
svol[1] = vol->r / ((1ULL << 16) + 1);
|
||||
assert(vol->channels == 2);
|
||||
svol[0] = vol->vol[0] * 257;
|
||||
svol[1] = vol->vol[1] * 257;
|
||||
spice_server_record_set_volume(&in->sin, 2, svol);
|
||||
spice_server_record_set_mute(&in->sin, vol->mute);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue