mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-02 09:01:48 -05:00
Cleaning and fixes
This commit is contained in:
parent
77d992bebc
commit
c12c08be8f
1 changed files with 130 additions and 57 deletions
|
|
@ -33,8 +33,68 @@ typedef struct {
|
||||||
char *fname;
|
char *fname;
|
||||||
int fd;
|
int fd;
|
||||||
int format;
|
int format;
|
||||||
|
size_t appl_ptr;
|
||||||
|
size_t file_ptr_bytes;
|
||||||
|
size_t wbuf_size;
|
||||||
|
size_t wbuf_size_bytes;
|
||||||
|
size_t wbuf_used_bytes;
|
||||||
|
char *wbuf;
|
||||||
|
snd_pcm_channel_area_t *wbuf_areas;
|
||||||
|
size_t buffer_bytes;
|
||||||
} snd_pcm_file_t;
|
} snd_pcm_file_t;
|
||||||
|
|
||||||
|
static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
|
||||||
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
assert(bytes <= file->wbuf_used_bytes);
|
||||||
|
while (bytes > 0) {
|
||||||
|
ssize_t err;
|
||||||
|
size_t n = bytes;
|
||||||
|
size_t cont = file->wbuf_size_bytes - file->file_ptr_bytes;
|
||||||
|
if (n > cont)
|
||||||
|
n = cont;
|
||||||
|
err = write(file->fd, file->wbuf + file->file_ptr_bytes, n);
|
||||||
|
if (err < 0) {
|
||||||
|
SYSERR("write failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes -= err;
|
||||||
|
file->wbuf_used_bytes -= err;
|
||||||
|
file->file_ptr_bytes += err;
|
||||||
|
if (file->file_ptr_bytes == file->wbuf_size_bytes)
|
||||||
|
file->file_ptr_bytes = 0;
|
||||||
|
if ((size_t)err != n)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_pcm_file_add_frames(snd_pcm_t *pcm,
|
||||||
|
const snd_pcm_channel_area_t *areas,
|
||||||
|
size_t offset, size_t frames)
|
||||||
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
while (frames > 0) {
|
||||||
|
size_t n = frames;
|
||||||
|
size_t cont = file->wbuf_size - file->appl_ptr;
|
||||||
|
size_t avail = file->wbuf_size - snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
|
||||||
|
if (n > cont)
|
||||||
|
n = cont;
|
||||||
|
if (n > avail)
|
||||||
|
n = avail;
|
||||||
|
snd_pcm_areas_copy(areas, offset,
|
||||||
|
file->wbuf_areas, file->appl_ptr,
|
||||||
|
pcm->channels, n, pcm->format);
|
||||||
|
frames -= n;
|
||||||
|
file->appl_ptr += n;
|
||||||
|
if (file->appl_ptr == file->wbuf_size)
|
||||||
|
file->appl_ptr = 0;
|
||||||
|
file->wbuf_used_bytes += snd_pcm_frames_to_bytes(pcm, n);
|
||||||
|
if (file->wbuf_used_bytes > file->buffer_bytes)
|
||||||
|
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes - file->buffer_bytes);
|
||||||
|
assert(file->wbuf_used_bytes < file->wbuf_size_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_close(snd_pcm_t *pcm)
|
static int snd_pcm_file_close(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
|
@ -45,6 +105,12 @@ static int snd_pcm_file_close(snd_pcm_t *pcm)
|
||||||
free(file->fname);
|
free(file->fname);
|
||||||
close(file->fd);
|
close(file->fd);
|
||||||
}
|
}
|
||||||
|
if (file->wbuf) {
|
||||||
|
free(file->wbuf);
|
||||||
|
free(file->wbuf_areas);
|
||||||
|
file->wbuf = 0;
|
||||||
|
file->wbuf_areas = 0;
|
||||||
|
}
|
||||||
free(file);
|
free(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -106,8 +172,13 @@ static int snd_pcm_file_prepare(snd_pcm_t *pcm)
|
||||||
static int snd_pcm_file_reset(snd_pcm_t *pcm)
|
static int snd_pcm_file_reset(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
/* FIXME */
|
int err = snd_pcm_reset(file->slave);
|
||||||
return snd_pcm_reset(file->slave);
|
if (err >= 0) {
|
||||||
|
/* FIXME: Questionable here */
|
||||||
|
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
|
||||||
|
assert(file->wbuf_used_bytes == 0);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_start(snd_pcm_t *pcm)
|
static int snd_pcm_file_start(snd_pcm_t *pcm)
|
||||||
|
|
@ -119,13 +190,24 @@ static int snd_pcm_file_start(snd_pcm_t *pcm)
|
||||||
static int snd_pcm_file_drop(snd_pcm_t *pcm)
|
static int snd_pcm_file_drop(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
return snd_pcm_drop(file->slave);
|
int err = snd_pcm_drop(file->slave);
|
||||||
|
if (err >= 0) {
|
||||||
|
/* FIXME: Questionable here */
|
||||||
|
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
|
||||||
|
assert(file->wbuf_used_bytes == 0);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_drain(snd_pcm_t *pcm)
|
static int snd_pcm_file_drain(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
return snd_pcm_drain(file->slave);
|
int err = snd_pcm_drain(file->slave);
|
||||||
|
if (err >= 0) {
|
||||||
|
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
|
||||||
|
assert(file->wbuf_used_bytes == 0);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
|
static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
|
||||||
|
|
@ -137,55 +219,27 @@ static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
|
||||||
static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames)
|
static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
ssize_t f = snd_pcm_rewind(file->slave, frames);
|
ssize_t err = snd_pcm_rewind(file->slave, frames);
|
||||||
off_t err;
|
if (err > 0) {
|
||||||
if (f > 0) {
|
size_t n = snd_pcm_frames_to_bytes(pcm, frames);
|
||||||
err = lseek(file->fd, -snd_pcm_frames_to_bytes(pcm, f), SEEK_CUR);
|
ssize_t ptr;
|
||||||
if (err < 0)
|
assert(n >= file->wbuf_used_bytes);
|
||||||
|
ptr = file->appl_ptr - err;
|
||||||
|
if (ptr < 0)
|
||||||
|
ptr += file->wbuf_size;
|
||||||
|
file->wbuf_used_bytes -= n;
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void snd_pcm_file_write_areas(snd_pcm_t *pcm,
|
|
||||||
const snd_pcm_channel_area_t *areas,
|
|
||||||
size_t offset, size_t frames)
|
|
||||||
{
|
|
||||||
snd_pcm_file_t *file = pcm->private;
|
|
||||||
size_t bytes = snd_pcm_frames_to_bytes(pcm, frames);
|
|
||||||
char *buf;
|
|
||||||
size_t channels = pcm->channels;
|
|
||||||
snd_pcm_channel_area_t buf_areas[channels];
|
|
||||||
size_t channel;
|
|
||||||
ssize_t r;
|
|
||||||
switch (pcm->access) {
|
|
||||||
case SND_PCM_ACCESS_MMAP_INTERLEAVED:
|
|
||||||
case SND_PCM_ACCESS_RW_INTERLEAVED:
|
|
||||||
buf = snd_pcm_channel_area_addr(areas, offset);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buf = alloca(bytes);
|
|
||||||
for (channel = 0; channel < channels; ++channel) {
|
|
||||||
snd_pcm_channel_area_t *a = &buf_areas[channel];
|
|
||||||
a->addr = buf;
|
|
||||||
a->first = pcm->bits_per_sample * channel;
|
|
||||||
a->step = pcm->bits_per_frame;
|
|
||||||
}
|
|
||||||
snd_pcm_areas_copy(areas, offset, buf_areas, 0,
|
|
||||||
channels, frames, pcm->format);
|
|
||||||
}
|
|
||||||
r = write(file->fd, buf, bytes);
|
|
||||||
assert(r == (ssize_t)bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
|
static ssize_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
snd_pcm_channel_area_t areas[pcm->channels];
|
||||||
ssize_t n = snd_pcm_writei(file->slave, buffer, size);
|
ssize_t n = snd_pcm_writei(file->slave, buffer, size);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
size_t bytes = snd_pcm_frames_to_bytes(pcm, n);
|
snd_pcm_areas_from_buf(pcm, areas, (void*) buffer);
|
||||||
ssize_t r = write(file->fd, buffer, bytes);
|
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||||
assert(r == (ssize_t)bytes);
|
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +251,7 @@ static ssize_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, size_t size)
|
||||||
ssize_t n = snd_pcm_writen(file->slave, bufs, size);
|
ssize_t n = snd_pcm_writen(file->slave, bufs, size);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
||||||
snd_pcm_file_write_areas(pcm, areas, 0, n);
|
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -205,11 +259,11 @@ static ssize_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, size_t size)
|
||||||
static ssize_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, size_t size)
|
static ssize_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
|
snd_pcm_channel_area_t areas[pcm->channels];
|
||||||
ssize_t n = snd_pcm_readi(file->slave, buffer, size);
|
ssize_t n = snd_pcm_readi(file->slave, buffer, size);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
size_t bytes = snd_pcm_frames_to_bytes(pcm, n);
|
snd_pcm_areas_from_buf(pcm, areas, buffer);
|
||||||
ssize_t r = write(file->fd, buffer, bytes);
|
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||||
assert(r == (ssize_t)bytes);
|
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -221,7 +275,7 @@ static ssize_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, size_t size)
|
||||||
ssize_t n = snd_pcm_writen(file->slave, bufs, size);
|
ssize_t n = snd_pcm_writen(file->slave, bufs, size);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
||||||
snd_pcm_file_write_areas(pcm, areas, 0, n);
|
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -237,9 +291,9 @@ static ssize_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, size_t size)
|
||||||
while (xfer < (size_t)n) {
|
while (xfer < (size_t)n) {
|
||||||
size_t frames = size - xfer;
|
size_t frames = size - xfer;
|
||||||
size_t cont = pcm->buffer_size - ofs;
|
size_t cont = pcm->buffer_size - ofs;
|
||||||
if (cont < frames)
|
if (frames > cont)
|
||||||
frames = cont;
|
frames = cont;
|
||||||
snd_pcm_file_write_areas(pcm, snd_pcm_mmap_areas(file->slave), ofs, frames);
|
snd_pcm_file_add_frames(pcm, snd_pcm_mmap_areas(file->slave), ofs, frames);
|
||||||
ofs += frames;
|
ofs += frames;
|
||||||
if (ofs == pcm->buffer_size)
|
if (ofs == pcm->buffer_size)
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
|
|
@ -263,7 +317,28 @@ static int snd_pcm_file_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||||
static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
snd_pcm_file_t *file = pcm->private;
|
||||||
return snd_pcm_hw_params(file->slave, params);
|
unsigned int channel;
|
||||||
|
snd_pcm_t *slave = file->slave;
|
||||||
|
int err = snd_pcm_hw_params(slave, params);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
if (file->wbuf) {
|
||||||
|
free(file->wbuf);
|
||||||
|
free(file->wbuf_areas);
|
||||||
|
}
|
||||||
|
file->buffer_bytes = snd_pcm_frames_to_bytes(slave, slave->buffer_size);
|
||||||
|
file->wbuf_size = slave->buffer_size * 2;
|
||||||
|
file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size);
|
||||||
|
file->wbuf = malloc(file->wbuf_size_bytes);
|
||||||
|
file->wbuf_areas = malloc(sizeof(*file->wbuf_areas) * slave->channels);
|
||||||
|
file->appl_ptr = file->file_ptr_bytes = 0;
|
||||||
|
for (channel = 0; channel < slave->channels; ++channel) {
|
||||||
|
snd_pcm_channel_area_t *a = &file->wbuf_areas[channel];
|
||||||
|
a->addr = file->wbuf;
|
||||||
|
a->first = slave->bits_per_sample * channel;
|
||||||
|
a->step = slave->bits_per_frame;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
||||||
|
|
@ -274,14 +349,12 @@ static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
||||||
|
|
||||||
static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
return 0;
|
||||||
return snd_pcm_mmap(file->slave);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
static int snd_pcm_file_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private;
|
return 0;
|
||||||
return snd_pcm_munmap(file->slave);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_pcm_file_dump(snd_pcm_t *pcm, FILE *fp)
|
static void snd_pcm_file_dump(snd_pcm_t *pcm, FILE *fp)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue