Volume control for OSS & SUN

Ignore first 4 bytes of audio-packet (clicking noise)


git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@490 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Michael Gernoth 2003-10-13 16:09:45 +00:00
parent 6c74a483f4
commit 5d67a3e036
5 changed files with 76 additions and 9 deletions

View File

@ -293,7 +293,10 @@ enum RDP_INPUT_DEVICE
#define CF_GDIOBJLAST 1023
/* Sound format constants */
#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_ADPCM 2
#define WAVE_FORMAT_ALAW 6
#define WAVE_FORMAT_MULAW 7
/* Virtual channel options */
#define CHANNEL_OPTION_INITIALIZED 0x80000000

View File

@ -89,6 +89,7 @@ BOOL wave_out_format_supported(WAVEFORMATEX *pwfx);
BOOL wave_out_set_format(WAVEFORMATEX *pwfx);
void wave_out_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void);
void wave_out_volume(uint16 left, uint16 right);
/* secure.c */
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt);
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2);

View File

@ -78,11 +78,18 @@ rdpsnd_process_negotiate(STREAM in)
unsigned int in_format_count, i;
WAVEFORMATEX *format;
STREAM out;
BOOL device_available = False;
in_uint8s(in, 14); /* flags, volume, pitch, UDP port */
in_uint16_le(in, in_format_count);
in_uint8s(in, 4); /* pad, status, pad */
if (wave_out_open())
{
wave_out_close();
device_available = True;
}
format_count = 0;
if (s_check_rem(in, 18*in_format_count))
{
@ -97,7 +104,7 @@ rdpsnd_process_negotiate(STREAM in)
in_uint16_le(in, format->wBitsPerSample);
in_uint16_le(in, format->cbSize);
if (wave_out_format_supported(format))
if (device_available && wave_out_format_supported(format))
{
format_count++;
if (format_count == MAX_FORMATS)
@ -155,6 +162,7 @@ rdpsnd_process(STREAM s)
{
uint8 type;
uint16 datalen;
uint32 volume;
static uint16 tick, format;
static uint8 packet_index;
static BOOL awaiting_data_packet;
@ -218,7 +226,11 @@ rdpsnd_process(STREAM s)
rdpsnd_process_unknown6(s);
break;
case RDPSND_SET_VOLUME:
/* uint32 volume */
in_uint32(s, volume);
if ( device_open )
{
wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);
}
break;
default:
unimpl("RDPSND packet type %d\n", type);

View File

@ -43,7 +43,7 @@ wave_out_open(void)
{
char *dsp_dev = "/dev/dsp";
if ((g_dsp_fd = open(dsp_dev, O_WRONLY)) == -1)
if ((g_dsp_fd = open(dsp_dev, O_WRONLY|O_NONBLOCK)) == -1)
{
perror(dsp_dev);
return False;
@ -112,6 +112,20 @@ wave_out_set_format(WAVEFORMATEX *pwfx)
return True;
}
void
wave_out_volume(uint16 left, uint16 right)
{
uint32 volume;
volume = left/(65536/100);
volume |= right/(65536/100) << 8;
if (ioctl(g_dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
{
perror("MIXER_WRITE(SOUND_MIXER_PCM)");
return;
}
}
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
@ -129,6 +143,7 @@ wave_out_write(STREAM s, uint16 tick, uint8 index)
packet->s = *s;
packet->tick = tick;
packet->index = index;
packet->s.p += 4;
/* we steal the data buffer from s, give it a new one */
s->data = malloc(s->size);

View File

@ -111,16 +111,16 @@ wave_out_set_format(WAVEFORMATEX *pwfx)
if (pwfx->wBitsPerSample == 8)
{
info.play.encoding = AUDIO_ENCODING_LINEAR8;
samplewidth = 1;
}
else if (pwfx->wBitsPerSample == 16)
{
info.play.encoding = AUDIO_ENCODING_LINEAR;
samplewidth = 2;
/* Do we need to swap the 16bit values? (Are we BigEndian) */
swapaudio = !(*(uint8 *) (&test));
}
samplewidth = pwfx->wBitsPerSample/8;
if (pwfx->nChannels == 1 )
{
info.play.channels = AUDIO_CHANNELS_MONO;
@ -136,6 +136,7 @@ wave_out_set_format(WAVEFORMATEX *pwfx)
info.play.samples = 0;
info.play.eof = 0;
info.play.error = 0;
reopened = True;
if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
{
@ -147,6 +148,40 @@ wave_out_set_format(WAVEFORMATEX *pwfx)
return True;
}
void
wave_out_volume(uint16 left, uint16 right)
{
audio_info_t info;
uint balance;
uint volume;
if (ioctl(g_dsp_fd, AUDIO_GETINFO, &info) == -1)
{
perror("AUDIO_GETINFO");
return;
}
volume = (left > right) ? left : right;
if ( volume/AUDIO_MID_BALANCE != 0 )
{
balance = AUDIO_MID_BALANCE - (left/(volume/AUDIO_MID_BALANCE)) + (right/(volume/AUDIO_MID_BALANCE));
}
else
{
balance = AUDIO_MID_BALANCE;
}
info.play.gain = volume/(65536/AUDIO_MAX_GAIN);
info.play.balance = balance;
if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
{
perror("AUDIO_SETINFO");
return;
}
}
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
@ -164,6 +199,7 @@ wave_out_write(STREAM s, uint16 tick, uint8 index)
packet->s = *s;
packet->tick = tick;
packet->index = index;
packet->s.p += 4;
/* we steal the data buffer from s, give it a new one */
s->data = malloc(s->size);
@ -209,13 +245,13 @@ wave_out_play(void)
/* Swap the current packet, but only once */
if ( swapaudio && ! swapped )
{
for ( i = 0; i < out->end - out->p; i+=2 )
for ( i = 0; i < out->end - out->p; i += 2 )
{
swap = *(out->p + i);
*(out->p + i ) = *(out->p + i + 1);
*(out->p + i) = *(out->p + i + 1);
*(out->p + i + 1) = swap;
swapped = True;
}
swapped = True;
}
if ( sentcompletion )