static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata) { int frames; int cframes; tbool ret; const void* data; const uint8* src; int encoded_size; uint8* encoded_data; AudinPulseDevice* pulse = (AudinPulseDevice*) userdata; pa_stream_peek(stream, &data, &length); frames = length / pulse->bytes_per_frame; DEBUG_DVC("length %d frames %d", (int) length, frames); src = (const uint8*) data; while (frames > 0) { cframes = pulse->frames_per_packet - pulse->buffer_frames; if (cframes > frames) cframes = frames; memcpy(pulse->buffer + pulse->buffer_frames * pulse->bytes_per_frame, src, cframes * pulse->bytes_per_frame); pulse->buffer_frames += cframes; if (pulse->buffer_frames >= pulse->frames_per_packet) { if (pulse->format == 0x11) { encoded_data = dsp_encode_ima_adpcm(&pulse->adpcm, pulse->buffer, pulse->buffer_frames * pulse->bytes_per_frame, pulse->sample_spec.channels, pulse->block_size, &encoded_size); DEBUG_DVC("encoded %d to %d", pulse->buffer_frames * pulse->bytes_per_frame, encoded_size); } else { encoded_data = pulse->buffer; encoded_size = pulse->buffer_frames * pulse->bytes_per_frame; } ret = pulse->receive(encoded_data, encoded_size, pulse->user_data); pulse->buffer_frames = 0; if (encoded_data != pulse->buffer) xfree(encoded_data); if (!ret) break; } src += cframes * pulse->bytes_per_frame; frames -= cframes; } pa_stream_drop(stream); }
static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int size) { int frames; int cframes; int ret = 0; int encoded_size; uint8* encoded_data; int rbytes_per_frame; int tbytes_per_frame; uint8* resampled_data; rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; if ((alsa->target_rate == alsa->actual_rate) && (alsa->target_channels == alsa->actual_channels)) { resampled_data = NULL; frames = size / rbytes_per_frame; } else { resampled_data = dsp_resample(src, alsa->bytes_per_channel, alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame, alsa->target_channels, alsa->target_rate, &frames); DEBUG_DVC("resampled %d frames at %d to %d frames at %d", size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate); size = frames * tbytes_per_frame; src = resampled_data; } while (frames > 0) { cframes = alsa->frames_per_packet - alsa->buffer_frames; if (cframes > frames) cframes = frames; memcpy(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src, cframes * tbytes_per_frame); alsa->buffer_frames += cframes; if (alsa->buffer_frames >= alsa->frames_per_packet) { if (alsa->wformat == 0x11) { encoded_data = dsp_encode_ima_adpcm(&alsa->adpcm, alsa->buffer, alsa->buffer_frames * tbytes_per_frame, alsa->target_channels, alsa->block_size, &encoded_size); DEBUG_DVC("encoded %d to %d", alsa->buffer_frames * tbytes_per_frame, encoded_size); } else { encoded_data = alsa->buffer; encoded_size = alsa->buffer_frames * tbytes_per_frame; } ret = alsa->receive(encoded_data, encoded_size, alsa->user_data); alsa->buffer_frames = 0; if (encoded_data != alsa->buffer) xfree(encoded_data); if (!ret) break; } src += cframes * tbytes_per_frame; frames -= cframes; } if (resampled_data) xfree(resampled_data); return ret; }