diff options
author | Thom Johansen <thomj@rockbox.org> | 2006-08-31 18:18:57 +0000 |
---|---|---|
committer | Thom Johansen <thomj@rockbox.org> | 2006-08-31 18:18:57 +0000 |
commit | 20332bce1d49d7285109564d2e29ee18b0acd54e (patch) | |
tree | 9e423a673c6f7e03816a0f0ca785ef3915405b44 /apps/codecs/mpc.c | |
parent | 6af8603d9a8894e644f0b9508f2142c2b56d09a3 (diff) | |
download | rockbox-20332bce1d49d7285109564d2e29ee18b0acd54e.tar.gz rockbox-20332bce1d49d7285109564d2e29ee18b0acd54e.zip |
FS patch #5172 by Andrew Cupper. Musepack seeking support. Decoder should also be faster.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10827 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/mpc.c')
-rw-r--r-- | apps/codecs/mpc.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/apps/codecs/mpc.c b/apps/codecs/mpc.c index 6629801a56..c1fa0d7a99 100644 --- a/apps/codecs/mpc.c +++ b/apps/codecs/mpc.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | CODEC_HEADER | 23 | CODEC_HEADER |
24 | 24 | ||
25 | mpc_decoder decoder; | 25 | mpc_decoder decoder IBSS_ATTR; |
26 | 26 | ||
27 | /* Our implementations of the mpc_reader callback functions. */ | 27 | /* Our implementations of the mpc_reader callback functions. */ |
28 | mpc_int32_t read_impl(void *data, void *ptr, mpc_int32_t size) | 28 | mpc_int32_t read_impl(void *data, void *ptr, mpc_int32_t size) |
@@ -63,7 +63,8 @@ mpc_bool_t canseek_impl(void *data) | |||
63 | return true; | 63 | return true; |
64 | } | 64 | } |
65 | 65 | ||
66 | MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH] IBSS_ATTR; | 66 | MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; |
67 | mpc_uint32_t seek_table[10000]; | ||
67 | 68 | ||
68 | #ifdef USE_IRAM | 69 | #ifdef USE_IRAM |
69 | extern char iramcopy[]; | 70 | extern char iramcopy[]; |
@@ -92,6 +93,7 @@ enum codec_status codec_start(struct codec_api *api) | |||
92 | ci->configure(DSP_DITHER, (bool *)false); | 93 | ci->configure(DSP_DITHER, (bool *)false); |
93 | ci->configure(DSP_SET_SAMPLE_DEPTH, (long *)(28)); | 94 | ci->configure(DSP_SET_SAMPLE_DEPTH, (long *)(28)); |
94 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*16)); | 95 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*16)); |
96 | ci->configure(CODEC_SET_FILEBUF_PRESEEK, (long *)(0)); | ||
95 | 97 | ||
96 | /* Create a decoder instance */ | 98 | /* Create a decoder instance */ |
97 | reader.read = read_impl; | 99 | reader.read = read_impl; |
@@ -101,6 +103,11 @@ enum codec_status codec_start(struct codec_api *api) | |||
101 | reader.canseek = canseek_impl; | 103 | reader.canseek = canseek_impl; |
102 | reader.data = ci; | 104 | reader.data = ci; |
103 | 105 | ||
106 | /* Ensure that SeekTable is clear since decoder is reused */ | ||
107 | decoder.SeekTable = NULL; | ||
108 | |||
109 | mpc_decoder_set_seek_table(&decoder, seek_table, sizeof(seek_table)); | ||
110 | |||
104 | next_track: | 111 | next_track: |
105 | if (codec_init(api)) { | 112 | if (codec_init(api)) { |
106 | retval = CODEC_ERROR; | 113 | retval = CODEC_ERROR; |
@@ -113,7 +120,7 @@ next_track: | |||
113 | retval = CODEC_ERROR; | 120 | retval = CODEC_ERROR; |
114 | goto done; | 121 | goto done; |
115 | } | 122 | } |
116 | frequency = info.sample_freq; | 123 | frequency = info.sample_freq / 1000; |
117 | ci->configure(DSP_SET_FREQUENCY, (long *)(long)info.sample_freq); | 124 | ci->configure(DSP_SET_FREQUENCY, (long *)(long)info.sample_freq); |
118 | 125 | ||
119 | /* set playback engine up for correct number of channels */ | 126 | /* set playback engine up for correct number of channels */ |
@@ -139,21 +146,23 @@ next_track: | |||
139 | /* This is the decoding loop. */ | 146 | /* This is the decoding loop. */ |
140 | samplesdone = 0; | 147 | samplesdone = 0; |
141 | do { | 148 | do { |
142 | #if 0 | 149 | #if 1 |
143 | /* Complete seek handler. This will be extremely slow and unresponsive | 150 | /* Complete seek handler. */ |
144 | on target, so has been disabledt. */ | ||
145 | if (ci->seek_time) { | 151 | if (ci->seek_time) { |
146 | mpc_int64_t new_offset = (ci->seek_time - 1)*info.sample_freq/1000; | 152 | /* hack to improve seek time if filebuf goes empty */ |
153 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*512)); | ||
154 | mpc_int64_t new_offset = (ci->seek_time - 1)*frequency; | ||
147 | if (mpc_decoder_seek_sample(&decoder, new_offset)) { | 155 | if (mpc_decoder_seek_sample(&decoder, new_offset)) { |
148 | samplesdone = new_offset; | 156 | samplesdone = new_offset; |
149 | ci->set_elapsed(ci->seek_time); | 157 | ci->set_elapsed(ci->seek_time); |
150 | } | 158 | } |
151 | ci->seek_complete(); | 159 | ci->seek_complete(); |
160 | /* reset chunksize */ | ||
161 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*16)); | ||
162 | |||
152 | } | 163 | } |
153 | #else | 164 | #else |
154 | /* Seek to start of track handler. This is the only case that isn't slow | 165 | /* Seek to start of track handler. */ |
155 | as hell, and needs to be supported for the back button to function as | ||
156 | wanted. */ | ||
157 | if (ci->seek_time) { | 166 | if (ci->seek_time) { |
158 | if (ci->seek_time == 1 && mpc_decoder_seek_sample(&decoder, 0)) { | 167 | if (ci->seek_time == 1 && mpc_decoder_seek_sample(&decoder, 0)) { |
159 | samplesdone = 0; | 168 | samplesdone = 0; |
@@ -178,7 +187,7 @@ next_track: | |||
178 | status*sizeof(MPC_SAMPLE_FORMAT))) | 187 | status*sizeof(MPC_SAMPLE_FORMAT))) |
179 | ci->yield(); | 188 | ci->yield(); |
180 | samplesdone += status; | 189 | samplesdone += status; |
181 | ci->set_elapsed(samplesdone/(frequency/1000)); | 190 | ci->set_elapsed(samplesdone/frequency); |
182 | } | 191 | } |
183 | } while (status != 0); | 192 | } while (status != 0); |
184 | retval = CODEC_OK; | 193 | retval = CODEC_OK; |
@@ -188,6 +197,7 @@ done: | |||
188 | goto next_track; | 197 | goto next_track; |
189 | 198 | ||
190 | exit: | 199 | exit: |
200 | mpc_decoder_destroy(&decoder); | ||
191 | return retval; | 201 | return retval; |
192 | } | 202 | } |
193 | 203 | ||