Здравствуйте, уважаемые форумчане. Пишу маленькую программу для сетевого голосового общения под Linux. Использую библиотеку alsa для звука. Собственно столкнулся с проблемой. Сломал всю голову уже. И так к сути... При передаче по сети через сокеты буффера с «голосом» получаю на выходе кучу помех,шуршаний, писка и так далее через которые слышен голос человека на другом конце. Шум и писк это пол беды. Я получаю на выходе грубо говоря несколько секунд такого безобразия, после чего звук обрывается, отрубаются уши на этот сеанс передачи( переполняется буффер как я думаю).При этом пакеты передаются и дальше и принимаются. Собственно проверял потери пакетов, они отсутствуют. Похожей писк идет когда идет заполнение допустим 0лями буффера. На клиенте ( исходном компьютере ) голос идет без помех, без писков, без потерь( с микрофона выдаю сразу в колонки(уши, гарнитуру) звук). Отсюда вопрос с одной стороны к людям разбирающемся в alsa, из за чего может вырубаться звук. С другой стороны вопрос почему правильные изначально данные при передаче обрастают писками и шумами? Вот функция передачи голоса
void speak()
{
long loops;
int sock;
int rc;
int ch;
int size;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
int fd,b;
char msg;
rc = snd_pcm_open(&handle, "hw:0,2,1",
SND_PCM_STREAM_CAPTURE, 0);
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, 2);
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params,
&val, &dir);
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle,
params, &frames, &dir);
rc = snd_pcm_hw_params(handle, params);
snd_pcm_hw_params_get_period_size(params,
&frames, &dir);
size = frames * 4;
buffer = (char *) malloc(size);
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
changemode(1);
int i;
sock = connectsock("127.0.0.1", "1231", "tcp");
if(sock < 0) //проверяем дескриптор сокета
printf("nety connecta");
else
{printf("connect esti");
while(loops>0)
{
rc = snd_pcm_readi(handle, buffer, frames);
send(sock,buffer, frames, 0);
}
}
changemode(0);
close(fd);
close(sock);
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buffer);
}
А вот кусок кода сервера
void speakOut()
{
int msock, csock;
struct sockaddr_in remaddr;
unsigned int remaddrs = sizeof(remaddr);
char msg[32];
int buff_out;
long loops;
int rc,wc;
int size;
snd_pcm_t *handle,*handle_Out;
snd_pcm_hw_params_t *params,*params_Out;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
char *buffer,*buffer_Out;
int fd,b;
int Mode=0,Menu;
wc = snd_pcm_open(&handle_Out, "hw:0,0",
SND_PCM_STREAM_PLAYBACK, 0);
snd_pcm_hw_params_alloca(¶ms_Out);
snd_pcm_hw_params_any(handle_Out, params_Out);
snd_pcm_hw_params_set_access(handle_Out, params_Out,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle_Out, params_Out,
SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle_Out, params_Out, 2);
val = 44100;
snd_pcm_hw_params_set_rate_near(handle_Out, params_Out,
&val, &dir);
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle_Out,
params_Out, &frames, &dir);
wc = snd_pcm_hw_params(handle_Out, params_Out);
snd_pcm_hw_params_get_period_size(params_Out,
&frames, &dir);
size = frames * 4;
buffer = (char *) malloc(size);
snd_pcm_hw_params_get_period_time(params_Out,
&val, &dir);
msock = sock("1231", "tcp", 5);
if(msock < 0)
return -1;
csock = accept(msock, (struct sockaddr*) &remaddr, &remaddrs);
if(csock < 0)
printf("Ошибка принятия подключения: \n");
else
{
while(1)
{
read(csock, &msg, sizeof(msg));
buffer_Out=msg;
wc= snd_pcm_writei (handle_Out, msg, frames);
memset(&msg, 0, sizeof(msg));
}
}
close(fd);
snd_pcm_drain(handle_Out);
snd_pcm_close(handle_Out);
free(buffer_Out);
close(csock);
close(msock);
}
Наверное многие скажут что надо кодировать данные, а не засылать так напрямую и будут правы, но хотелось бы узнать почему именно в таком варианте происходит подобное.