Здравствуйте, работаю на Linux в 1 раз, поэтому наверно вопрос будет немного простой, но для меня пока что, сложный. Занят проектом под Linux, вкратце если то нужна говорилка между компами. Написать желательно под alsa. Вроде как то разобрался в чем то. Примеры различные, запустил. На данный момент добился того что бы 1 программа записывала в файл фрагмент звука. А 2ой программой можно было этот фрагмент прочитать. Проблема в том что я собираю файл, а потом через консоль находясь в директории с программой набирай ./programmRecord > NameFile.mp3 ( на запись ) и ./ProgrammPlay < NameFile.mp3 ( на чтение ).
Собственно вопрос:
1. Как можно сделать ввод файла в самой программе? Чтобы убрать участие консоли.
2. Не совсем понятно где именно идет передача в сам файл.( Пример брал из книжки, но так корректно и не понял можно ли обойтись без файла. Что бы сохранял значение в промежуточной переменной.
Проблема только в работе со звуком. По факту не понятно как в буффер передать данные с микрофона и как их подать на наушники(колонки). Остальное все я представляю как делать.
Вот код примера с которым работаю.
/*
This example reads standard from input and writes
to the default PCM device for 5 seconds of data.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
int main() {
long loops;
int rc;
int size;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "hw:0,0",
SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
fprintf(stderr,
"unable to open pcm device: %s\n",
snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params,
&val, &dir);
/* Set period size to 32 frames. */
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle,
params, &frames, &dir);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr,
"unable to set hw parameters: %s\n",
snd_strerror(rc));
exit(1);
}
/* Use a buffer large enough to hold one period */
snd_pcm_hw_params_get_period_size(params, &frames,
&dir);
size = frames * 4; /* 2 bytes/sample, 2 channels */
buffer = (char *) malloc(size);
/* We want to loop for 5 seconds */
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
/* 5 seconds in microseconds divided by
* period time */
loops = 5000000 / val;
while (loops > 0) {
loops--;
rc = read(0, buffer, size);
if (rc == 0) {
fprintf(stderr, "end of file on input\n");
break;
} else if (rc != size) {
fprintf(stderr,
"short read: read %d bytes\n", rc);
}
rc = snd_pcm_writei(handle, buffer, frames);
if (rc == -EPIPE) {
/* EPIPE means underrun */
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
} else if (rc < 0) {
fprintf(stderr,
"error from writei: %s\n",
snd_strerror(rc));
} else if (rc != (int)frames) {
fprintf(stderr,
"short write, write %d frames\n", rc);
}
}
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buffer);
return 0;
}
Дополнение 1 :
Как всегда после написания, голова начала работать и вроде понял что должно быть что то вроде
fd = open("file_rec", O_RDWR);
if(!fd)
printf("file didn't open\n");
while (loops > 0) {
loops--;
b = snd_pcm_readi(fd, buffer, frames);
write(fd, buffer, size);
}
Но выдается при запуски ошибка сегментации. Пока что не понял из за чего.