Skip to content

Commit 3d70d22

Browse files
authored
Merge pull request tinyalsa#227 from dvdli/mmap-boundary-dev
match the boundary type with kernel driver
2 parents 2e6239c + c5b2fc7 commit 3d70d22

File tree

1 file changed

+45
-52
lines changed

1 file changed

+45
-52
lines changed

‎src/pcm.c‎

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ struct pcm {
305305
/** Size of the buffer */
306306
unsigned int buffer_size;
307307
/** The boundary for ring buffer pointers */
308-
unsigned int boundary;
308+
unsigned long boundary;
309309
/** Description of the last error that occured */
310310
char error[PCM_ERROR_MAX];
311311
/** Configuration that was passed to @ref pcm_open */
@@ -527,17 +527,14 @@ int pcm_set_config(struct pcm *pcm, const struct pcm_config *config)
527527
sparams.xfer_align = config->period_size / 2; /* needed for old kernels */
528528
sparams.silence_size = config->silence_size;
529529
sparams.silence_threshold = config->silence_threshold;
530-
pcm->boundary = sparams.boundary = pcm->buffer_size;
531-
532-
while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size)
533-
pcm->boundary *= 2;
534530

535531
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
536532
int errno_copy = errno;
537533
oops(pcm, errno, "cannot set sw params");
538534
return -errno_copy;
539535
}
540536

537+
pcm->boundary = sparams.boundary;
541538
return 0;
542539
}
543540

@@ -603,20 +600,17 @@ unsigned int pcm_frames_to_bytes(const struct pcm *pcm, unsigned int frames)
603600
static int pcm_sync_ptr(struct pcm *pcm, int flags)
604601
{
605602
if (pcm->sync_ptr == NULL) {
606-
/* status and control are mmaped */
607-
603+
/* status and control are mmapped */
608604
if (flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
609-
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HWSYNC) == -1) {
610-
oops(pcm, errno, "failed to sync hardware pointer");
611-
return -1;
605+
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_HWSYNC) == -1) {
606+
return oops(pcm, errno, "failed to sync hardware pointer");
612607
}
613608
}
614609
} else {
615610
pcm->sync_ptr->flags = flags;
616611
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_SYNC_PTR,
617612
pcm->sync_ptr) < 0) {
618-
oops(pcm, errno, "failed to sync mmap ptr");
619-
return -1;
613+
return oops(pcm, errno, "failed to sync mmap ptr");
620614
}
621615
}
622616

@@ -1235,45 +1229,49 @@ int pcm_stop(struct pcm *pcm)
12351229
return 0;
12361230
}
12371231

1238-
static inline int pcm_mmap_playback_avail(struct pcm *pcm)
1232+
static inline long pcm_mmap_playback_avail(struct pcm *pcm)
12391233
{
1240-
int avail;
1241-
1242-
avail = pcm->mmap_status->hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr;
1234+
long avail = pcm->mmap_status->hw_ptr + (unsigned long) pcm->buffer_size -
1235+
pcm->mmap_control->appl_ptr;
12431236

1244-
if (avail < 0)
1237+
if (avail < 0) {
12451238
avail += pcm->boundary;
1246-
else if (avail >= (int)pcm->boundary)
1239+
} else if ((unsigned long) avail >= pcm->boundary) {
12471240
avail -= pcm->boundary;
1241+
}
12481242

12491243
return avail;
12501244
}
12511245

1252-
static inline int pcm_mmap_capture_avail(struct pcm *pcm)
1246+
static inline long pcm_mmap_capture_avail(struct pcm *pcm)
12531247
{
1254-
int avail = pcm->mmap_status->hw_ptr - pcm->mmap_control->appl_ptr;
1255-
if (avail < 0)
1248+
long avail = pcm->mmap_status->hw_ptr - pcm->mmap_control->appl_ptr;
1249+
if (avail < 0) {
12561250
avail += pcm->boundary;
1251+
}
1252+
12571253
return avail;
12581254
}
12591255

12601256
int pcm_mmap_avail(struct pcm *pcm)
12611257
{
12621258
pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC);
1263-
if (pcm->flags & PCM_IN)
1264-
return pcm_mmap_capture_avail(pcm);
1265-
else
1266-
return pcm_mmap_playback_avail(pcm);
1259+
if (pcm->flags & PCM_IN) {
1260+
return (int) pcm_mmap_capture_avail(pcm);
1261+
} else {
1262+
return (int) pcm_mmap_playback_avail(pcm);
1263+
}
12671264
}
12681265

