diff options
Diffstat (limited to 'apps/codecs/alac.c')
-rw-r--r-- | apps/codecs/alac.c | 188 |
1 files changed, 93 insertions, 95 deletions
diff --git a/apps/codecs/alac.c b/apps/codecs/alac.c index cd9129a278..82bda264c3 100644 --- a/apps/codecs/alac.c +++ b/apps/codecs/alac.c | |||
@@ -32,116 +32,114 @@ CODEC_HEADER | |||
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 | /* this is the codec entry point */ | 34 | /* this is the codec entry point */ |
35 | enum codec_status codec_main(void) | 35 | enum codec_status codec_main(enum codec_entry_call_reason reason) |
36 | { | 36 | { |
37 | size_t n; | 37 | if (reason == CODEC_LOAD) { |
38 | demux_res_t demux_res; | 38 | /* Generic codec initialisation */ |
39 | stream_t input_stream; | 39 | ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); |
40 | uint32_t samplesdone; | 40 | ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1); |
41 | uint32_t elapsedtime; | 41 | } |
42 | int samplesdecoded; | ||
43 | unsigned int i; | ||
44 | unsigned char* buffer; | ||
45 | alac_file alac; | ||
46 | int retval; | ||
47 | |||
48 | /* Generic codec initialisation */ | ||
49 | ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); | ||
50 | ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1); | ||
51 | |||
52 | next_track: | ||
53 | retval = CODEC_OK; | ||
54 | |||
55 | /* Clean and initialize decoder structures */ | ||
56 | memset(&demux_res , 0, sizeof(demux_res)); | ||
57 | if (codec_init()) { | ||
58 | LOGF("ALAC: Error initialising codec\n"); | ||
59 | retval = CODEC_ERROR; | ||
60 | goto exit; | ||
61 | } | ||
62 | |||
63 | if (codec_wait_taginfo() != 0) | ||
64 | goto done; | ||
65 | |||
66 | ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); | ||
67 | codec_set_replaygain(ci->id3); | ||
68 | 42 | ||
69 | stream_create(&input_stream,ci); | 43 | return CODEC_OK; |
44 | } | ||
70 | 45 | ||
71 | /* Read from ci->id3->offset before calling qtmovie_read. */ | 46 | /* this is called for each file to process */ |
72 | samplesdone = (uint32_t)(((uint64_t)(ci->id3->offset) * ci->id3->frequency) / | 47 | enum codec_status codec_run(void) |
73 | (ci->id3->bitrate*128)); | 48 | { |
74 | 49 | size_t n; | |
75 | /* if qtmovie_read returns successfully, the stream is up to | 50 | demux_res_t demux_res; |
76 | * the movie data, which can be used directly by the decoder */ | 51 | stream_t input_stream; |
77 | if (!qtmovie_read(&input_stream, &demux_res)) { | 52 | uint32_t samplesdone; |
78 | LOGF("ALAC: Error initialising file\n"); | 53 | uint32_t elapsedtime = 0; |
79 | retval = CODEC_ERROR; | 54 | int samplesdecoded; |
80 | goto done; | 55 | unsigned int i; |
81 | } | 56 | unsigned char* buffer; |
82 | 57 | alac_file alac; | |
83 | /* initialise the sound converter */ | 58 | intptr_t param; |
84 | create_alac(demux_res.sound_sample_size, demux_res.num_channels,&alac); | 59 | |
85 | alac_set_info(&alac, demux_res.codecdata); | 60 | /* Clean and initialize decoder structures */ |
86 | 61 | memset(&demux_res , 0, sizeof(demux_res)); | |
87 | /* Set i for first frame, seek to desired sample position for resuming. */ | 62 | if (codec_init()) { |
88 | i=0; | 63 | LOGF("ALAC: Error initialising codec\n"); |
89 | if (samplesdone > 0) { | 64 | return CODEC_ERROR; |
90 | if (m4a_seek(&demux_res, &input_stream, samplesdone, | ||
91 | &samplesdone, (int*) &i)) { | ||
92 | elapsedtime = (samplesdone * 10) / (ci->id3->frequency / 100); | ||
93 | ci->set_elapsed(elapsedtime); | ||
94 | } else { | ||
95 | samplesdone = 0; | ||
96 | } | 65 | } |
97 | } | ||
98 | 66 | ||
99 | /* The main decoding loop */ | 67 | ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); |
100 | while (i < demux_res.num_sample_byte_sizes) { | 68 | codec_set_replaygain(ci->id3); |
101 | ci->yield(); | 69 | |
102 | if (ci->stop_codec || ci->new_track) { | 70 | ci->seek_buffer(0); |
103 | break; | 71 | |
72 | stream_create(&input_stream,ci); | ||
73 | |||
74 | /* Read from ci->id3->offset before calling qtmovie_read. */ | ||
75 | samplesdone = (uint32_t)(((uint64_t)(ci->id3->offset) * ci->id3->frequency) / | ||
76 | (ci->id3->bitrate*128)); | ||
77 | |||
78 | /* if qtmovie_read returns successfully, the stream is up to | ||
79 | * the movie data, which can be used directly by the decoder */ | ||
80 | if (!qtmovie_read(&input_stream, &demux_res)) { | ||
81 | LOGF("ALAC: Error initialising file\n"); | ||
82 | return CODEC_ERROR; | ||
104 | } | 83 | } |
105 | 84 | ||
106 | /* Deal with any pending seek requests */ | 85 | /* initialise the sound converter */ |
107 | if (ci->seek_time) { | 86 | create_alac(demux_res.sound_sample_size, demux_res.num_channels,&alac); |
108 | if (m4a_seek(&demux_res, &input_stream, | 87 | alac_set_info(&alac, demux_res.codecdata); |
109 | ((ci->seek_time-1)/10) * (ci->id3->frequency/100), | 88 | |
110 | &samplesdone, (int *)&i)) { | 89 | /* Set i for first frame, seek to desired sample position for resuming. */ |
111 | elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); | 90 | i=0; |
112 | ci->set_elapsed(elapsedtime); | 91 | if (samplesdone > 0) { |
113 | } | 92 | if (m4a_seek(&demux_res, &input_stream, samplesdone, |
114 | ci->seek_complete(); | 93 | &samplesdone, (int*) &i)) { |
94 | elapsedtime = (samplesdone * 10) / (ci->id3->frequency / 100); | ||
95 | ci->set_elapsed(elapsedtime); | ||
96 | } else { | ||
97 | samplesdone = 0; | ||
98 | } | ||
115 | } | 99 | } |
116 | 100 | ||
117 | /* Request the required number of bytes from the input buffer */ | 101 | /* The main decoding loop */ |
118 | buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE); | 102 | while (i < demux_res.num_sample_byte_sizes) { |
103 | enum codec_command_action action = ci->get_command(¶m); | ||
104 | |||
105 | if (action == CODEC_ACTION_HALT) | ||
106 | break; | ||
119 | 107 | ||
120 | /* Decode one block - returned samples will be host-endian */ | 108 | /* Request the required number of bytes from the input buffer */ |
121 | ci->yield(); | 109 | buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE); |
122 | samplesdecoded=alac_decode_frame(&alac, buffer, outputbuffer, ci->yield); | ||
123 | 110 | ||
124 | /* Advance codec buffer by amount of consumed bytes */ | 111 | /* Deal with any pending seek requests */ |
125 | ci->advance_buffer(alac.bytes_consumed); | 112 | if (action == CODEC_ACTION_SEEK_TIME) { |
113 | if (m4a_seek(&demux_res, &input_stream, | ||
114 | (param/10) * (ci->id3->frequency/100), | ||
115 | &samplesdone, (int *)&i)) { | ||
116 | elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); | ||
117 | } | ||
118 | ci->set_elapsed(elapsedtime); | ||
119 | ci->seek_complete(); | ||
120 | } | ||
126 | 121 | ||
127 | /* Output the audio */ | 122 | /* Request the required number of bytes from the input buffer */ |
128 | ci->yield(); | 123 | buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE); |
129 | ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded); | ||
130 | 124 | ||
131 | /* Update the elapsed-time indicator */ | 125 | /* Decode one block - returned samples will be host-endian */ |
132 | samplesdone+=samplesdecoded; | 126 | samplesdecoded=alac_decode_frame(&alac, buffer, outputbuffer, ci->yield); |
133 | elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); | 127 | ci->yield(); |
134 | ci->set_elapsed(elapsedtime); | ||
135 | 128 | ||
136 | i++; | 129 | /* Advance codec buffer by amount of consumed bytes */ |
137 | } | 130 | ci->advance_buffer(alac.bytes_consumed); |
138 | 131 | ||
139 | done: | 132 | /* Output the audio */ |
140 | LOGF("ALAC: Decoded %lu samples\n",(unsigned long)samplesdone); | 133 | ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded); |
141 | 134 | ||
142 | if (ci->request_next_track()) | 135 | /* Update the elapsed-time indicator */ |
143 | goto next_track; | 136 | samplesdone+=samplesdecoded; |
137 | elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); | ||
138 | ci->set_elapsed(elapsedtime); | ||
139 | |||
140 | i++; | ||
141 | } | ||
144 | 142 | ||
145 | exit: | 143 | LOGF("ALAC: Decoded %lu samples\n",(unsigned long)samplesdone); |
146 | return retval; | 144 | return CODEC_OK; |
147 | } | 145 | } |