summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/input_cdda.c132
1 files changed, 89 insertions, 43 deletions
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index 4de29e449..314479a74 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -20,7 +20,7 @@
* Compact Disc Digital Audio (CDDA) Input Plugin
* by Mike Melanson (melanson@pcisys.net)
*
- * $Id: input_cdda.c,v 1.17 2003/05/02 15:02:11 miguelfreitas Exp $
+ * $Id: input_cdda.c,v 1.18 2003/05/06 00:22:39 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -161,29 +161,36 @@ static void read_cdrom_toc(int fd, cdrom_toc *toc) {
tocentry.cdte_addr.msf.frame;
}
-static void read_cdrom_frame(int fd, int frame,
- unsigned char data[CD_RAW_FRAME_SIZE]) {
+static int read_cdrom_frames(int fd, int frame, int num_frames,
+ unsigned char *data) {
struct cdrom_msf msf;
- /* read from starting frame... */
- msf.cdmsf_min0 = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
- msf.cdmsf_sec0 = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
- msf.cdmsf_frame0 = frame % CD_FRAMES_PER_SECOND;
+ while( num_frames ) {
+ /* read from starting frame... */
+ msf.cdmsf_min0 = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
+ msf.cdmsf_sec0 = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
+ msf.cdmsf_frame0 = frame % CD_FRAMES_PER_SECOND;
- /* read until ending track (starting frame + 1)... */
- msf.cdmsf_min1 = (frame + 1) / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
- msf.cdmsf_sec1 = ((frame + 1) / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
- msf.cdmsf_frame1 = (frame + 1) % CD_FRAMES_PER_SECOND;
+ /* read until ending track (starting frame + 1)... */
+ msf.cdmsf_min1 = (frame + 1) / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
+ msf.cdmsf_sec1 = ((frame + 1) / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
+ msf.cdmsf_frame1 = (frame + 1) % CD_FRAMES_PER_SECOND;
- /* MSF structure is the input to the ioctl */
- memcpy(data, &msf, sizeof(msf));
+ /* MSF structure is the input to the ioctl */
+ memcpy(data, &msf, sizeof(msf));
- /* read a frame */
- if(ioctl(fd, CDROMREADRAW, data, data) < 0) {
- perror("CDROMREADRAW");
- return;
+ /* read a frame */
+ if(ioctl(fd, CDROMREADRAW, data, data) < 0) {
+ perror("CDROMREADRAW");
+ return -1;
+ }
+
+ data += CD_RAW_FRAME_SIZE;
+ frame++;
+ num_frames--;
}
+ return 0;
}
#elif defined(__sun)
@@ -256,21 +263,28 @@ static void read_cdrom_toc(int fd, cdrom_toc *toc) {
tocentry.cdte_addr.msf.frame;
}
-static void read_cdrom_frame(int fd, int frame,
- unsigned char data[CD_RAW_FRAME_SIZE]) {
+static int read_cdrom_frames(int fd, int frame, int num_frames,
+ unsigned char *data) {
struct cdrom_cdda cdda;
- cdda.cdda_addr = frame - 2 * CD_FRAMES_PER_SECOND;
- cdda.cdda_length = 1;
- cdda.cdda_data = data;
- cdda.cdda_subcode = CDROM_DA_NO_SUBCODE;
+ while( num_frames ) {
+ cdda.cdda_addr = frame - 2 * CD_FRAMES_PER_SECOND;
+ cdda.cdda_length = 1;
+ cdda.cdda_data = data;
+ cdda.cdda_subcode = CDROM_DA_NO_SUBCODE;
- /* read a frame */
- if(ioctl(fd, CDROMCDDA, &cdda) < 0) {
- perror("CDROMCDDA");
- return;
+ /* read a frame */
+ if(ioctl(fd, CDROMCDDA, &cdda) < 0) {
+ perror("CDROMCDDA");
+ return -1;
+ }
+
+ data += CD_RAW_FRAME_SIZE;
+ frame++;
+ num_frames--;
}
+ return 0;
}
#elif defined(__FreeBSD__)
@@ -343,23 +357,30 @@ static void read_cdrom_toc(int fd, cdrom_toc *toc) {
tocentry.entry.addr.msf.frame;
}
-static void read_cdrom_frame(int fd, int frame,
- unsigned char data[CD_RAW_FRAME_SIZE]) {
+static int read_cdrom_frames(int fd, int frame, int num_frames,
+ unsigned char *data) {
struct ioc_read_audio cdda;
- cdda.address_format = CD_MSF_FORMAT;
- cdda.address.msf.minute = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
- cdda.address.msf.second = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
- cdda.address.msf.frame = frame % CD_FRAMES_PER_SECOND;
- cdda.nframes = 1;
- cdda.buffer = data;
-
- /* read a frame */
- if(ioctl(fd, CDIOCREADAUDIO, &cdda) < 0) {
- perror("CDIOCREADAUDIO");
- return;
+ while( num_frames ) {
+ cdda.address_format = CD_MSF_FORMAT;
+ cdda.address.msf.minute = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND;
+ cdda.address.msf.second = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE;
+ cdda.address.msf.frame = frame % CD_FRAMES_PER_SECOND;
+ cdda.nframes = 1;
+ cdda.buffer = data;
+
+ /* read a frame */
+ if(ioctl(fd, CDIOCREADAUDIO, &cdda) < 0) {
+ perror("CDIOCREADAUDIO");
+ return -1;
+ }
+
+ data += CD_RAW_FRAME_SIZE;
+ frame++;
+ num_frames--;
}
+ return 0;
}
#else
@@ -371,8 +392,8 @@ static void read_cdrom_toc(int fd, cdrom_toc *toc) {
}
-static void read_cdrom_frame(int fd, int frame,
- unsigned char data[CD_RAW_FRAME_SIZE]) {
+static int read_cdrom_frames(int fd, int frame, int num_frames,
+ unsigned char *data) {
}
@@ -385,6 +406,7 @@ static void read_cdrom_frame(int fd, int frame,
*************************************************************************/
#define MAX_TRACKS 99
+#define CACHED_FRAMES 100
typedef struct {
int start;
@@ -424,6 +446,10 @@ typedef struct {
int current_frame;
int last_frame;
+ unsigned char cache[CACHED_FRAMES][CD_RAW_FRAME_SIZE];
+ int cache_first;
+ int cache_last;
+
} cdda_input_plugin_t;
typedef struct {
@@ -1163,7 +1189,23 @@ static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buf
if (this->current_frame >= this->last_frame)
return NULL;
- read_cdrom_frame(this->fd, this->current_frame++, frame_data);
+ /* populate frame cache */
+ if( this->cache_first == -1 ||
+ this->current_frame < this->cache_first ||
+ this->current_frame > this->cache_last ) {
+
+ this->cache_first = this->current_frame;
+ this->cache_last = this->current_frame + CACHED_FRAMES - 1;
+ if( this->cache_last > this->last_frame )
+ this->cache_last = this->last_frame;
+
+ read_cdrom_frames(this->fd, this->cache_first,
+ this->cache_last - this->cache_first + 1,
+ this->cache[0]);
+ }
+
+ memcpy(frame_data, this->cache[this->current_frame-this->cache_first], CD_RAW_FRAME_SIZE);
+ this->current_frame++;
buf = fifo->buffer_pool_alloc(fifo);
buf->content = buf->mem;
@@ -1267,7 +1309,11 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
this->last_frame = toc.leadout_track.first_frame - 1;
else
this->last_frame = toc.toc_entries[this->track + 1].first_frame - 1;
+
+ /* invalidate cache */
+ this->cache_first = this->cache_last = -1;
+
/*
* CDDB
*/