mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-09 23:53:28 -04:00
wma: decode every codec packet in an ASF payload
A payload normally holds one codec packet of blockalign bytes, but
some files put several in each. Only the first was decoded, so such
a file played one packet in every 8 or 15, as a few seconds of
broken sound, and then ended.
Step through the payload in blockalign sized packets.
Checked with perfsim (Sansa e200v1 build) against ffmpeg's decode:
doors-test.wma (WMA v2, 11 kHz mono), 15 packets a payload:
80896 of 1205760 samples before, all of them after, 86 dB SNR
test.wma (WMA v1, 44.1 kHz stereo), 8 packets a payload:
1294336 of 10346496 samples before, all after, 114 dB SNR
The output of 26 other WMA files is byte-identical before and after.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6ffbee954b
commit
fb2ee6c08f
1 changed files with 31 additions and 18 deletions
|
|
@ -178,29 +178,42 @@ new_packet:
|
|||
goto new_packet;
|
||||
}
|
||||
} else if (res > 0) {
|
||||
wma_decode_superframe_init(&wmadec, audiobuf, audiobufsize);
|
||||
/* A payload usually holds one codec packet (a superframe) of
|
||||
* blockalign bytes, but it can hold several. */
|
||||
int packetsize = audiobufsize;
|
||||
int offset;
|
||||
|
||||
for (i=0; i < wmadec.nb_frames; i++)
|
||||
if (wfx.blockalign > 0 && audiobufsize % wfx.blockalign == 0)
|
||||
packetsize = wfx.blockalign;
|
||||
|
||||
for (offset = 0; offset < audiobufsize; offset += packetsize)
|
||||
{
|
||||
wmares = wma_decode_superframe_frame(&wmadec,
|
||||
audiobuf, audiobufsize);
|
||||
const uint8_t *packet = audiobuf + offset;
|
||||
|
||||
ci->yield ();
|
||||
wma_decode_superframe_init(&wmadec, packet, packetsize);
|
||||
|
||||
if (wmares < 0) {
|
||||
/* Do the above, but for errors in decode. */
|
||||
errcount++;
|
||||
DEBUGF("WMA decode error %d, errcount %d\n",wmares, errcount);
|
||||
if (errcount > 5) {
|
||||
return CODEC_ERROR;
|
||||
} else {
|
||||
ci->advance_buffer(packetlength);
|
||||
goto new_packet;
|
||||
for (i=0; i < wmadec.nb_frames; i++)
|
||||
{
|
||||
wmares = wma_decode_superframe_frame(&wmadec,
|
||||
packet, packetsize);
|
||||
|
||||
ci->yield ();
|
||||
|
||||
if (wmares < 0) {
|
||||
/* Do the above, but for errors in decode. */
|
||||
errcount++;
|
||||
DEBUGF("WMA decode error %d, errcount %d\n",wmares, errcount);
|
||||
if (errcount > 5) {
|
||||
return CODEC_ERROR;
|
||||
} else {
|
||||
ci->advance_buffer(packetlength);
|
||||
goto new_packet;
|
||||
}
|
||||
} else if (wmares > 0) {
|
||||
ci->pcmbuf_insert((*wmadec.frame_out)[0], (*wmadec.frame_out)[1], wmares);
|
||||
elapsedtime += (wmares*10)/(wfx.rate/100);
|
||||
ci->set_elapsed(elapsedtime);
|
||||
}
|
||||
} else if (wmares > 0) {
|
||||
ci->pcmbuf_insert((*wmadec.frame_out)[0], (*wmadec.frame_out)[1], wmares);
|
||||
elapsedtime += (wmares*10)/(wfx.rate/100);
|
||||
ci->set_elapsed(elapsedtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue