annotate libmpcodecs/ad_speex.c @ 22949:6613c5397aba

Remove the .norecurse hack. It bloats the Makefile, adds maintenance burden, likely has no users and most of all does not work correctly anyway.
author diego
date Wed, 11 Apr 2007 07:16:04 +0000
parents a95ed9a69caf
children bbb6ebec87a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
1 /**
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
2 * Speex decoder by Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>
20962
a95ed9a69caf Put files fully owned by my under GPL v2 "or later"
reimar
parents: 18879
diff changeset
3 * License: GPL v2 or later
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
4 * This code may be be relicensed under the terms of the GNU LGPL when it
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
5 * becomes part of the FFmpeg project (ffmpeg.org)
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
6 */
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
7 #include "config.h"
18157
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
8 #include <stdlib.h>
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
9 #include <speex/speex.h>
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
10 #include <speex/speex_stereo.h>
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
11 #include <speex/speex_header.h>
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
12 #include "ad_internal.h"
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
13
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
14 static ad_info_t info = {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
15 "Speex audio decoder",
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
16 "speex",
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
17 "Reimar Döffinger",
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
18 "",
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
19 ""
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
20 };
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
21
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
22 LIBAD_EXTERN(speex)
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
23
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
24 typedef struct {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
25 SpeexBits bits;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
26 void *dec_context;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
27 SpeexStereoState stereo;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
28 SpeexHeader *hdr;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
29 } context_t;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
30
18157
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
31 #define MAX_FRAMES_PER_PACKET 100
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
32
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
33 static int preinit(sh_audio_t *sh) {
18157
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
34 sh->audio_out_minsize = 2 * 320 * MAX_FRAMES_PER_PACKET * 2 * sizeof(short);
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
35 return 1;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
36 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
37
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
38 static int init(sh_audio_t *sh) {
18879
cc65a585fdcc rm unnecesary casts from void* - part 3
reynaldo
parents: 18157
diff changeset
39 context_t *ctx = calloc(1, sizeof(context_t));
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
40 const SpeexMode *spx_mode;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
41 const SpeexStereoState st_st = SPEEX_STEREO_STATE_INIT; // hack
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
42 if (!sh->wf || sh->wf->cbSize < 80) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
43 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n");
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
44 return 0;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
45 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
46 ctx->hdr = speex_packet_to_header((char *)&sh->wf[1], sh->wf->cbSize);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
47 if (ctx->hdr->nb_channels != 1 && ctx->hdr->nb_channels != 2) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
48 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of channels (%i), "
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
49 "assuming mono\n", ctx->hdr->nb_channels);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
50 ctx->hdr->nb_channels = 1;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
51 }
18157
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
52 if (ctx->hdr->frames_per_packet > MAX_FRAMES_PER_PACKET) {
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
53 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Invalid number of frames per packet (%i), "
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
54 "assuming 1\n", ctx->hdr->frames_per_packet);
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
55 ctx->hdr->frames_per_packet = 1;
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
56 }
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
57 switch (ctx->hdr->mode) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
58 case 0:
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
59 spx_mode = &speex_nb_mode; break;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
60 case 1:
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
61 spx_mode = &speex_wb_mode; break;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
62 case 2:
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
63 spx_mode = &speex_uwb_mode; break;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
64 default:
18157
2c7219c38e56 bug fixes: left-over mode variable used uninitialized,
reimar
parents: 17429
diff changeset
65 mp_msg(MSGT_DECAUDIO, MSGL_WARN, "Unknown speex mode (%i)\n", ctx->hdr->mode);
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
66 spx_mode = &speex_nb_mode;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
67 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
68 ctx->dec_context = speex_decoder_init(spx_mode);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
69 speex_bits_init(&ctx->bits);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
70 memcpy(&ctx->stereo, &st_st, sizeof(ctx->stereo)); // hack part 2
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
71 sh->channels = ctx->hdr->nb_channels;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
72 sh->samplerate = ctx->hdr->rate;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
73 sh->samplesize = 2;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
74 sh->sample_format = AF_FORMAT_S16_NE;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
75 sh->context = ctx;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
76 return 1;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
77 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
78
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
79 static void uninit(sh_audio_t *sh) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
80 context_t *ctx = sh->context;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
81 if (ctx) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
82 speex_bits_destroy(&ctx->bits);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
83 speex_decoder_destroy(ctx->dec_context);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
84 if (ctx->hdr)
17429
7dac2afa70aa Use free instead of speex_free - since speex_free does not appear in the
reimar
parents: 16916
diff changeset
85 free(ctx->hdr);
16916
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
86 free(ctx);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
87 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
88 ctx = NULL;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
89 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
90
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
91 static int decode_audio(sh_audio_t *sh, unsigned char *buf,
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
92 int minlen, int maxlen) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
93 context_t *ctx = sh->context;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
94 int len, framelen, framesamples;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
95 char *packet;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
96 int i, err;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
97 speex_decoder_ctl(ctx->dec_context, SPEEX_GET_FRAME_SIZE, &framesamples);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
98 framelen = framesamples * ctx->hdr->nb_channels * sizeof(short);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
99 if (maxlen < ctx->hdr->frames_per_packet * framelen) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
100 mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n");
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
101 return -1;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
102 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
103 len = ds_get_packet(sh->ds, (unsigned char **)&packet);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
104 if (len <= 0) return -1;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
105 speex_bits_read_from(&ctx->bits, packet, len);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
106 i = ctx->hdr->frames_per_packet;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
107 do {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
108 err = speex_decode_int(ctx->dec_context, &ctx->bits, (short *)buf);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
109 if (err == -2)
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
110 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error decoding file.\n");
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
111 if (ctx->hdr->nb_channels == 2)
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
112 speex_decode_stereo_int((short *)buf, framesamples, &ctx->stereo);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
113 buf = &buf[framelen];
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
114 } while (--i > 0);
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
115 return ctx->hdr->frames_per_packet * framelen;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
116 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
117
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
118 static int control(sh_audio_t *sh, int cmd, void *arg, ...) {
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
119 return CONTROL_UNKNOWN;
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
120 }
56f3945e2a61 Speex audio decoding
reimar
parents:
diff changeset
121