You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.9KB

  1. /*
  2. * Discworld II BMV audio decoder
  3. * Copyright (c) 2011 Konstantin Shishkov
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "libavutil/channel_layout.h"
  22. #include "libavutil/common.h"
  23. #include "avcodec.h"
  24. #include "internal.h"
  25. static const int bmv_aud_mults[16] = {
  26. 16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32
  27. };
  28. static av_cold int bmv_aud_decode_init(AVCodecContext *avctx)
  29. {
  30. avctx->channels = 2;
  31. avctx->channel_layout = AV_CH_LAYOUT_STEREO;
  32. avctx->sample_fmt = AV_SAMPLE_FMT_S16;
  33. return 0;
  34. }
  35. static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
  36. int *got_frame_ptr, AVPacket *avpkt)
  37. {
  38. AVFrame *frame = data;
  39. const uint8_t *buf = avpkt->data;
  40. int buf_size = avpkt->size;
  41. int blocks = 0, total_blocks, i;
  42. int ret;
  43. int16_t *output_samples;
  44. int scale[2];
  45. total_blocks = *buf++;
  46. if (buf_size < total_blocks * 65 + 1) {
  47. av_log(avctx, AV_LOG_ERROR, "expected %d bytes, got %d\n",
  48. total_blocks * 65 + 1, buf_size);
  49. return AVERROR_INVALIDDATA;
  50. }
  51. /* get output buffer */
  52. frame->nb_samples = total_blocks * 32;
  53. if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
  54. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  55. return ret;
  56. }
  57. output_samples = (int16_t *)frame->data[0];
  58. for (blocks = 0; blocks < total_blocks; blocks++) {
  59. uint8_t code = *buf++;
  60. code = (code >> 1) | (code << 7);
  61. scale[0] = bmv_aud_mults[code & 0xF];
  62. scale[1] = bmv_aud_mults[code >> 4];
  63. for (i = 0; i < 32; i++) {
  64. *output_samples++ = av_clip_int16((scale[0] * (int8_t)*buf++) >> 5);
  65. *output_samples++ = av_clip_int16((scale[1] * (int8_t)*buf++) >> 5);
  66. }
  67. }
  68. *got_frame_ptr = 1;
  69. return buf_size;
  70. }
  71. AVCodec ff_bmv_audio_decoder = {
  72. .name = "bmv_audio",
  73. .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"),
  74. .type = AVMEDIA_TYPE_AUDIO,
  75. .id = AV_CODEC_ID_BMV_AUDIO,
  76. .init = bmv_aud_decode_init,
  77. .decode = bmv_aud_decode_frame,
  78. .capabilities = AV_CODEC_CAP_DR1,
  79. };