xref: /btstack/test/lc3/lc3_decoder.c (revision 42c5c5581b83a00e2c1de42e4fe687a30b9efa5a)
1 /*
2  * Copyright (C) 2022 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 // *****************************************************************************
39 //
40 // LC3 decoder Google
41 //
42 // *****************************************************************************
43 
44 #include <stdint.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <fcntl.h>
49 #include <unistd.h>
50 
51 #include "wav_util.h"
52 #include "btstack_util.h"
53 #include "btstack_debug.h"
54 
55 #include "btstack_lc3.h"
56 #include "btstack_lc3_google.h"
57 
58 #define MAX_NUM_CHANNELS 2
59 #define MAX_SAMPLES_PER_FRAME 480
60 
61 static uint8_t  read_buffer[200];
62 
63 static uint32_t frame_count = 0;
64 
65 static void show_usage(const char * path){
66     printf("\n\nUsage: %s input_file.lc3 output_file.wav\n\n", path);
67 }
68 
69 static ssize_t __read(int fd, void *buf, size_t count){
70     ssize_t len, pos = 0;
71     while (count > 0) {
72         len = read(fd, (int8_t * )buf + pos, count);
73         if (len <= 0)
74             return pos;
75 
76         count -= len;
77         pos   += len;
78     }
79     return pos;
80 }
81 
82 int main (int argc, const char * argv[]){
83     if (argc < 3){
84         show_usage(argv[0]);
85         return -1;
86     }
87 
88     const char * lc3_filename = argv[1];
89     const char * wav_filename = argv[2];
90 
91     int fd = open(lc3_filename, O_RDONLY);
92     if (fd < 0) {
93         printf("Can't open file %s", lc3_filename);
94         return -1;
95     }
96 
97     // read & parse header
98     uint16_t min_header_size = 18;
99     int bytes_read = __read(fd, read_buffer, min_header_size);
100     if (bytes_read != min_header_size) return -10;
101     uint16_t file_id = little_endian_read_16(read_buffer, 0);
102     if (file_id != 0xcc1c) return -10;
103     uint16_t header_size = little_endian_read_16(read_buffer, 2);
104     if (header_size > 100) return -10;
105     uint32_t sample_rate_hz = little_endian_read_16(read_buffer, 4) * 100;
106     uint32_t bitrate        = little_endian_read_16(read_buffer, 6) * 100;
107     uint8_t  num_channels   = little_endian_read_16(read_buffer, 8);
108     uint32_t frame_us       = little_endian_read_16(read_buffer, 10) * 10;
109     // offset 12: epmode
110     // offset 14: signal_len
111     // skip addittional fields
112     if (header_size > min_header_size){
113         __read(fd, read_buffer, header_size - min_header_size);
114     }
115 
116     if (num_channels > MAX_NUM_CHANNELS) {
117         printf("Too much channels: %u\n", num_channels);
118         return -10;
119     }
120 
121     // pick frame duration
122     btstack_lc3_frame_duration_t duration2;
123     switch (frame_us) {
124         case 7500:
125             duration2 = BTSTACK_LC3_FRAME_DURATION_7500US;
126             break;
127         case 10000:
128             duration2 = BTSTACK_LC3_FRAME_DURATION_10000US;
129             break;
130         default:
131             return -10;
132     }
133 
134     uint16_t number_samples_per_frame = btstack_lc3_samples_per_frame(sample_rate_hz, duration2);
135     if (number_samples_per_frame > MAX_SAMPLES_PER_FRAME) {
136         printf("number samples per frame %u too large\n", number_samples_per_frame);
137         return -10;
138     }
139 
140     // init decoder
141     uint8_t channel;
142     btstack_lc3_decoder_google_t decoder_contexts[MAX_NUM_CHANNELS];
143     const btstack_lc3_decoder_t * lc3_decoder;
144     for (channel = 0 ; channel < num_channels ; channel++){
145         btstack_lc3_decoder_google_t * decoder_context = &decoder_contexts[channel];
146         lc3_decoder = btstack_lc3_decoder_google_init_instance(decoder_context);
147         lc3_decoder->configure(decoder_context, sample_rate_hz, duration2, number_samples_per_frame);
148     }
149 
150     // calc num octets from bitrate
151     uint32_t bitrate_per_channel = bitrate / num_channels;
152     uint16_t bytes_per_frame = 0;
153     if ((sample_rate_hz == 8000) && (bitrate_per_channel == 27700)){
154         // fix bitrate for 8_1
155         bitrate_per_channel = 27734;
156         bitrate = bitrate_per_channel * num_channels;
157         bytes_per_frame = 26;
158     } else if (sample_rate_hz == 44100){
159         // fix bitrate for 441_1 and 441_2
160         if ((frame_us == 7500) && (bitrate_per_channel == 95000)) {
161             bitrate = 95060;
162         }
163         if ((frame_us == 10000) && (bitrate_per_channel == 95500)) {
164             bytes_per_frame = 130;
165         }
166     } else {
167         bytes_per_frame = bitrate_per_channel / (10000 / (frame_us/100)) / 8;
168     }
169 
170     // print format
171     printf("LC3 file:            %s\n", lc3_filename);
172     printf("WAC file:            %s\n", wav_filename);
173     printf("Samplerate:          %u Hz\n", sample_rate_hz);
174     printf("Channels:            %u\n", num_channels);
175     printf("Bitrate              %u bps\n", bitrate);
176     uint16_t frame_ms = frame_us / 1000;
177     printf("Frame:               %u.%u ms\n", frame_ms, frame_us - (frame_ms * 1000));
178 
179     printf("Bytes per frame:     %u\n", bytes_per_frame);
180     printf("Samples per frame:   %u\n", number_samples_per_frame);
181 
182     // open wav writer
183     wav_writer_open(wav_filename, num_channels, sample_rate_hz);
184 
185     while (true){
186 
187         bool done = false;
188         int16_t pcm[MAX_NUM_CHANNELS * MAX_SAMPLES_PER_FRAME];
189 
190         // get len of lc3 frames
191         int bytes_read = __read(fd, read_buffer, 2);
192         if (2 != bytes_read) {
193             done = true;
194             break;
195         }
196         uint16_t total_frame_len = little_endian_read_16(read_buffer, 0);
197         if (total_frame_len != (bytes_per_frame * num_channels)){
198             done = true;
199             break;
200         }
201 
202         for (channel = 0; channel < num_channels; channel++){
203 
204             // get next lc3 frame (one channel)
205             int bytes_read = __read(fd, read_buffer, bytes_per_frame);
206             if (bytes_per_frame != bytes_read) {
207                 done = true;
208                 break;
209             }
210 
211             // process frame
212             uint8_t tmp_BEC_detect;
213             uint8_t BFI = 0;
214 
215             uint8_t status = lc3_decoder->decode_signed_16(&decoder_contexts[channel], read_buffer, BFI, &pcm[channel], num_channels, &tmp_BEC_detect);
216             if (status != ERROR_CODE_SUCCESS){
217                 printf("Error %u\n", status);
218                 done = true;
219                 break;
220             }
221         }
222 
223         if (done) break;
224 
225         wav_writer_write_int16(num_channels * number_samples_per_frame, pcm);
226 
227         frame_count++;
228     }
229 
230     wav_writer_close();
231     close(fd);
232 
233     printf("Wrote %d frames / %u samples\n\n", frame_count, frame_count * number_samples_per_frame);
234 }
235