12691266
static void pcm_mmap_appl_forward(struct pcm *pcm, int frames)
12701267
{
1271-
unsigned int appl_ptr = pcm->mmap_control->appl_ptr;
1268+
unsigned long appl_ptr = pcm->mmap_control->appl_ptr;
12721269
appl_ptr += frames;
12731270

12741271
/* check for boundary wrap */
1275-
if (appl_ptr > pcm->boundary)
1276-
appl_ptr -= pcm->boundary;
1272+
if (appl_ptr >= pcm->boundary) {
1273+
appl_ptr -= pcm->boundary;
1274+
}
12771275
pcm->mmap_control->appl_ptr = appl_ptr;
12781276
}
12791277

@@ -1293,7 +1291,7 @@ int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
12931291
avail = pcm->buffer_size;
12941292
continuous = pcm->buffer_size - *offset;
12951293

1296-
/* we can only copy frames if the are availabale and continuos */
1294+
/* we can only copy frames if the are available and continuos */
12971295
copy_frames = *frames;
12981296
if (copy_frames > avail)
12991297
copy_frames = avail;
@@ -1411,7 +1409,7 @@ int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
14111409
*tstamp = pcm->mmap_status->tstamp;
14121410

14131411
/*
1414-
* When status is mmaped, get avail again to ensure
1412+
* When status is mmapped, get avail again to ensure
14151413
* valid timestamp.
14161414
*/
14171415
if (!pcm->sync_ptr) {
@@ -1473,22 +1471,22 @@ int pcm_wait(struct pcm *pcm, int timeout)
14731471
}
14741472

14751473
/*
1476-
* Transfer data to/from mmaped buffer. This imitates the
1474+
* Transfer data to/from mmapped buffer. This imitates the
14771475
* behavior of read/write system calls.
14781476
*
14791477
* However, this doesn't seems to offer any advantage over
14801478
* the read/write syscalls. Should it be removed?
14811479
*/
1482-
int pcm_mmap_transfer(struct pcm *pcm, void *buffer, unsigned int frames)
1480+
static int pcm_mmap_transfer(struct pcm *pcm, void *buffer, unsigned int frames)
14831481
{
14841482
int is_playback;
14851483

14861484
int state;
14871485
unsigned int avail;
1488-
unsigned int user_offset;
1486+
unsigned int user_offset = 0;
14891487

14901488
int err;
1491-
int tmp;
1489+
int transferred_frames;
14921490

14931491
is_playback = !(pcm->flags & PCM_IN);
14941492

@@ -1508,17 +1506,15 @@ int pcm_mmap_transfer(struct pcm *pcm, void *buffer, unsigned int frames)
15081506
* Another thread may start capture
15091507
*/
15101508
if (!is_playback && state == PCM_STATE_PREPARED &&
1511-
frames >= pcm->config.start_threshold) {
1512-
err = pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_START);
1513-
if (err == -1)
1509+
frames >= pcm->config.start_threshold) {
1510+
if (pcm_start(pcm) < 0) {
15141511
return -1;
1515-
/* state = PCM_STATE_RUNNING */
1512+
}
15161513
}
15171514

1518-
avail = pcm_mmap_avail(pcm);
1519-
user_offset = 0;
1520-
15211515
while (frames) {
1516+
avail = pcm_mmap_avail(pcm);
1517+
15221518
if (!avail) {
15231519
if (pcm->flags & PCM_NONBLOCK) {
15241520
errno = EAGAIN;
@@ -1531,25 +1527,22 @@ int pcm_mmap_transfer(struct pcm *pcm, void *buffer, unsigned int frames)
15311527
errno = -err;
15321528
break;
15331529
}
1534-
1535-
/* get hardware pointer */
1536-
avail = pcm_avail_update(pcm);
15371530
}
15381531

1539-
tmp = pcm_mmap_transfer_areas(pcm, buffer, user_offset, frames);
1540-
if (tmp < 0)
1532+
transferred_frames = pcm_mmap_transfer_areas(pcm, buffer, user_offset, frames);
1533+
if (transferred_frames < 0) {
15411534
break;
1535+
}
15421536

1543-
user_offset += tmp;
1544-
frames -= tmp;
1545-
avail -= tmp;
1537+
user_offset += transferred_frames;
1538+
frames -= transferred_frames;
15461539

15471540
/* start playback if written >= start_threshold */
15481541
if (is_playback && state == PCM_STATE_PREPARED &&
1549-
pcm->buffer_size - avail >= pcm->config.start_threshold) {
1550-
err = pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_START);
1551-
if (err == -1)
1542+
pcm->buffer_size - avail >= pcm->config.start_threshold) {
1543+
if (pcm_start(pcm) < 0) {
15521544
break;
1545+
}
15531546
}
15541547
}
15551548

0 commit comments

Comments
 (0)