History

avcodec/adpcm: Mono ADPCM for EA WVE Files

aaron committed 2 years ago

Commit f44353c1 parent 0e321921 file · +32 −12Browse files

Unified · Split

libavcodec/adpcm.c+32−12
@@ -262,7 +262,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) · 261 unmodified lines
262 break;262 break;
263 case AV_CODEC_ID_ADPCM_DTK:263 case AV_CODEC_ID_ADPCM_DTK:
264 case AV_CODEC_ID_ADPCM_EA:264 case AV_CODEC_ID_ADPCM_EA:
265 min_channels = 2;265 min_channels = 1;
266 break;266 break;
267 case AV_CODEC_ID_ADPCM_AFC:267 case AV_CODEC_ID_ADPCM_AFC:
268 case AV_CODEC_ID_ADPCM_EA_R1:268 case AV_CODEC_ID_ADPCM_EA_R1:
@@ -914,10 +914,12 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, · 645 unmodified lines
914 bytestream2_seek(gb, -8, SEEK_CUR);914 bytestream2_seek(gb, -8, SEEK_CUR);
915 break;915 break;
916 case AV_CODEC_ID_ADPCM_EA:916 case AV_CODEC_ID_ADPCM_EA:
917 /* Stereo is 30 bytes per block */
918 /* Mono is 15 bytes per block */
917 has_coded_samples = 1;919 has_coded_samples = 1;
918 *coded_samples = bytestream2_get_le32(gb);920 *coded_samples = bytestream2_get_le32(gb);
919 *coded_samples -= *coded_samples % 28;921 *coded_samples -= *coded_samples % 28;
920 nb_samples = (buf_size - 12) / 30 * 28;922 nb_samples = (buf_size - 12) / (ch == 2 ? 30 : 15) * 28;
921 break;923 break;
922 case AV_CODEC_ID_ADPCM_IMA_EA_EACS:924 case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
923 has_coded_samples = 1;925 has_coded_samples = 1;
@@ -1652,10 +1654,10 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, · 728 unmodified lines
1652 int coeff1l, coeff2l, coeff1r, coeff2r;1654 int coeff1l, coeff2l, coeff1r, coeff2r;
1653 int shift_left, shift_right;1655 int shift_left, shift_right;
1654 1656
1655 /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,1657 /* Each EA ADPCM frame has a 12-byte header followed by 30-byte (stereo) or 15-byte (mono) pieces,
1656 each coding 28 stereo samples. */1658 each coding 28 stereo/mono samples. */
1657 1659
1658 if (channels != 2)1660 if (channels != 2 && channels != 1)
1659 return AVERROR_INVALIDDATA;1661 return AVERROR_INVALIDDATA;
1660 1662
1661 current_left_sample = sign_extend(bytestream2_get_le16u(&gb), 16);1663 current_left_sample = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1670,11 +1672,16 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, · 8 unmodified lines
1670 coeff1r = ea_adpcm_table[ byte & 0x0F];1672 coeff1r = ea_adpcm_table[ byte & 0x0F];
1671 coeff2r = ea_adpcm_table[(byte & 0x0F) + 4];1673 coeff2r = ea_adpcm_table[(byte & 0x0F) + 4];
1672 1674
1673 byte = bytestream2_get_byteu(&gb);1675 if (channels == 2){
1674 shift_left = 20 - (byte >> 4);1676 byte = bytestream2_get_byteu(&gb);
1675 shift_right = 20 - (byte & 0x0F);1677 shift_left = 20 - (byte >> 4);
1678 shift_right = 20 - (byte & 0x0F);
1679 } else{
1680 /* Mono packs the shift into the coefficient byte's lower nibble instead */
1681 shift_left = 20 - (byte & 0x0F);
1682 }
1676 1683
1677 for (int count2 = 0; count2 < 28; count2++) {1684 for (int count2 = 0; count2 < (channels == 2 ? 28 : 14); count2++) {
1678 byte = bytestream2_get_byteu(&gb);1685 byte = bytestream2_get_byteu(&gb);
1679 next_left_sample = sign_extend(byte >> 4, 4) * (1 << shift_left);1686 next_left_sample = sign_extend(byte >> 4, 4) * (1 << shift_left);
1680 next_right_sample = sign_extend(byte, 4) * (1 << shift_right);1687 next_right_sample = sign_extend(byte, 4) * (1 << shift_right);
@@ -1691,11 +1698,24 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, · 10 unmodified lines
1691 previous_right_sample = current_right_sample;1698 previous_right_sample = current_right_sample;
1692 current_right_sample = av_clip_int16(next_right_sample);1699 current_right_sample = av_clip_int16(next_right_sample);
1693 *samples++ = current_left_sample;1700 *samples++ = current_left_sample;
1694 *samples++ = current_right_sample;1701
1702 if (channels == 2){
1703 *samples++ = current_right_sample;
1704 } else {
1705 next_left_sample = sign_extend(byte, 4) * (1 << shift_left);
1706
1707 next_left_sample = (next_left_sample +
1708 (current_left_sample * coeff1l) +
1709 (previous_left_sample * coeff2l) + 0x80) >> 8;
1710
1711 previous_left_sample = current_left_sample;
1712 current_left_sample = av_clip_int16(next_left_sample);
1713
1714 *samples++ = current_left_sample;
1715 }
1695 }1716 }
1696 }1717 }
1697 1718 bytestream2_skip(&gb, channels == 2 ? 2 : 3); // Skip terminating NULs
1698 bytestream2_skip(&gb, 2); // Skip terminating 0x0000
1699 ) /* End of CASE */1719 ) /* End of CASE */
1700 CASE(ADPCM_EA_MAXIS_XA,1720 CASE(ADPCM_EA_MAXIS_XA,
1701 int coeff[2][2], shift[2];1721 int coeff[2][2], shift[2];

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t