mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-11 14:12:26 -05:00
Added some basic codec configuration functionality.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6652 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2326beaf39
commit
68b9acd7de
5 changed files with 62 additions and 22 deletions
|
|
@ -67,9 +67,8 @@ static volatile bool paused;
|
||||||
#define CODEC_FLAC "/.rockbox/codecs/codecflac.rock";
|
#define CODEC_FLAC "/.rockbox/codecs/codecflac.rock";
|
||||||
#define CODEC_WAV "/.rockbox/codecs/codecwav.rock";
|
#define CODEC_WAV "/.rockbox/codecs/codecwav.rock";
|
||||||
|
|
||||||
#define AUDIO_WATERMARK (1024*256)
|
#define AUDIO_DEFAULT_WATERMARK (1024*256)
|
||||||
#define AUDIO_FILE_CHUNK (1024*32)
|
#define AUDIO_DEFAULT_FILECHUNK (1024*32)
|
||||||
#define AUDIO_INITIAL_CHUNK (1024*1024*2)
|
|
||||||
|
|
||||||
#define AUDIO_PLAY 1
|
#define AUDIO_PLAY 1
|
||||||
#define AUDIO_STOP 2
|
#define AUDIO_STOP 2
|
||||||
|
|
@ -165,8 +164,10 @@ static struct codec_api ci;
|
||||||
variable keeps information about whether to go a next/previous track. */
|
variable keeps information about whether to go a next/previous track. */
|
||||||
static int new_track;
|
static int new_track;
|
||||||
|
|
||||||
/* If we have just started playing, don't fill the whole file buffer. */
|
/* Configuration */
|
||||||
static unsigned int first_bufferfill;
|
static int conf_bufferlimit;
|
||||||
|
static int conf_watermark;
|
||||||
|
static int conf_filechunk;
|
||||||
|
|
||||||
static bool v1first = false;
|
static bool v1first = false;
|
||||||
|
|
||||||
|
|
@ -359,6 +360,26 @@ bool codec_seek_buffer_callback(off_t newpos)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void codec_configure_callback(int setting, void *value)
|
||||||
|
{
|
||||||
|
switch (setting) {
|
||||||
|
case CODEC_SET_FILEBUF_WATERMARK:
|
||||||
|
conf_watermark = (unsigned int)value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODEC_SET_FILEBUF_CHUNKSIZE:
|
||||||
|
conf_filechunk = (unsigned int)value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODEC_SET_FILEBUF_LIMIT:
|
||||||
|
conf_bufferlimit = (unsigned int)value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logf("Illegal key: %d", setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Simple file type probing by looking filename extension. */
|
/* Simple file type probing by looking filename extension. */
|
||||||
int probe_file_format(const char *filename)
|
int probe_file_format(const char *filename)
|
||||||
{
|
{
|
||||||
|
|
@ -431,10 +452,10 @@ void audio_fill_file_buffer(void)
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fill_bytesleft < MIN(AUDIO_FILE_CHUNK,
|
if (fill_bytesleft < MIN((unsigned int)conf_filechunk,
|
||||||
tracks[track_widx].filerem - i))
|
tracks[track_widx].filerem - i))
|
||||||
break ;
|
break ;
|
||||||
rc = MIN(AUDIO_FILE_CHUNK, codecbuflen - buf_widx);
|
rc = MIN(conf_filechunk, codecbuflen - buf_widx);
|
||||||
rc = read(current_fd, &codecbuf[buf_widx], rc);
|
rc = read(current_fd, &codecbuf[buf_widx], rc);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
tracks[track_widx].filerem = 0;
|
tracks[track_widx].filerem = 0;
|
||||||
|
|
@ -535,7 +556,7 @@ bool loadcodec(const char *trackname, bool start_play)
|
||||||
}
|
}
|
||||||
|
|
||||||
size = filesize(fd);
|
size = filesize(fd);
|
||||||
if ((off_t)fill_bytesleft < size + AUDIO_WATERMARK) {
|
if ((off_t)fill_bytesleft < size + conf_watermark) {
|
||||||
logf("Not enough space");
|
logf("Not enough space");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -550,7 +571,7 @@ bool loadcodec(const char *trackname, bool start_play)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_n = MIN(AUDIO_FILE_CHUNK, codecbuflen - buf_widx);
|
copy_n = MIN(conf_filechunk, codecbuflen - buf_widx);
|
||||||
rc = read(fd, &codecbuf[buf_widx], copy_n);
|
rc = read(fd, &codecbuf[buf_widx], copy_n);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -603,7 +624,14 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
/* Load the codec */
|
/* Load the codec */
|
||||||
if (buf_widx >= codecbuflen)
|
if (buf_widx >= codecbuflen)
|
||||||
buf_widx -= codecbuflen;
|
buf_widx -= codecbuflen;
|
||||||
|
|
||||||
|
/* Set default values */
|
||||||
|
if (start_play) {
|
||||||
|
conf_bufferlimit = 0;
|
||||||
|
conf_watermark = AUDIO_DEFAULT_WATERMARK;
|
||||||
|
conf_filechunk = AUDIO_DEFAULT_FILECHUNK;
|
||||||
|
}
|
||||||
|
|
||||||
tracks[track_widx].codecbuf = &codecbuf[buf_widx];
|
tracks[track_widx].codecbuf = &codecbuf[buf_widx];
|
||||||
if (!loadcodec(trackname, start_play)) {
|
if (!loadcodec(trackname, start_play)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
@ -720,18 +748,19 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limit buffering size at first run. */
|
|
||||||
if (first_bufferfill && fill_bytesleft >= first_bufferfill) {
|
|
||||||
fill_bytesleft = first_bufferfill;
|
|
||||||
first_bufferfill = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
track_changed = true;
|
track_changed = true;
|
||||||
track_count++;
|
track_count++;
|
||||||
i = tracks[track_widx].filepos;
|
i = tracks[track_widx].filepos;
|
||||||
while (i < size) {
|
while (i < size) {
|
||||||
/* Give codecs some processing time to prevent glitches. */
|
/* Give codecs some processing time to prevent glitches. */
|
||||||
yield_codecs();
|
yield_codecs();
|
||||||
|
|
||||||
|
/* Limit buffering size at first run. */
|
||||||
|
if (conf_bufferlimit && (int)fill_bytesleft >= conf_bufferlimit) {
|
||||||
|
fill_bytesleft = conf_bufferlimit;
|
||||||
|
conf_bufferlimit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!queue_empty(&audio_queue)) {
|
if (!queue_empty(&audio_queue)) {
|
||||||
logf("Buffering interrupted");
|
logf("Buffering interrupted");
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
@ -741,7 +770,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
if (fill_bytesleft == 0)
|
if (fill_bytesleft == 0)
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
copy_n = MIN(AUDIO_FILE_CHUNK, codecbuflen - buf_widx);
|
copy_n = MIN(conf_filechunk, codecbuflen - buf_widx);
|
||||||
copy_n = MIN(size - i, copy_n);
|
copy_n = MIN(size - i, copy_n);
|
||||||
copy_n = MIN((int)fill_bytesleft, copy_n);
|
copy_n = MIN((int)fill_bytesleft, copy_n);
|
||||||
rc = read(fd, &codecbuf[buf_widx], copy_n);
|
rc = read(fd, &codecbuf[buf_widx], copy_n);
|
||||||
|
|
@ -825,7 +854,7 @@ void audio_check_buffer(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Start buffer filling as necessary. */
|
/* Start buffer filling as necessary. */
|
||||||
if (codecbufused > AUDIO_WATERMARK || !queue_empty(&audio_queue)
|
if (codecbufused > conf_watermark || !queue_empty(&audio_queue)
|
||||||
|| !playing || ci.stop_codec || ci.reload_codec)
|
|| !playing || ci.stop_codec || ci.reload_codec)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
|
|
@ -1163,7 +1192,6 @@ void audio_play(int offset)
|
||||||
#endif
|
#endif
|
||||||
paused = false;
|
paused = false;
|
||||||
playing = true;
|
playing = true;
|
||||||
first_bufferfill = AUDIO_INITIAL_CHUNK;
|
|
||||||
queue_post(&audio_queue, AUDIO_PLAY, (void *)offset);
|
queue_post(&audio_queue, AUDIO_PLAY, (void *)offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1435,6 +1463,7 @@ void audio_init(void)
|
||||||
ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
|
ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
|
||||||
ci.seek_buffer = codec_seek_buffer_callback;
|
ci.seek_buffer = codec_seek_buffer_callback;
|
||||||
ci.set_elapsed = codec_set_elapsed_callback;
|
ci.set_elapsed = codec_set_elapsed_callback;
|
||||||
|
ci.configure = codec_configure_callback;
|
||||||
|
|
||||||
queue_init(&audio_queue);
|
queue_init(&audio_queue);
|
||||||
queue_init(&codec_queue);
|
queue_init(&codec_queue);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,13 @@
|
||||||
#define AFMT_REAL 0x0800 // Realaudio
|
#define AFMT_REAL 0x0800 // Realaudio
|
||||||
#define AFMT_UNKNOWN 0x1000 // Unknown file format
|
#define AFMT_UNKNOWN 0x1000 // Unknown file format
|
||||||
|
|
||||||
|
#define CODEC_SET_FILEBUF_WATERMARK 1
|
||||||
|
#define CODEC_SET_FILEBUF_CHUNKSIZE 2
|
||||||
|
#define CODEC_SET_FILEBUF_LIMIT 3
|
||||||
|
|
||||||
|
/* Not yet implemented. */
|
||||||
|
#define CODEC_SET_AUDIOBUF_WATERMARK 4
|
||||||
|
|
||||||
struct codec_api {
|
struct codec_api {
|
||||||
off_t filesize;
|
off_t filesize;
|
||||||
off_t curpos;
|
off_t curpos;
|
||||||
|
|
@ -60,6 +67,8 @@ struct codec_api {
|
||||||
bool (*seek_buffer)(off_t newpos);
|
bool (*seek_buffer)(off_t newpos);
|
||||||
off_t (*mp3_get_filepos)(int newtime);
|
off_t (*mp3_get_filepos)(int newtime);
|
||||||
bool (*request_next_track)(void);
|
bool (*request_next_track)(void);
|
||||||
|
|
||||||
|
void (*configure)(int setting, void *value);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
|
||||||
rb->memcpy(iramstart, iramcopy, iramend-iramstart);
|
rb->memcpy(iramstart, iramcopy, iramend-iramstart);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This function sets up the buffers and reads the file into RAM */
|
ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10));
|
||||||
|
ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512));
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,8 +216,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
|
||||||
|
|
||||||
/* Create a decoder instance */
|
/* Create a decoder instance */
|
||||||
|
|
||||||
next_track:
|
ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
|
||||||
|
|
||||||
|
next_track:
|
||||||
memset(&Stream, 0, sizeof(struct mad_stream));
|
memset(&Stream, 0, sizeof(struct mad_stream));
|
||||||
memset(&Frame, 0, sizeof(struct mad_frame));
|
memset(&Frame, 0, sizeof(struct mad_frame));
|
||||||
memset(&Synth, 0, sizeof(struct mad_synth));
|
memset(&Synth, 0, sizeof(struct mad_synth));
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
|
||||||
rb->memcpy(iramstart, iramcopy, iramend-iramstart);
|
rb->memcpy(iramstart, iramcopy, iramend-iramstart);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This function sets up the buffers and reads the file into RAM */
|
ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
|
||||||
|
|
||||||
/* We need to flush reserver memory every track load. */
|
/* We need to flush reserver memory every track load. */
|
||||||
next_track:
|
next_track:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue