📄 audio_alsa_source.cc
字号:
d_worker = &audio_alsa_source::work_s16_2x1; else d_worker = &audio_alsa_source::work_s16; break; case SND_PCM_FORMAT_S32: if (special_case) d_worker = &audio_alsa_source::work_s32_2x1; else d_worker = &audio_alsa_source::work_s32; break; default: assert (0); } return true;}audio_alsa_source::~audio_alsa_source (){ if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING) snd_pcm_drop (d_pcm_handle); snd_pcm_close(d_pcm_handle); delete [] ((char *) d_hw_params); delete [] ((char *) d_sw_params); delete [] d_buffer;}intaudio_alsa_source::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items){ assert ((noutput_items % d_period_size) == 0); assert (noutput_items != 0); // this is a call through a pointer to a method... return (this->*d_worker)(noutput_items, input_items, output_items);}/* * Work function that deals with float to S16 conversion */intaudio_alsa_source::work_s16 (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items){ typedef gr_int16 sample_t; // the type of samples we're creating static const int NBITS = 16; // # of bits in a sample unsigned int nchan = output_items.size (); float **out = (float **) &output_items[0]; sample_t *buf = (sample_t *) d_buffer; int bi; unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t); assert (d_buffer_size_bytes == d_period_size * sizeof_frame); // To minimize latency, return at most a single period's worth of samples. // [We could also read the first one in a blocking mode and subsequent // ones in non-blocking mode, but we'll leave that for later (or never).] if (!read_buffer (buf, d_period_size, sizeof_frame)) return -1; // No fixing this problem. Say we're done. // process one period of data bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ for (unsigned int chan = 0; chan < nchan; chan++){ out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1)); } } return d_period_size;}/* * Work function that deals with float to S16 conversion * and stereo to mono kludge... */intaudio_alsa_source::work_s16_2x1 (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items){ typedef gr_int16 sample_t; // the type of samples we're creating static const int NBITS = 16; // # of bits in a sample unsigned int nchan = output_items.size (); float **out = (float **) &output_items[0]; sample_t *buf = (sample_t *) d_buffer; int bi; assert (nchan == 1); unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t); assert (d_buffer_size_bytes == d_period_size * sizeof_frame); // To minimize latency, return at most a single period's worth of samples. // [We could also read the first one in a blocking mode and subsequent // ones in non-blocking mode, but we'll leave that for later (or never).] if (!read_buffer (buf, d_period_size, sizeof_frame)) return -1; // No fixing this problem. Say we're done. // process one period of data bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ int t = (buf[bi] + buf[bi+1]) / 2; bi += 2; out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1)); } return d_period_size;}/* * Work function that deals with float to S32 conversion */intaudio_alsa_source::work_s32 (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items){ typedef gr_int32 sample_t; // the type of samples we're creating static const int NBITS = 32; // # of bits in a sample unsigned int nchan = output_items.size (); float **out = (float **) &output_items[0]; sample_t *buf = (sample_t *) d_buffer; int bi; unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t); assert (d_buffer_size_bytes == d_period_size * sizeof_frame); // To minimize latency, return at most a single period's worth of samples. // [We could also read the first one in a blocking mode and subsequent // ones in non-blocking mode, but we'll leave that for later (or never).] if (!read_buffer (buf, d_period_size, sizeof_frame)) return -1; // No fixing this problem. Say we're done. // process one period of data bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ for (unsigned int chan = 0; chan < nchan; chan++){ out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1)); } } return d_period_size;}/* * Work function that deals with float to S32 conversion * and stereo to mono kludge... */intaudio_alsa_source::work_s32_2x1 (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items){ typedef gr_int32 sample_t; // the type of samples we're creating static const int NBITS = 32; // # of bits in a sample unsigned int nchan = output_items.size (); float **out = (float **) &output_items[0]; sample_t *buf = (sample_t *) d_buffer; int bi; assert (nchan == 1); unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t); assert (d_buffer_size_bytes == d_period_size * sizeof_frame); // To minimize latency, return at most a single period's worth of samples. // [We could also read the first one in a blocking mode and subsequent // ones in non-blocking mode, but we'll leave that for later (or never).] if (!read_buffer (buf, d_period_size, sizeof_frame)) return -1; // No fixing this problem. Say we're done. // process one period of data bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ int t = (buf[bi] + buf[bi+1]) / 2; bi += 2; out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1)); } return d_period_size;}boolaudio_alsa_source::read_buffer (void *vbuffer, unsigned nframes, unsigned sizeof_frame){ unsigned char *buffer = (unsigned char *) vbuffer; while (nframes > 0){ int r = snd_pcm_readi (d_pcm_handle, buffer, nframes); if (r == -EAGAIN) continue; // try again else if (r == -EPIPE){ // overrun d_noverruns++; fputs ("aO", stderr); if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){ output_error_msg ("snd_pcm_prepare failed. Can't recover from overrun", r); return false; } continue; // try again } else if (r == -ESTRPIPE){ // h/w is suspended (whatever that means) // This is apparently related to power management d_nsuspends++; if ((r = snd_pcm_resume (d_pcm_handle)) < 0){ output_error_msg ("failed to resume from suspend", r); return false; } continue; // try again } else if (r < 0){ output_error_msg ("snd_pcm_readi failed", r); return false; } nframes -= r; buffer += r * sizeof_frame; } return true;}voidaudio_alsa_source::output_error_msg (const char *msg, int err){ fprintf (stderr, "audio_alsa_source[%s]: %s: %s\n", snd_pcm_name (d_pcm_handle), msg, snd_strerror (err));}voidaudio_alsa_source::bail (const char *msg, int err) throw (std::runtime_error){ output_error_msg (msg, err); throw std::runtime_error ("audio_alsa_source");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -