diff options
Diffstat (limited to 'lib/rbcodec/codecs/alac.c')
-rw-r--r-- | lib/rbcodec/codecs/alac.c | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/lib/rbcodec/codecs/alac.c b/lib/rbcodec/codecs/alac.c index 903ea2850e..052a44cd70 100644 --- a/lib/rbcodec/codecs/alac.c +++ b/lib/rbcodec/codecs/alac.c | |||
@@ -31,6 +31,12 @@ CODEC_HEADER | |||
31 | 31 | ||
32 | static int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR; | 32 | static int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR; |
33 | 33 | ||
34 | static void set_elapsed_samples(uint32_t samplesdone) | ||
35 | { | ||
36 | uint32_t elapsedtime = (uint64_t)samplesdone * 1000ULL / ci->id3->frequency; | ||
37 | ci->set_elapsed(elapsedtime); | ||
38 | } | ||
39 | |||
34 | /* this is the codec entry point */ | 40 | /* this is the codec entry point */ |
35 | enum codec_status codec_main(enum codec_entry_call_reason reason) | 41 | enum codec_status codec_main(enum codec_entry_call_reason reason) |
36 | { | 42 | { |
@@ -50,12 +56,14 @@ enum codec_status codec_run(void) | |||
50 | demux_res_t demux_res; | 56 | demux_res_t demux_res; |
51 | stream_t input_stream; | 57 | stream_t input_stream; |
52 | uint32_t samplesdone; | 58 | uint32_t samplesdone; |
53 | uint32_t elapsedtime; | ||
54 | int samplesdecoded; | 59 | int samplesdecoded; |
55 | unsigned int i; | 60 | unsigned int i; |
56 | unsigned char* buffer; | 61 | unsigned char* buffer; |
57 | alac_file alac; | 62 | alac_file alac; |
58 | intptr_t param; | 63 | intptr_t param; |
64 | unsigned long resume_time; | ||
65 | uint32_t resume_offset; | ||
66 | unsigned int did_resume; | ||
59 | 67 | ||
60 | /* Clean and initialize decoder structures */ | 68 | /* Clean and initialize decoder structures */ |
61 | memset(&demux_res , 0, sizeof(demux_res)); | 69 | memset(&demux_res , 0, sizeof(demux_res)); |
@@ -71,10 +79,10 @@ enum codec_status codec_run(void) | |||
71 | 79 | ||
72 | stream_create(&input_stream,ci); | 80 | stream_create(&input_stream,ci); |
73 | 81 | ||
74 | /* Read resume info before calling qtmovie_read. */ | 82 | /* Save resume info because qtmovie_read() can modify it. */ |
75 | elapsedtime = ci->id3->elapsed; | 83 | resume_time = ci->id3->elapsed; |
76 | samplesdone = ci->id3->offset; | 84 | resume_offset = ci->id3->offset; |
77 | 85 | ||
78 | /* if qtmovie_read returns successfully, the stream is up to | 86 | /* if qtmovie_read returns successfully, the stream is up to |
79 | * the movie data, which can be used directly by the decoder */ | 87 | * the movie data, which can be used directly by the decoder */ |
80 | if (!qtmovie_read(&input_stream, &demux_res)) { | 88 | if (!qtmovie_read(&input_stream, &demux_res)) { |
@@ -84,28 +92,24 @@ enum codec_status codec_run(void) | |||
84 | 92 | ||
85 | /* initialise the sound converter */ | 93 | /* initialise the sound converter */ |
86 | alac_set_info(&alac, demux_res.codecdata); | 94 | alac_set_info(&alac, demux_res.codecdata); |
87 | |||
88 | /* Set i for first frame, seek to desired sample position for resuming. */ | ||
89 | i=0; | ||
90 | |||
91 | if (elapsedtime || samplesdone) { | ||
92 | if (samplesdone) { | ||
93 | samplesdone = | ||
94 | (uint32_t)((uint64_t)samplesdone*ci->id3->frequency / | ||
95 | (ci->id3->bitrate*128)); | ||
96 | } | ||
97 | else { | ||
98 | samplesdone = (elapsedtime/10) * (ci->id3->frequency/100); | ||
99 | } | ||
100 | 95 | ||
101 | if (!m4a_seek(&demux_res, &input_stream, samplesdone, | 96 | if (resume_time) |
102 | &samplesdone, (int*) &i)) { | 97 | did_resume = m4a_seek(&demux_res, &input_stream, |
103 | samplesdone = 0; | 98 | (uint64_t)resume_time * ci->id3->frequency / 1000ULL, |
104 | } | 99 | &samplesdone, (int *) &i); |
100 | else if (resume_offset) | ||
101 | did_resume = m4a_seek_raw(&demux_res, &input_stream, resume_offset, | ||
102 | &samplesdone, (int *) &i); | ||
103 | else | ||
104 | did_resume = 0; | ||
105 | |||
106 | /* Start from the beginning if we did not resume. */ | ||
107 | if (!did_resume) { | ||
108 | i = 0; | ||
109 | samplesdone = 0; | ||
105 | } | 110 | } |
106 | 111 | ||
107 | elapsedtime = samplesdone * 1000LL / ci->id3->frequency; | 112 | set_elapsed_samples(samplesdone); |
108 | ci->set_elapsed(elapsedtime); | ||
109 | 113 | ||
110 | /* The main decoding loop */ | 114 | /* The main decoding loop */ |
111 | while (i < demux_res.num_sample_byte_sizes) { | 115 | while (i < demux_res.num_sample_byte_sizes) { |
@@ -117,11 +121,10 @@ enum codec_status codec_run(void) | |||
117 | /* Deal with any pending seek requests */ | 121 | /* Deal with any pending seek requests */ |
118 | if (action == CODEC_ACTION_SEEK_TIME) { | 122 | if (action == CODEC_ACTION_SEEK_TIME) { |
119 | if (m4a_seek(&demux_res, &input_stream, | 123 | if (m4a_seek(&demux_res, &input_stream, |
120 | (param/10) * (ci->id3->frequency/100), | 124 | (uint64_t)param * ci->id3->frequency / 1000ULL, |
121 | &samplesdone, (int *)&i)) { | 125 | &samplesdone, (int *) &i)) |
122 | elapsedtime=samplesdone*1000LL/ci->id3->frequency; | 126 | set_elapsed_samples(samplesdone); |
123 | } | 127 | |
124 | ci->set_elapsed(elapsedtime); | ||
125 | ci->seek_complete(); | 128 | ci->seek_complete(); |
126 | } | 129 | } |
127 | 130 | ||
@@ -140,8 +143,7 @@ enum codec_status codec_run(void) | |||
140 | 143 | ||
141 | /* Update the elapsed-time indicator */ | 144 | /* Update the elapsed-time indicator */ |
142 | samplesdone+=samplesdecoded; | 145 | samplesdone+=samplesdecoded; |
143 | elapsedtime=samplesdone*1000LL/ci->id3->frequency; | 146 | set_elapsed_samples(samplesdone); |
144 | ci->set_elapsed(elapsedtime); | ||
145 | 147 | ||
146 | i++; | 148 | i++; |
147 | } | 149 | } |