Name: pulseaudio-modules-tizen
Summary: Pulseaudio modules for Tizen
-Version: 15.0.20
+Version: 15.0.21
Release: 0
Group: Multimedia/Audio
License: LGPL-2.1+
pa_assert(map);
channels = rc->ss.channels - source_ss->channels;
- if (channels <= 0)
+ if (channels <= 0) {
+ pa_log_error("No empty channels. reference copy will be disabled");
return -1;
+ }
+
+ /* TODO: temporary code for supporting mchstreamer. reference copy uses the last 2ch of its channels */
+ if (rc->ss.channels == 16)
+ channels = 2;
*sample_spec = rc->ss;
sample_spec->channels = rc->reference_channels = channels;
pa_channel_map_init_auto(map, channels, PA_CHANNEL_MAP_AIFF);
+ pa_log_info("reference will be copied to empty channels(%d). source-output ch(%d), source ch(%d)",
+ channels, rc->ss.channels, source_ss->channels);
+
return 0;
}
/* trigger resolves a race condition related to post_process between source and render thread */
if (u->triggered) {
- if (code == PA_ECHO_CANCEL_MESSAGE_PUSH_DATA || code == PA_ECHO_CANCEL_MESSAGE_PUSH_ECHO) {
+ if (code == PA_ECHO_CANCEL_MESSAGE_PUSH_ECHO) {
pa_source_output *o = NULL;
pa_usec_t latency;
#endif
#define MEMBLOCKQ_MAXLENGTH (16 * 1024 * 1024)
+#define MEMBLOCKQ_PUSH_REFERENCE_BLOCK_ALIGN
typedef struct pa_processor_method_interface pa_processor_method_interface;
struct pa_processor {
pa_assert(processor);
bytes = pa_usec_to_bytes(latency, &processor->reference_memblockq_ss);
- n = (bytes + (processor->reference_process_bytes - 1)) / processor->reference_process_bytes;
+#ifdef MEMBLOCKQ_PUSH_REFERENCE_BLOCK_ALIGN
+ n = (bytes + (processor->reference_process_bytes - 1)) / processor->reference_process_bytes;
pa_silence_memchunk_get(
&processor->core->silence_cache,
processor->core->mempool,
&silence,
&processor->reference_memblockq_ss,
processor->reference_process_bytes);
+#else
+ n = 1;
+ pa_silence_memchunk_get(
+ &processor->core->silence_cache,
+ processor->core->mempool,
+ &silence,
+ &processor->reference_memblockq_ss,
+ bytes);
+#endif
write_index = pa_memblockq_get_write_index(processor->reference_memblockq);
read_index = pa_memblockq_get_read_index(processor->reference_memblockq);
pa_memblock_unref(silence.memblock);
- pa_log_info("push n(%u) silence blocks. ref_process_bytes(%zu) "
+ pa_log_info("push n(%u) silence blocks. latency(%" PRId64 "), ref_process_bytes(%zu) "
"write_index(%" PRId64 "->%" PRId64 "), read_index(%" PRId64 "->%" PRId64 ")",
pa_memblockq_get_nblocks(processor->reference_memblockq),
+ latency,
processor->reference_process_bytes,
write_index, pa_memblockq_get_write_index(processor->reference_memblockq),
read_index, pa_memblockq_get_read_index(processor->reference_memblockq));
u->write_count = 0;
u->first = true;
- u->timestamp = pa_rtclock_now();
pa_log_info("Resumed successfully...");
case PA_SINK_MESSAGE_GET_LATENCY: {
int64_t r = 0;
- if (u->pcm_handle)
- r = u->timestamp + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec) - pa_rtclock_now();
+ if (u->pcm_handle) {
+ pa_usec_t now = pa_rtclock_now();
+ pa_usec_t write_latency = u->timestamp + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec);
+
+ if (now < write_latency)
+ r = write_latency - now;
+ }
*((int64_t *) data) = r;
pa_sink_render_full(u->sink, u->frag_size, &chunk);
p = pa_memblock_acquire(chunk.memblock);
+ if (u->first)
+ u->timestamp = pa_rtclock_now();
+
if (pa_hal_interface_pcm_write(u->hal_interface, u->pcm_handle, (const char*)p + chunk.index, (uint32_t)frames_to_write)) {
pa_log_error("failed to write pcm. p(%p), size(%zu)", p, frames_to_write);
return -1;
case PA_SOURCE_MESSAGE_GET_LATENCY: {
uint64_t r = 0;
- if (u->pcm_handle)
- r = pa_rtclock_now() - (u->timestamp + pa_bytes_to_usec(u->read_count, &u->source->sample_spec));
+ if (u->pcm_handle) {
+ pa_usec_t now = pa_rtclock_now();
+ pa_usec_t read_latency = u->timestamp + pa_bytes_to_usec(u->read_count, &u->source->sample_spec);
+
+ if (now > read_latency)
+ r = now - read_latency;
+ }
*((int64_t *) data) = r;