| 94 | } |
| 95 | |
| 96 | fl::vector<audio::Sample> Mp3HelixDecoder::decodeToAudioSamples(const fl::u8* data, fl::size len) { |
| 97 | fl::vector<audio::Sample> samples; |
| 98 | |
| 99 | decode(data, len, [&](const Mp3Frame& frame) { |
| 100 | // Convert stereo to mono by averaging channels |
| 101 | if (frame.channels == 2) { |
| 102 | fl::vector<fl::i16> mono_pcm; |
| 103 | mono_pcm.reserve(frame.samples); |
| 104 | |
| 105 | for (int i = 0; i < frame.samples; i++) { |
| 106 | fl::i32 left = frame.pcm[i * 2]; |
| 107 | fl::i32 right = frame.pcm[i * 2 + 1]; |
| 108 | fl::i32 avg = (left + right) / 2; |
| 109 | mono_pcm.push_back(static_cast<fl::i16>(avg)); |
| 110 | } |
| 111 | |
| 112 | audio::Sample sample(mono_pcm); |
| 113 | samples.push_back(sample); |
| 114 | } else { |
| 115 | // Mono audio - use directly |
| 116 | audio::Sample sample(fl::span<const fl::i16>(frame.pcm, frame.samples)); |
| 117 | samples.push_back(sample); |
| 118 | } |
| 119 | }); |
| 120 | |
| 121 | return samples; |
| 122 | } |
| 123 | |
| 124 | // Mp3StreamDecoderImpl - internal implementation of streaming MP3 decoder |
| 125 | class Mp3StreamDecoderImpl { |