[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Openvortex-dev] Re: [Alsa-devel] au8830+via & alsa 0.9.7c
From: |
Wilfried Weissmann |
Subject: |
[Openvortex-dev] Re: [Alsa-devel] au8830+via & alsa 0.9.7c |
Date: |
Sun, 23 Nov 2003 22:28:24 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020623 Debian/1.0.0-0.woody.1 |
Manuel Jander wrote:
This could be a period size bug. I didn't test the Alaw support myself,
but know i see that it could be useful for VoIP.
i just did some more testing after upgrading the libraries and utils to
version 0.9.7 to get you some details. i recorded samples with arecord
in mu-law mono with a sampling rate from 8khz to 48khz in 2khz steps.
8khz is fine. but the samples from 10khz to 32khz are getting worse with
increased sampling rate (contrary to what i said before). 34khz to 48khz
have perfect sound again.
another funny thing is that at first i recorded a sample with 44100hz
and then with 28000hz. and at the beginning of the 28000hz sample i
found a low pitched snippet (due to the change is sampling rate) of the
previous sample.
Sounds like a buffer problem. Some sizes miscalculated or some sort of
that. Maybe we are hitting an unknown design limitation ? Wouldn't be
the first time, since there is no "datasheet", only guesses and
"abtasten in der Dunkelheit" (don't know how to translate this, sorry).
i have written a small program that is cloned from the speakfreely
sources to demonstrate the problem. now i think that the bug is not
alaw/mulaw specific because of i can reproduce similar effects the with
linear samples (with this program). the program tries to simulate voip
traffic by sleeping between the playback of two samples. it should play
a low pitched beep (called "silence"). then wait for a second before a
long (5x) high pitched beep (called "beep") is played followed by a one
second sleep. this is repeated 3 times.
for(i=0; i<3; i++) {
printf("start loop %d\n", i);
soundplay(BUFFERSIZE(silence), silence);
printf("pause loop %d\n", i);
sleep(1);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
printf("end loop %d\n", i);
sleep(1);
}
but what i hear is quite different. the first time is OK:
a low beep, then a high beeeeeeeeeeeeeeep
afterwards i cannot hear a low beep. no sound for 2 seconds (1 second at
the end of the loop + one after playing a low beep). then i hear two
short high beeps (?!?).
adding or deleting some "soundplay(BUFFERSIZE(beep), beep);" produces
different odd effects (total silence after the first loop, ...).
to run the program start it with:
$ ./soundbyte /dev/dsp /dev/mixer
this is quite similar to what i hear when i use speakfreely with silence
suppression and/or experiencing network congestion. speakfreely is
compiled with the "-DLINEAR" option to prevent it from using MULAW.
Best Regards
Manuel Jander
Greetings,
Wilfried
/*
Sound interface for Speak Freely for Unix
Designed and implemented in July of 1990 by John Walker
*/
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#define MAX_GAIN 100
#define SAMPLE_RATE 16000
static int audiof = -1; /* Audio device file descriptor */
static int stereo=0; /* 0=mono, 1=stereo */
static int Audio_fd; /* Audio control port */
static int aubufsize = 2048; /* Default */
/* SOUNDINIT -- Open the sound peripheral and initialise for
access. Return TRUE if successful, FALSE
otherwise. */
int soundinit(int iomode, char *devAudioOutput, char *devAudioControl)
{
int attempts = 3;
int format = AFMT_S16_LE;
int speed = SAMPLE_RATE;
int channels;
int arg = 0x7FFF000B, frag_size;
/* When opening the audio device file and control file, we
check for a specification which begins with a sharp sign
and, if present, use the integer which follows as the number
of an already-open file descriptor. This allows a launcher
program to open the audio device and then fork two processes
which invoke sfmike and sfspeaker. Why go to all this
trouble? Because some audio drivers, particularly on
Linux, don't permit two separate programs to open /dev/audio
simultaneously, even though function just fine in full
duplex. This kludge allows getting aroung around that
restriction. */
audiof = open(devAudioOutput, iomode);
if (audiof >= 0) {
Audio_fd = open(devAudioControl, O_RDWR);
if (Audio_fd < 0) {
perror(devAudioControl);
close(audiof);
audiof = -1;
return 0;
}
/*fcntl(audiof, F_SETFL, O_NDELAY);*/
channels = 1;
if (ioctl(audiof, SNDCTL_DSP_CHANNELS, &channels) == -1) {
perror("SNDCTL_DSP_CHANNELS");
exit(-1);
}
stereo = (channels==1)?0:1;
{
int linearSet = 0;
if (ioctl(audiof, SNDCTL_DSP_SETFMT, &format) == -1) {
perror("SNDCTL_DSP_SETFMT");
} else if (ioctl(audiof, SNDCTL_DSP_STEREO, &stereo) == -1) {
perror("SNDCTL_DSP_STEREO");
} else if (ioctl(audiof, SNDCTL_DSP_SPEED, &speed) == -1) {
perror("SNDCTL_DSP_SPEED");
} else {
linearSet = 1;
}
if (!linearSet) {
soundterm();
return 0;
}
}
if (ioctl(audiof, SNDCTL_DSP_NONBLOCK, NULL) < 0) {
perror("SNDCTL_DSP_NONBLOCK");
soundterm();
return 0;
}
if (ioctl(audiof, SNDCTL_DSP_SETFRAGMENT, &arg) == -1) {
/* Ignore EINVAL if we were handed an open file descriptor
because that just means that sound is already being
transferred, which, in turn, means that another process
has already configured the device.
*/
if ((errno != EINVAL)) {
perror("SNDCTL_DSP_SETFRAGMENT (LINUX_DSP_SMALL_BUFFER defined)");
}
/* This isn't fatal, so keep on going. */
}
if (ioctl(audiof, SNDCTL_DSP_GETBLKSIZE, &frag_size) == -1) {
perror("SNDCTL_DSP_GETBLKSIZE (LINUX_DSP_SMALL_BUFFER defined)");
soundterm();
return 0;
}
}
return 0;
}
/* SOUNDTERM -- Close the sound device. */
void soundterm(void)
{
if (close(audiof) < 0) {
perror("closing audio device");
}
if (close(Audio_fd) < 0) {
perror("closing audio control device");
}
audiof = -1;
}
/* SOUNDPLAY -- Begin playing a sound. */
void soundplay(int len, short int *buf)
{
int ios;
//fprintf(stderr, "sound: writing %d bytes\n", len);
while (1) {
ios = write(audiof, buf, len);
//fprintf(stderr, "sound: wrote %d of %d bytes\n", ios, len);
if (ios == -1) {
} else {
if (ios < len) {
buf += ios;
len -= ios;
} else {
break;
}
}
}
//fprintf(stderr, "sound: done\n");
}
short int beep[2048];
short int silence[2048];
#define BUFFERSIZE(what) (sizeof(what)/sizeof(short int))
//#define sleep(x)
int main(int argc, char ** argv) {
int i;
for(i=0; i<BUFFERSIZE(beep); i++) {
beep[i]=sin(( i*2160/BUFFERSIZE(beep) )/4)*16000;
}
for(i=0; i<BUFFERSIZE(silence); i++) {
silence[i]=sin(( i*2160/BUFFERSIZE(beep) )/8)*16000;
}
soundinit(O_RDWR, argv[1], argv[2]);
//soundplay(BUFFERSIZE(beep), beep);
for(i=0; i<3; i++) {
printf("start loop %d\n", i);
soundplay(BUFFERSIZE(silence), silence);
printf("pause loop %d\n", i);
sleep(1);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
soundplay(BUFFERSIZE(beep), beep);
printf("end loop %d\n", i);
sleep(1);
}
}
all:
gcc -lm soundbyte.c -o soundbyte
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Openvortex-dev] Re: [Alsa-devel] au8830+via & alsa 0.9.7c,
Wilfried Weissmann <=