summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/alac.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/alac.c')
-rw-r--r--lib/rbcodec/codecs/alac.c64
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
32static int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR; 32static int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR;
33 33
34static 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 */
35enum codec_status codec_main(enum codec_entry_call_reason reason) 41enum 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 }