From bb7c5dfd959e0088c5e64ba5e9b3f876463a5523 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Mon, 16 Sep 2013 14:31:17 -0700 Subject: add support for mmap read --- include/tinyalsa/asoundlib.h | 1 + pcm.c | 36 +++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h index 3d20b94..f578c4d 100644 --- a/include/tinyalsa/asoundlib.h +++ b/include/tinyalsa/asoundlib.h @@ -185,6 +185,7 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count); * mmap() support. */ int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count); +int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count); int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, unsigned int *frames); int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); diff --git a/pcm.c b/pcm.c index ca3eb3e..70d1d2f 100644 --- a/pcm.c +++ b/pcm.c @@ -300,7 +300,7 @@ static void pcm_hw_munmap_status(struct pcm *pcm) { } static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset, - const char *src, unsigned int src_offset, + char *buf, unsigned int src_offset, unsigned int frames) { int size_bytes = pcm_frames_to_bytes(pcm, frames); @@ -308,12 +308,18 @@ static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset, int src_offset_bytes = pcm_frames_to_bytes(pcm, src_offset); /* interleaved only atm */ - memcpy((char*)pcm->mmap_buffer + pcm_offset_bytes, - src + src_offset_bytes, size_bytes); + if (pcm->flags & PCM_IN) + memcpy(buf + src_offset_bytes, + (char*)pcm->mmap_buffer + pcm_offset_bytes, + size_bytes); + else + memcpy((char*)pcm->mmap_buffer + pcm_offset_bytes, + buf + src_offset_bytes, + size_bytes); return 0; } -static int pcm_mmap_write_areas(struct pcm *pcm, const char *src, +static int pcm_mmap_transfer_areas(struct pcm *pcm, char *buf, unsigned int offset, unsigned int size) { void *pcm_areas; @@ -323,7 +329,7 @@ static int pcm_mmap_write_areas(struct pcm *pcm, const char *src, while (size > 0) { frames = size; pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames); - pcm_areas_copy(pcm, pcm_offset, src, offset, frames); + pcm_areas_copy(pcm, pcm_offset, buf, offset, frames); commit = pcm_mmap_commit(pcm, pcm_offset, frames); if (commit < 0) { oops(pcm, commit, "failed to commit %d frames\n", frames); @@ -894,7 +900,7 @@ int pcm_wait(struct pcm *pcm, int timeout) return 1; } -int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes) +int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int bytes) { int err = 0, frames, avail; unsigned int offset = 0, count; @@ -955,7 +961,7 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes) break; /* copy frames from buffer */ - frames = pcm_mmap_write_areas(pcm, buffer, offset, frames); + frames = pcm_mmap_transfer_areas(pcm, (void *)buffer, offset, frames); if (frames < 0) { fprintf(stderr, "write error: hw 0x%x app 0x%x avail 0x%x\n", (unsigned int)pcm->mmap_status->hw_ptr, @@ -970,3 +976,19 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes) return 0; } + +int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count) +{ + if ((~pcm->flags) & (PCM_OUT | PCM_MMAP)) + return -ENOSYS; + + return pcm_mmap_transfer(pcm, (void *)data, count); +} + +int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count) +{ + if ((~pcm->flags) & (PCM_IN | PCM_MMAP)) + return -ENOSYS; + + return pcm_mmap_transfer(pcm, data, count); +} -- cgit v1.2.3