alsa: refactoring

master
Chelovechishko 9 years ago
parent bc4e1bf8d4
commit f45f527e05
  1. 181
      input/alsa.c

@ -1,71 +1,106 @@
// input: ALSA // input: ALSA
void* input_alsa(void* data)
{
struct audio_data *audio = (struct audio_data *)data;
signed char *buffer;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
snd_pcm_uframes_t frames;
val = 44100;
int i, n, o, size, dir, err, lo;
int tempr, templ;
int radj, ladj;
// assuming stereo
#define CHANNELS_COUNT 2
#define SAMPLE_RATE 44100
void initialize_audio_parameters(snd_pcm_t** handle, struct audio_data* audio,
snd_pcm_uframes_t* frames) {
// alsa: open device to capture audio // alsa: open device to capture audio
if ((err = snd_pcm_open(&handle, audio-> source, SND_PCM_STREAM_CAPTURE, 0) < 0)) { int err = snd_pcm_open(handle, audio->source, SND_PCM_STREAM_CAPTURE, 0);
fprintf(stderr, if (err < 0) {
"error opening stream: %s\n", fprintf(stderr, "error opening stream: %s\n", snd_strerror(err));
snd_strerror(err));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef DEBUG #ifdef DEBUG
else printf("open stream successful\n"); else printf("open stream successful\n");
#endif #endif
snd_pcm_hw_params_alloca(&params); //assembling params snd_pcm_hw_params_t* params;
snd_pcm_hw_params_any (handle, params); //setting defaults or something snd_pcm_hw_params_alloca(&params); // assembling params
snd_pcm_hw_params_set_access(handle, params, snd_pcm_hw_params_any(*handle, params); // setting defaults or something
SND_PCM_ACCESS_RW_INTERLEAVED); //interleaved mode right left right left // interleaved mode right left right left
snd_pcm_hw_params_set_format(handle, params, snd_pcm_hw_params_set_access(*handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
SND_PCM_FORMAT_S16_LE); //trying to set 16bit // trying to set 16bit
snd_pcm_hw_params_set_channels(handle, params, 2); //assuming stereo snd_pcm_hw_params_set_format(*handle, params, SND_PCM_FORMAT_S16_LE);
val = 44100; snd_pcm_hw_params_set_channels(*handle, params, CHANNELS_COUNT);
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); //trying 44100 rate unsigned int sample_rate = SAMPLE_RATE;
frames = 256; // trying our rate
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, snd_pcm_hw_params_set_rate_near(*handle, params, &sample_rate, NULL);
&dir); //number of frames pr read // number of frames pr read
snd_pcm_hw_params_set_period_size_near(*handle, params, frames, NULL);
err = snd_pcm_hw_params(handle, params); //attempting to set params err = snd_pcm_hw_params(*handle, params); // attempting to set params
if (err < 0) { if (err < 0) {
fprintf(stderr, fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(err));
"unable to set hw parameters: %s\n",
snd_strerror(err));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
snd_pcm_hw_params_get_format(params, // getting actual format
(snd_pcm_format_t * )&val); //getting actual format snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*)&sample_rate);
//converting result to number of bits // converting result to number of bits
if (val < 6)audio->format = 16; if (sample_rate <= 5)
else if (val > 5 && val < 10)audio->format = 24; audio->format = 16;
else if (val > 9)audio->format = 32; else if (sample_rate <= 9 )
audio->format = 24;
else
audio->format = 32;
snd_pcm_hw_params_get_rate(params, &audio->rate, NULL);
snd_pcm_hw_params_get_period_size(params, frames, NULL);
// snd_pcm_hw_params_get_period_time(params, &sample_rate, &dir);
}
snd_pcm_hw_params_get_rate(params, &audio->rate, &dir); //getting rate int get_certain_frame(signed char* buffer, int buffer_index, int adjustment) {
// using the 10 upper bits this would give me a vert res of 1024, enough...
int temp = buffer[buffer_index + adjustment - 1] << 2;
int lo = buffer[buffer_index + adjustment - 2] >> 6;
if (lo < 0)
lo = abs(lo) + 1;
if (temp >= 0)
temp += lo;
else
temp -= lo;
return temp;
}
snd_pcm_hw_params_get_period_size(params, &frames, &dir); void fill_audio_outs(struct audio_data* audio, signed char* buffer,
snd_pcm_hw_params_get_period_time(params, &val, &dir); const int size) {
int radj = audio->format / 4; // adjustments for interleaved
int ladj = audio->format / 8;
static int audio_out_buffer_index = 0;
// sorting out one channel and only biggest octet
for (int buffer_index = 0; buffer_index < size; buffer_index += ladj * 2) {
// first channel
int tempr = get_certain_frame(buffer, buffer_index, radj);
// second channel
int templ = get_certain_frame(buffer, buffer_index, ladj);
// mono: adding channels and storing it in the buffer
if (audio->channels == 1)
audio->audio_out_l[audio_out_buffer_index] = (templ + tempr) / 2;
else { // stereo storing channels in buffer
audio->audio_out_l[audio_out_buffer_index] = templ;
audio->audio_out_r[audio_out_buffer_index] = tempr;
}
size = frames * (audio->format / 8) * 2; // frames * bits/8 * 2 channels if (++audio_out_buffer_index == 2048 - 1)
buffer = malloc(size); audio_out_buffer_index = 0;
radj = audio->format / 4; //adjustments for interleaved }
ladj = audio->format / 8; }
o = 0;
while (1) { #define FRAMES_NUMBER 256
void* input_alsa(void* data) {
struct audio_data* audio = (struct audio_data*)data;
snd_pcm_t* handle;
snd_pcm_uframes_t frames = FRAMES_NUMBER;
initialize_audio_parameters(&handle, audio, &frames);
err = snd_pcm_readi(handle, buffer, frames); // frames * bits/8 * channels
const int size = frames * (audio->format / 8) * CHANNELS_COUNT;
signed char* buffer = malloc(size);
while (1) {
int err = snd_pcm_readi(handle, buffer, frames);
if (err == -EPIPE) { if (err == -EPIPE) {
/* EPIPE means overrun */ /* EPIPE means overrun */
#ifdef DEBUG #ifdef DEBUG
@ -81,53 +116,11 @@ void* input_alsa(void* data)
fprintf(stderr, "short read, read %d %d frames\n", err, (int)frames); fprintf(stderr, "short read, read %d %d frames\n", err, (int)frames);
#endif #endif
} }
fill_audio_outs(audio, buffer, size);
//sorting out one channel and only biggest octet
n = 0; //frame counter
for (i = 0; i < size ; i = i + (ladj) * 2) {
//first channel
tempr = ((buffer[i + (radj) - 1 ] <<
2)); //using the 10 upper bits this would give me a vert res of 1024, enough...
lo = ((buffer[i + (radj) - 2] >> 6));
if (lo < 0)lo = abs(lo) + 1;
if (tempr >= 0)tempr = tempr + lo;
if (tempr < 0)tempr = tempr - lo;
//other channel
templ = (buffer[i + (ladj) - 1] << 2);
lo = (buffer[i + (ladj) - 2] >> 6);
if (lo < 0)lo = abs(lo) + 1;
if (templ >= 0)templ = templ + lo;
else templ = templ - lo;
//mono: adding channels and storing it in the buffer
if (audio->channels == 1) audio->audio_out_l[o] = (tempr + templ) / 2;
//stereo storing channels in buffer
if (audio->channels == 2) {
audio->audio_out_l[o] = templ;
audio->audio_out_r[o] = tempr;
}
o++;
if (o == 2048 - 1)o = 0;
n++;
}
if (audio->terminate == 1) { if (audio->terminate == 1) {
free(buffer); free(buffer);
snd_pcm_close(handle); snd_pcm_close(handle);
break; return NULL;
} }
} }
return 0;
} }

Loading…
Cancel
Save