summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-10-31 11:48:42 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-10-31 11:48:42 +0200
commit121226678e0e2b70ab531fd1e9e798b809f9ff1e (patch)
tree8218eecf4625c1de0d7d4c22f0f107c6120d4ee2
parentf835959ebfda70d71ae6a0a87e163203a69866b7 (diff)
fix brainfart with recorded data transformation
-rw-r--r--src/pcm.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/src/pcm.c b/src/pcm.c
index fa0983b..c6ba125 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -164,8 +164,24 @@ snd_pcm_wait(snd_pcm_t *pcm, int timeout)
return 1; // we are always ready for io
}
+snd_pcm_sframes_t
+snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
+{
+ const unsigned int chans = (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? pcm->hw.par.pchan : pcm->hw.par.rchan);
+ const int bpf = (pcm->hw.par.bps * chans);
+ return bytes / bpf;
+}
+
+ssize_t
+snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
+{
+ const unsigned int chans = (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? pcm->hw.par.pchan : pcm->hw.par.rchan);
+ const int bpf = (pcm->hw.par.bps * chans);
+ return frames * bpf;
+}
+
static size_t
-io_do(snd_pcm_t *pcm, void *buffer, const size_t frames, size_t (*io)(struct sio_hdl*, void*, size_t))
+io_do(snd_pcm_t *pcm, const void *buffer, const size_t frames, size_t (*io)(struct sio_hdl*, const void*, size_t, void*), void *arg)
{
if (pcm->hw.needs_conversion) {
struct aparams params = {
@@ -183,44 +199,34 @@ io_do(snd_pcm_t *pcm, void *buffer, const size_t frames, size_t (*io)(struct sio
size_t total_frames = frames, io_bytes = 0;
unsigned char decoded[4096], encoded[sizeof(decoded)];
const size_t max_frames = snd_pcm_bytes_to_frames(pcm, sizeof(decoded));
- for (unsigned char *p = buffer; total_frames > 0;) {
+ for (const unsigned char *p = buffer; total_frames > 0;) {
const int todo_frames = (total_frames > max_frames ? max_frames : total_frames);
total_frames -= todo_frames;
// sadly can't function pointer here as some formats may need different parameters for decoder
if (pcm->hw.alsa_format == SND_PCM_FORMAT_FLOAT_LE || pcm->hw.alsa_format == SND_PCM_FORMAT_FLOAT_BE) {
- dec_do_float(&dec, p, decoded, todo_frames);
+ dec_do_float(&dec, (void*)p, decoded, todo_frames);
} else {
- dec_do(&dec, p, decoded, todo_frames);
+ dec_do(&dec, (void*)p, decoded, todo_frames);
}
enc_do(&enc, decoded, encoded, todo_frames);
const size_t todo_bytes = snd_pcm_frames_to_bytes(pcm, todo_frames);
- io_bytes += io(pcm->hdl, encoded, todo_bytes);
+ io_bytes += io(pcm->hdl, encoded, todo_bytes, arg);
p += todo_bytes;
}
return io_bytes;
}
- return io(pcm->hdl, buffer, snd_pcm_frames_to_bytes(pcm, frames));
+ return io(pcm->hdl, buffer, snd_pcm_frames_to_bytes(pcm, frames), arg);
}
-snd_pcm_sframes_t
-snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
-{
- const unsigned int chans = (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? pcm->hw.par.pchan : pcm->hw.par.rchan);
- const int bpf = (pcm->hw.par.bps * chans);
- return bytes / bpf;
-}
-
-ssize_t
-snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
+static size_t
+cb_write(struct sio_hdl *hdl, const void *buffer, size_t bytes, void *arg)
{
- const unsigned int chans = (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? pcm->hw.par.pchan : pcm->hw.par.rchan);
- const int bpf = (pcm->hw.par.bps * chans);
- return frames * bpf;
+ return sio_write(hdl, buffer, bytes);
}
snd_pcm_sframes_t
@@ -231,12 +237,26 @@ snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
return 0;
}
- const snd_pcm_sframes_t ret = snd_pcm_bytes_to_frames(pcm, io_do(pcm, (void*)buffer, size, (size_t(*)(struct sio_hdl*, void*, size_t))sio_write));
+ const snd_pcm_sframes_t ret = snd_pcm_bytes_to_frames(pcm, io_do(pcm, buffer, size, cb_write, NULL));
pcm->written += ret;
pcm->avail -= ret;
return ret;
}
+struct transformation {
+ unsigned char *ptr, *end;
+};
+
+static size_t
+cb_transform(struct sio_hdl *hdl, const void *buffer, size_t bytes, void *arg)
+{
+ struct transformation *trans = arg;
+ assert(trans->ptr + bytes <= trans->end);
+ memcpy(trans->ptr, buffer, bytes);
+ trans->ptr += bytes;
+ return bytes;
+}
+
snd_pcm_sframes_t
snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
@@ -245,7 +265,11 @@ snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
return 0;
}
- const snd_pcm_sframes_t ret = snd_pcm_bytes_to_frames(pcm, io_do(pcm, buffer, size, sio_read));
+ size_t bytes = snd_pcm_frames_to_bytes(pcm, size);
+ bytes = sio_read(pcm->hdl, buffer, bytes);
+
+ struct transformation trans = { .ptr = buffer, .end = (unsigned char*)buffer + bytes };
+ const snd_pcm_sframes_t ret = snd_pcm_bytes_to_frames(pcm, io_do(pcm, buffer, snd_pcm_bytes_to_frames(pcm, bytes), cb_transform, &trans));
pcm->written += ret;
pcm->avail -= ret;
return ret;