summaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rwxr-xr-x[-rw-r--r--]src/utils/padsp0
-rw-r--r--src/utils/padsp.c77
2 files changed, 72 insertions, 5 deletions
diff --git a/src/utils/padsp b/src/utils/padsp
index bae5a728..bae5a728 100644..100755
--- a/src/utils/padsp
+++ b/src/utils/padsp
diff --git a/src/utils/padsp.c b/src/utils/padsp.c
index dfef3f3a..b20f0d06 100644
--- a/src/utils/padsp.c
+++ b/src/utils/padsp.c
@@ -93,6 +93,8 @@ struct fd_info {
pa_cvolume sink_volume, source_volume;
uint32_t sink_index, source_index;
int volume_modify_count;
+
+ int optr_n_blocks;
PA_LLIST_FIELDS(fd_info);
};
@@ -579,6 +581,7 @@ static fd_info* fd_info_new(fd_info_type_t type, int *_errno) {
i->volume_modify_count = 0;
i->sink_index = (uint32_t) -1;
i->source_index = (uint32_t) -1;
+ i->optr_n_blocks = 0;
PA_LLIST_INIT(fd_info, i);
reset_params(i);
@@ -1952,6 +1955,8 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno)
free_streams(i);
dsp_flush_socket(i);
reset_params(i);
+
+ i->optr_n_blocks = 0;
pa_threaded_mainloop_unlock(i->mainloop);
break;
@@ -2040,14 +2045,76 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno)
break;
}
+ case SOUND_PCM_READ_RATE:
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": SOUND_PCM_READ_RATE\n");
+
+ pa_threaded_mainloop_lock(i->mainloop);
+ *(int*) argp = i->sample_spec.rate;
+ pa_threaded_mainloop_unlock(i->mainloop);
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": SOUND_PCM_READ_CHANNELS\n");
+
+ pa_threaded_mainloop_lock(i->mainloop);
+ *(int*) argp = i->sample_spec.channels;
+ pa_threaded_mainloop_unlock(i->mainloop);
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": SOUND_PCM_READ_BITS\n");
+
+ pa_threaded_mainloop_lock(i->mainloop);
+ *(int*) argp = pa_sample_size(&i->sample_spec)*8;
+ pa_threaded_mainloop_unlock(i->mainloop);
+ break;
+
+ case SNDCTL_DSP_GETOPTR: {
+ count_info *info;
+
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": SNDCTL_DSP_GETODELAY\n");
+
+ info = (count_info*) argp;
+ memset(info, 0, sizeof(*info));
+
+ pa_threaded_mainloop_lock(i->mainloop);
+
+ for (;;) {
+ pa_usec_t usec;
+
+ PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, exit_loop);
+
+ if (pa_stream_get_time(i->play_stream, &usec) >= 0) {
+ size_t k = pa_usec_to_bytes(usec, &i->sample_spec);
+ int m;
+
+ info->bytes = (int) k;
+ m = k / i->fragment_size;
+ info->blocks = m - i->optr_n_blocks;
+ i->optr_n_blocks = m;
+
+ break;
+ }
+
+ if (pa_context_errno(i->context) != PA_ERR_NODATA) {
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_get_latency(): %s\n", pa_strerror(pa_context_errno(i->context)));
+ break;
+ }
+
+ pa_threaded_mainloop_wait(i->mainloop);
+ }
+
+ pa_threaded_mainloop_unlock(i->mainloop);
+
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": GETOPTR bytes=%i, blocks=%i, ptr=%i\n", info->bytes, info->blocks, info->ptr);
+
+ break;
+ }
+
case SNDCTL_DSP_GETIPTR:
debug(DEBUG_LEVEL_NORMAL, __FILE__": invalid ioctl SNDCTL_DSP_GETIPTR\n");
goto inval;
-
- case SNDCTL_DSP_GETOPTR:
- debug(DEBUG_LEVEL_NORMAL, __FILE__": invalid ioctl SNDCTL_DSP_GETOPTR\n");
- goto inval;
-
+
default:
debug(DEBUG_LEVEL_NORMAL, __FILE__": unknown ioctl 0x%08lx\n", request);