1159b3361Sopenharmony_ci/*
2159b3361Sopenharmony_ci * interface.c
3159b3361Sopenharmony_ci *
4159b3361Sopenharmony_ci * Copyright (C) 1999-2012 The L.A.M.E. project
5159b3361Sopenharmony_ci *
6159b3361Sopenharmony_ci * Initially written by Michael Hipp, see also AUTHORS and README.
7159b3361Sopenharmony_ci *
8159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or
9159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public
10159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either
11159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version.
12159b3361Sopenharmony_ci *
13159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful,
14159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16159b3361Sopenharmony_ci * Library General Public License for more details.
17159b3361Sopenharmony_ci *
18159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public
19159b3361Sopenharmony_ci * License along with this library; if not, write to the
20159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA.
22159b3361Sopenharmony_ci */
23159b3361Sopenharmony_ci/* $Id$ */
24159b3361Sopenharmony_ci
25159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H
26159b3361Sopenharmony_ci# include <config.h>
27159b3361Sopenharmony_ci#endif
28159b3361Sopenharmony_ci
29159b3361Sopenharmony_ci#include <stdlib.h>
30159b3361Sopenharmony_ci#include <stdio.h>
31159b3361Sopenharmony_ci
32159b3361Sopenharmony_ci#include "common.h"
33159b3361Sopenharmony_ci#include "interface.h"
34159b3361Sopenharmony_ci#include "tabinit.h"
35159b3361Sopenharmony_ci#include "layer3.h"
36159b3361Sopenharmony_ci#include "lame.h"
37159b3361Sopenharmony_ci#include "machine.h"
38159b3361Sopenharmony_ci#include "VbrTag.h"
39159b3361Sopenharmony_ci#include "decode_i386.h"
40159b3361Sopenharmony_ci
41159b3361Sopenharmony_ci#include "layer1.h"
42159b3361Sopenharmony_ci#include "layer2.h"
43159b3361Sopenharmony_ci
44159b3361Sopenharmony_ci#ifdef WITH_DMALLOC
45159b3361Sopenharmony_ci#include <dmalloc.h>
46159b3361Sopenharmony_ci#endif
47159b3361Sopenharmony_ci
48159b3361Sopenharmony_ciextern void lame_report_def(const char* format, va_list args);
49159b3361Sopenharmony_ci
50159b3361Sopenharmony_ci/* #define HIP_DEBUG */
51159b3361Sopenharmony_ci
52159b3361Sopenharmony_ciint
53159b3361Sopenharmony_ciInitMP3(PMPSTR mp)
54159b3361Sopenharmony_ci{
55159b3361Sopenharmony_ci    hip_init_tables_layer1();
56159b3361Sopenharmony_ci    hip_init_tables_layer2();
57159b3361Sopenharmony_ci    hip_init_tables_layer3();
58159b3361Sopenharmony_ci
59159b3361Sopenharmony_ci    if (mp) {
60159b3361Sopenharmony_ci        memset(mp, 0, sizeof(MPSTR));
61159b3361Sopenharmony_ci
62159b3361Sopenharmony_ci        mp->framesize = 0;
63159b3361Sopenharmony_ci        mp->num_frames = 0;
64159b3361Sopenharmony_ci        mp->enc_delay = -1;
65159b3361Sopenharmony_ci        mp->enc_padding = -1;
66159b3361Sopenharmony_ci        mp->vbr_header = 0;
67159b3361Sopenharmony_ci        mp->header_parsed = 0;
68159b3361Sopenharmony_ci        mp->side_parsed = 0;
69159b3361Sopenharmony_ci        mp->data_parsed = 0;
70159b3361Sopenharmony_ci        mp->free_format = 0;
71159b3361Sopenharmony_ci        mp->old_free_format = 0;
72159b3361Sopenharmony_ci        mp->ssize = 0;
73159b3361Sopenharmony_ci        mp->dsize = 0;
74159b3361Sopenharmony_ci        mp->fsizeold = -1;
75159b3361Sopenharmony_ci        mp->bsize = 0;
76159b3361Sopenharmony_ci        mp->head = mp->tail = NULL;
77159b3361Sopenharmony_ci        mp->fr.single = -1;
78159b3361Sopenharmony_ci        mp->bsnum = 0;
79159b3361Sopenharmony_ci        mp->wordpointer = mp->bsspace[mp->bsnum] + 512;
80159b3361Sopenharmony_ci        mp->bitindex = 0;
81159b3361Sopenharmony_ci        mp->synth_bo = 1;
82159b3361Sopenharmony_ci        mp->sync_bitstream = 1;
83159b3361Sopenharmony_ci
84159b3361Sopenharmony_ci        mp->report_dbg = &lame_report_def;
85159b3361Sopenharmony_ci        mp->report_err = &lame_report_def;
86159b3361Sopenharmony_ci        mp->report_msg = &lame_report_def;
87159b3361Sopenharmony_ci    }
88159b3361Sopenharmony_ci    make_decode_tables(32767);
89159b3361Sopenharmony_ci
90159b3361Sopenharmony_ci    return 1;
91159b3361Sopenharmony_ci}
92159b3361Sopenharmony_ci
93159b3361Sopenharmony_civoid
94159b3361Sopenharmony_ciExitMP3(PMPSTR mp)
95159b3361Sopenharmony_ci{
96159b3361Sopenharmony_ci    if (mp) {
97159b3361Sopenharmony_ci        struct buf *b, *bn;
98159b3361Sopenharmony_ci
99159b3361Sopenharmony_ci        b = mp->tail;
100159b3361Sopenharmony_ci        while (b) {
101159b3361Sopenharmony_ci            free(b->pnt);
102159b3361Sopenharmony_ci            bn = b->next;
103159b3361Sopenharmony_ci            free(b);
104159b3361Sopenharmony_ci            b = bn;
105159b3361Sopenharmony_ci        }
106159b3361Sopenharmony_ci    }
107159b3361Sopenharmony_ci}
108159b3361Sopenharmony_ci
109159b3361Sopenharmony_cistatic struct buf *
110159b3361Sopenharmony_ciaddbuf(PMPSTR mp, unsigned char *buf, int size)
111159b3361Sopenharmony_ci{
112159b3361Sopenharmony_ci    struct buf *nbuf;
113159b3361Sopenharmony_ci
114159b3361Sopenharmony_ci    nbuf = (struct buf *) malloc(sizeof(struct buf));
115159b3361Sopenharmony_ci    if (!nbuf) {
116159b3361Sopenharmony_ci        lame_report_fnc(mp->report_err, "hip: addbuf() Out of memory!\n");
117159b3361Sopenharmony_ci        return NULL;
118159b3361Sopenharmony_ci    }
119159b3361Sopenharmony_ci    nbuf->pnt = (unsigned char *) malloc((size_t) size);
120159b3361Sopenharmony_ci    if (!nbuf->pnt) {
121159b3361Sopenharmony_ci        free(nbuf);
122159b3361Sopenharmony_ci        return NULL;
123159b3361Sopenharmony_ci    }
124159b3361Sopenharmony_ci    nbuf->size = size;
125159b3361Sopenharmony_ci    memcpy(nbuf->pnt, buf, (size_t) size);
126159b3361Sopenharmony_ci    nbuf->next = NULL;
127159b3361Sopenharmony_ci    nbuf->prev = mp->head;
128159b3361Sopenharmony_ci    nbuf->pos = 0;
129159b3361Sopenharmony_ci
130159b3361Sopenharmony_ci    if (!mp->tail) {
131159b3361Sopenharmony_ci        mp->tail = nbuf;
132159b3361Sopenharmony_ci    }
133159b3361Sopenharmony_ci    else {
134159b3361Sopenharmony_ci        mp->head->next = nbuf;
135159b3361Sopenharmony_ci    }
136159b3361Sopenharmony_ci
137159b3361Sopenharmony_ci    mp->head = nbuf;
138159b3361Sopenharmony_ci    mp->bsize += size;
139159b3361Sopenharmony_ci
140159b3361Sopenharmony_ci    return nbuf;
141159b3361Sopenharmony_ci}
142159b3361Sopenharmony_ci
143159b3361Sopenharmony_civoid
144159b3361Sopenharmony_ciremove_buf(PMPSTR mp)
145159b3361Sopenharmony_ci{
146159b3361Sopenharmony_ci    struct buf *buf = mp->tail;
147159b3361Sopenharmony_ci
148159b3361Sopenharmony_ci    mp->tail = buf->next;
149159b3361Sopenharmony_ci    if (mp->tail)
150159b3361Sopenharmony_ci        mp->tail->prev = NULL;
151159b3361Sopenharmony_ci    else {
152159b3361Sopenharmony_ci        mp->tail = mp->head = NULL;
153159b3361Sopenharmony_ci    }
154159b3361Sopenharmony_ci
155159b3361Sopenharmony_ci    free(buf->pnt);
156159b3361Sopenharmony_ci    free(buf);
157159b3361Sopenharmony_ci
158159b3361Sopenharmony_ci}
159159b3361Sopenharmony_ci
160159b3361Sopenharmony_cistatic int
161159b3361Sopenharmony_ciread_buf_byte(PMPSTR mp)
162159b3361Sopenharmony_ci{
163159b3361Sopenharmony_ci    unsigned int b;
164159b3361Sopenharmony_ci
165159b3361Sopenharmony_ci    int     pos;
166159b3361Sopenharmony_ci
167159b3361Sopenharmony_ci
168159b3361Sopenharmony_ci    pos = mp->tail->pos;
169159b3361Sopenharmony_ci    while (pos >= mp->tail->size) {
170159b3361Sopenharmony_ci        remove_buf(mp);
171159b3361Sopenharmony_ci        if (!mp->tail) {
172159b3361Sopenharmony_ci            lame_report_fnc(mp->report_err, "hip: Fatal error! tried to read past mp buffer\n");
173159b3361Sopenharmony_ci            exit(1);
174159b3361Sopenharmony_ci        }
175159b3361Sopenharmony_ci        pos = mp->tail->pos;
176159b3361Sopenharmony_ci    }
177159b3361Sopenharmony_ci
178159b3361Sopenharmony_ci    b = mp->tail->pnt[pos];
179159b3361Sopenharmony_ci    mp->bsize--;
180159b3361Sopenharmony_ci    mp->tail->pos++;
181159b3361Sopenharmony_ci
182159b3361Sopenharmony_ci
183159b3361Sopenharmony_ci    return b;
184159b3361Sopenharmony_ci}
185159b3361Sopenharmony_ci
186159b3361Sopenharmony_ci
187159b3361Sopenharmony_ci
188159b3361Sopenharmony_cistatic void
189159b3361Sopenharmony_ciread_head(PMPSTR mp)
190159b3361Sopenharmony_ci{
191159b3361Sopenharmony_ci    unsigned long head;
192159b3361Sopenharmony_ci
193159b3361Sopenharmony_ci    head = read_buf_byte(mp);
194159b3361Sopenharmony_ci    head <<= 8;
195159b3361Sopenharmony_ci    head |= read_buf_byte(mp);
196159b3361Sopenharmony_ci    head <<= 8;
197159b3361Sopenharmony_ci    head |= read_buf_byte(mp);
198159b3361Sopenharmony_ci    head <<= 8;
199159b3361Sopenharmony_ci    head |= read_buf_byte(mp);
200159b3361Sopenharmony_ci
201159b3361Sopenharmony_ci    mp->header = head;
202159b3361Sopenharmony_ci}
203159b3361Sopenharmony_ci
204159b3361Sopenharmony_ci
205159b3361Sopenharmony_ci
206159b3361Sopenharmony_ci
207159b3361Sopenharmony_cistatic void
208159b3361Sopenharmony_cicopy_mp(PMPSTR mp, int size, unsigned char *ptr)
209159b3361Sopenharmony_ci{
210159b3361Sopenharmony_ci    int     len = 0;
211159b3361Sopenharmony_ci
212159b3361Sopenharmony_ci    while (len < size && mp->tail) {
213159b3361Sopenharmony_ci        int     nlen;
214159b3361Sopenharmony_ci        int     blen = mp->tail->size - mp->tail->pos;
215159b3361Sopenharmony_ci        if ((size - len) <= blen) {
216159b3361Sopenharmony_ci            nlen = size - len;
217159b3361Sopenharmony_ci        }
218159b3361Sopenharmony_ci        else {
219159b3361Sopenharmony_ci            nlen = blen;
220159b3361Sopenharmony_ci        }
221159b3361Sopenharmony_ci        memcpy(ptr + len, mp->tail->pnt + mp->tail->pos, (size_t) nlen);
222159b3361Sopenharmony_ci        len += nlen;
223159b3361Sopenharmony_ci        mp->tail->pos += nlen;
224159b3361Sopenharmony_ci        mp->bsize -= nlen;
225159b3361Sopenharmony_ci        if (mp->tail->pos == mp->tail->size) {
226159b3361Sopenharmony_ci            remove_buf(mp);
227159b3361Sopenharmony_ci        }
228159b3361Sopenharmony_ci    }
229159b3361Sopenharmony_ci}
230159b3361Sopenharmony_ci
231159b3361Sopenharmony_ci/* number of bytes needed by GetVbrTag to parse header */
232159b3361Sopenharmony_ci#define XING_HEADER_SIZE 194
233159b3361Sopenharmony_ci
234159b3361Sopenharmony_ci/*
235159b3361Sopenharmony_citraverse mp data structure without changing it
236159b3361Sopenharmony_ci(just like sync_buffer)
237159b3361Sopenharmony_cipull out Xing bytes
238159b3361Sopenharmony_cicall vbr header check code from LAME
239159b3361Sopenharmony_ciif we find a header, parse it and also compute the VBR header size
240159b3361Sopenharmony_ciif no header, do nothing.
241159b3361Sopenharmony_ci
242159b3361Sopenharmony_cibytes = number of bytes before MPEG header.  skip this many bytes
243159b3361Sopenharmony_cibefore starting to read
244159b3361Sopenharmony_cireturn value: number of bytes in VBR header, including syncword
245159b3361Sopenharmony_ci*/
246159b3361Sopenharmony_cistatic int
247159b3361Sopenharmony_cicheck_vbr_header(PMPSTR mp, int bytes)
248159b3361Sopenharmony_ci{
249159b3361Sopenharmony_ci    int     i, pos;
250159b3361Sopenharmony_ci    struct buf *buf = mp->tail;
251159b3361Sopenharmony_ci    unsigned char xing[XING_HEADER_SIZE];
252159b3361Sopenharmony_ci    VBRTAGDATA pTagData;
253159b3361Sopenharmony_ci
254159b3361Sopenharmony_ci    pos = buf->pos;
255159b3361Sopenharmony_ci    /* skip to valid header */
256159b3361Sopenharmony_ci    for (i = 0; i < bytes; ++i) {
257159b3361Sopenharmony_ci        while (pos >= buf->size) {
258159b3361Sopenharmony_ci            buf = buf->next;
259159b3361Sopenharmony_ci            if (!buf)
260159b3361Sopenharmony_ci                return -1; /* fatal error */
261159b3361Sopenharmony_ci            pos = buf->pos;
262159b3361Sopenharmony_ci        }
263159b3361Sopenharmony_ci        ++pos;
264159b3361Sopenharmony_ci    }
265159b3361Sopenharmony_ci    /* now read header */
266159b3361Sopenharmony_ci    for (i = 0; i < XING_HEADER_SIZE; ++i) {
267159b3361Sopenharmony_ci        while (pos >= buf->size) {
268159b3361Sopenharmony_ci            buf = buf->next;
269159b3361Sopenharmony_ci            if (!buf)
270159b3361Sopenharmony_ci                return -1; /* fatal error */
271159b3361Sopenharmony_ci            pos = buf->pos;
272159b3361Sopenharmony_ci        }
273159b3361Sopenharmony_ci        xing[i] = buf->pnt[pos];
274159b3361Sopenharmony_ci        ++pos;
275159b3361Sopenharmony_ci    }
276159b3361Sopenharmony_ci
277159b3361Sopenharmony_ci    /* check first bytes for Xing header */
278159b3361Sopenharmony_ci    mp->vbr_header = GetVbrTag(&pTagData, xing);
279159b3361Sopenharmony_ci    if (mp->vbr_header) {
280159b3361Sopenharmony_ci        mp->num_frames = pTagData.frames;
281159b3361Sopenharmony_ci        mp->enc_delay = pTagData.enc_delay;
282159b3361Sopenharmony_ci        mp->enc_padding = pTagData.enc_padding;
283159b3361Sopenharmony_ci
284159b3361Sopenharmony_ci        /* lame_report_fnc(mp->report_msg,"hip: delays: %i %i \n",mp->enc_delay,mp->enc_padding); */
285159b3361Sopenharmony_ci        /* lame_report_fnc(mp->report_msg,"hip: Xing VBR header dectected.  MP3 file has %i frames\n", pTagData.frames); */
286159b3361Sopenharmony_ci        if (pTagData.headersize < 1)
287159b3361Sopenharmony_ci            return 1;
288159b3361Sopenharmony_ci        return pTagData.headersize;
289159b3361Sopenharmony_ci    }
290159b3361Sopenharmony_ci    return 0;
291159b3361Sopenharmony_ci}
292159b3361Sopenharmony_ci
293159b3361Sopenharmony_ci
294159b3361Sopenharmony_ci
295159b3361Sopenharmony_ci
296159b3361Sopenharmony_ci
297159b3361Sopenharmony_cistatic int
298159b3361Sopenharmony_cisync_buffer(PMPSTR mp, int free_match)
299159b3361Sopenharmony_ci{
300159b3361Sopenharmony_ci    /* traverse mp structure without modifying pointers, looking
301159b3361Sopenharmony_ci     * for a frame valid header.
302159b3361Sopenharmony_ci     * if free_format, valid header must also have the same
303159b3361Sopenharmony_ci     * samplerate.
304159b3361Sopenharmony_ci     * return number of bytes in mp, before the header
305159b3361Sopenharmony_ci     * return -1 if header is not found
306159b3361Sopenharmony_ci     */
307159b3361Sopenharmony_ci    unsigned int b[4] = { 0, 0, 0, 0 };
308159b3361Sopenharmony_ci    int     i, h, pos;
309159b3361Sopenharmony_ci    struct buf *buf = mp->tail;
310159b3361Sopenharmony_ci    if (!buf)
311159b3361Sopenharmony_ci        return -1;
312159b3361Sopenharmony_ci
313159b3361Sopenharmony_ci    pos = buf->pos;
314159b3361Sopenharmony_ci    for (i = 0; i < mp->bsize; i++) {
315159b3361Sopenharmony_ci        /* get 4 bytes */
316159b3361Sopenharmony_ci
317159b3361Sopenharmony_ci        b[0] = b[1];
318159b3361Sopenharmony_ci        b[1] = b[2];
319159b3361Sopenharmony_ci        b[2] = b[3];
320159b3361Sopenharmony_ci        while (pos >= buf->size) {
321159b3361Sopenharmony_ci            buf = buf->next;
322159b3361Sopenharmony_ci            if (!buf) {
323159b3361Sopenharmony_ci                return -1;
324159b3361Sopenharmony_ci                /* not enough data to read 4 bytes */
325159b3361Sopenharmony_ci            }
326159b3361Sopenharmony_ci            pos = buf->pos;
327159b3361Sopenharmony_ci        }
328159b3361Sopenharmony_ci        b[3] = buf->pnt[pos];
329159b3361Sopenharmony_ci        ++pos;
330159b3361Sopenharmony_ci
331159b3361Sopenharmony_ci        if (i >= 3) {
332159b3361Sopenharmony_ci            struct frame *fr = &mp->fr;
333159b3361Sopenharmony_ci            unsigned long head;
334159b3361Sopenharmony_ci
335159b3361Sopenharmony_ci            head = b[0];
336159b3361Sopenharmony_ci            head <<= 8;
337159b3361Sopenharmony_ci            head |= b[1];
338159b3361Sopenharmony_ci            head <<= 8;
339159b3361Sopenharmony_ci            head |= b[2];
340159b3361Sopenharmony_ci            head <<= 8;
341159b3361Sopenharmony_ci            head |= b[3];
342159b3361Sopenharmony_ci            h = head_check(head, fr->lay);
343159b3361Sopenharmony_ci
344159b3361Sopenharmony_ci            if (h && free_match) {
345159b3361Sopenharmony_ci                /* just to be even more thorough, match the sample rate */
346159b3361Sopenharmony_ci                int     mode, stereo, sampling_frequency, mpeg25, lsf;
347159b3361Sopenharmony_ci
348159b3361Sopenharmony_ci                if (head & (1 << 20)) {
349159b3361Sopenharmony_ci                    lsf = (head & (1 << 19)) ? 0x0 : 0x1;
350159b3361Sopenharmony_ci                    mpeg25 = 0;
351159b3361Sopenharmony_ci                }
352159b3361Sopenharmony_ci                else {
353159b3361Sopenharmony_ci                    lsf = 1;
354159b3361Sopenharmony_ci                    mpeg25 = 1;
355159b3361Sopenharmony_ci                }
356159b3361Sopenharmony_ci
357159b3361Sopenharmony_ci                mode = ((head >> 6) & 0x3);
358159b3361Sopenharmony_ci                stereo = (mode == MPG_MD_MONO) ? 1 : 2;
359159b3361Sopenharmony_ci
360159b3361Sopenharmony_ci                if (mpeg25)
361159b3361Sopenharmony_ci                    sampling_frequency = 6 + ((head >> 10) & 0x3);
362159b3361Sopenharmony_ci                else
363159b3361Sopenharmony_ci                    sampling_frequency = ((head >> 10) & 0x3) + (lsf * 3);
364159b3361Sopenharmony_ci                h = ((stereo == fr->stereo) && (lsf == fr->lsf) && (mpeg25 == fr->mpeg25) &&
365159b3361Sopenharmony_ci                     (sampling_frequency == fr->sampling_frequency));
366159b3361Sopenharmony_ci            }
367159b3361Sopenharmony_ci
368159b3361Sopenharmony_ci            if (h) {
369159b3361Sopenharmony_ci                return i - 3;
370159b3361Sopenharmony_ci            }
371159b3361Sopenharmony_ci        }
372159b3361Sopenharmony_ci    }
373159b3361Sopenharmony_ci    return -1;
374159b3361Sopenharmony_ci}
375159b3361Sopenharmony_ci
376159b3361Sopenharmony_ci
377159b3361Sopenharmony_civoid
378159b3361Sopenharmony_cidecode_reset(PMPSTR mp)
379159b3361Sopenharmony_ci{
380159b3361Sopenharmony_ci#if 0
381159b3361Sopenharmony_ci    remove_buf(mp);
382159b3361Sopenharmony_ci    /* start looking for next frame */
383159b3361Sopenharmony_ci    /* mp->fsizeold = mp->framesize; */
384159b3361Sopenharmony_ci    mp->fsizeold = -1;
385159b3361Sopenharmony_ci    mp->old_free_format = mp->free_format;
386159b3361Sopenharmony_ci    mp->framesize = 0;
387159b3361Sopenharmony_ci    mp->header_parsed = 0;
388159b3361Sopenharmony_ci    mp->side_parsed = 0;
389159b3361Sopenharmony_ci    mp->data_parsed = 0;
390159b3361Sopenharmony_ci    mp->sync_bitstream = 1; /* TODO check if this is right */
391159b3361Sopenharmony_ci#else
392159b3361Sopenharmony_ci    InitMP3(mp);        /* Less error prone to just to reinitialise. */
393159b3361Sopenharmony_ci#endif
394159b3361Sopenharmony_ci}
395159b3361Sopenharmony_ci
396159b3361Sopenharmony_ciint
397159b3361Sopenharmony_ciaudiodata_precedesframes(PMPSTR mp)
398159b3361Sopenharmony_ci{
399159b3361Sopenharmony_ci    if (mp->fr.lay == 3)
400159b3361Sopenharmony_ci        return layer3_audiodata_precedesframes(mp);
401159b3361Sopenharmony_ci    else
402159b3361Sopenharmony_ci        return 0;       /* For Layer 1 & 2 the audio data starts at the frame that describes it, so no audio data precedes. */
403159b3361Sopenharmony_ci}
404159b3361Sopenharmony_ci
405159b3361Sopenharmony_cistatic int
406159b3361Sopenharmony_cidecodeMP3_clipchoice(PMPSTR mp, unsigned char *in, int isize, char *out, int *done,
407159b3361Sopenharmony_ci                     int (*synth_1to1_mono_ptr) (PMPSTR, real *, unsigned char *, int *),
408159b3361Sopenharmony_ci                     int (*synth_1to1_ptr) (PMPSTR, real *, int, unsigned char *, int *))
409159b3361Sopenharmony_ci{
410159b3361Sopenharmony_ci    int     i, iret, bits, bytes;
411159b3361Sopenharmony_ci
412159b3361Sopenharmony_ci    if (in && isize && addbuf(mp, in, isize) == NULL)
413159b3361Sopenharmony_ci        return MP3_ERR;
414159b3361Sopenharmony_ci
415159b3361Sopenharmony_ci    /* First decode header */
416159b3361Sopenharmony_ci    if (!mp->header_parsed) {
417159b3361Sopenharmony_ci
418159b3361Sopenharmony_ci        if (mp->fsizeold == -1 || mp->sync_bitstream) {
419159b3361Sopenharmony_ci            int     vbrbytes;
420159b3361Sopenharmony_ci            mp->sync_bitstream = 0;
421159b3361Sopenharmony_ci
422159b3361Sopenharmony_ci            /* This is the very first call.   sync with anything */
423159b3361Sopenharmony_ci            /* bytes= number of bytes before header */
424159b3361Sopenharmony_ci            bytes = sync_buffer(mp, 0);
425159b3361Sopenharmony_ci
426159b3361Sopenharmony_ci            /* now look for Xing VBR header */
427159b3361Sopenharmony_ci            if (mp->bsize >= bytes + XING_HEADER_SIZE) {
428159b3361Sopenharmony_ci                /* vbrbytes = number of bytes in entire vbr header */
429159b3361Sopenharmony_ci                vbrbytes = check_vbr_header(mp, bytes);
430159b3361Sopenharmony_ci            }
431159b3361Sopenharmony_ci            else {
432159b3361Sopenharmony_ci                /* not enough data to look for Xing header */
433159b3361Sopenharmony_ci#ifdef HIP_DEBUG
434159b3361Sopenharmony_ci                lame_report_fnc(mp->report_dbg, "hip: not enough data to look for Xing header\n");
435159b3361Sopenharmony_ci#endif
436159b3361Sopenharmony_ci                return MP3_NEED_MORE;
437159b3361Sopenharmony_ci            }
438159b3361Sopenharmony_ci
439159b3361Sopenharmony_ci            if (mp->vbr_header) {
440159b3361Sopenharmony_ci                /* do we have enough data to parse entire Xing header? */
441159b3361Sopenharmony_ci                if (bytes + vbrbytes > mp->bsize) {
442159b3361Sopenharmony_ci                    /* lame_report_fnc(mp->report_err,"hip: not enough data to parse entire Xing header\n"); */
443159b3361Sopenharmony_ci                    return MP3_NEED_MORE;
444159b3361Sopenharmony_ci                }
445159b3361Sopenharmony_ci
446159b3361Sopenharmony_ci                /* read in Xing header.  Buffer data in case it
447159b3361Sopenharmony_ci                 * is used by a non zero main_data_begin for the next
448159b3361Sopenharmony_ci                 * frame, but otherwise dont decode Xing header */
449159b3361Sopenharmony_ci#ifdef HIP_DEBUG
450159b3361Sopenharmony_ci                lame_report_fnc(mp->report_dbg, "hip: found xing header, skipping %i bytes\n", vbrbytes + bytes);
451159b3361Sopenharmony_ci#endif
452159b3361Sopenharmony_ci                for (i = 0; i < vbrbytes + bytes; ++i)
453159b3361Sopenharmony_ci                    read_buf_byte(mp);
454159b3361Sopenharmony_ci                /* now we need to find another syncword */
455159b3361Sopenharmony_ci                /* just return and make user send in more data */
456159b3361Sopenharmony_ci
457159b3361Sopenharmony_ci                return MP3_NEED_MORE;
458159b3361Sopenharmony_ci            }
459159b3361Sopenharmony_ci        }
460159b3361Sopenharmony_ci        else {
461159b3361Sopenharmony_ci            /* match channels, samplerate, etc, when syncing */
462159b3361Sopenharmony_ci            bytes = sync_buffer(mp, 1);
463159b3361Sopenharmony_ci        }
464159b3361Sopenharmony_ci
465159b3361Sopenharmony_ci        /* buffer now synchronized */
466159b3361Sopenharmony_ci        if (bytes < 0) {
467159b3361Sopenharmony_ci            /* lame_report_fnc(mp->report_err,"hip: need more bytes %d\n", bytes); */
468159b3361Sopenharmony_ci            return MP3_NEED_MORE;
469159b3361Sopenharmony_ci        }
470159b3361Sopenharmony_ci        if (bytes > 0) {
471159b3361Sopenharmony_ci            /* there were some extra bytes in front of header.
472159b3361Sopenharmony_ci             * bitstream problem, but we are now resynced
473159b3361Sopenharmony_ci             * should try to buffer previous data in case new
474159b3361Sopenharmony_ci             * frame has nonzero main_data_begin, but we need
475159b3361Sopenharmony_ci             * to make sure we do not overflow buffer
476159b3361Sopenharmony_ci             */
477159b3361Sopenharmony_ci            int     size;
478159b3361Sopenharmony_ci            if (mp->fsizeold != -1) {
479159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "hip: bitstream problem, resyncing skipping %d bytes...\n", bytes);
480159b3361Sopenharmony_ci            }
481159b3361Sopenharmony_ci            mp->old_free_format = 0;
482159b3361Sopenharmony_ci#if 1
483159b3361Sopenharmony_ci            /* FIXME: correct ??? */
484159b3361Sopenharmony_ci            mp->sync_bitstream = 1;
485159b3361Sopenharmony_ci#endif
486159b3361Sopenharmony_ci            /* skip some bytes, buffer the rest */
487159b3361Sopenharmony_ci            size = (int) (mp->wordpointer - (mp->bsspace[mp->bsnum] + 512));
488159b3361Sopenharmony_ci
489159b3361Sopenharmony_ci            if (size > MAXFRAMESIZE) {
490159b3361Sopenharmony_ci                /* wordpointer buffer is trashed.  probably cant recover, but try anyway */
491159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "hip: wordpointer trashed.  size=%i (%i)  bytes=%i \n",
492159b3361Sopenharmony_ci                        size, MAXFRAMESIZE, bytes);
493159b3361Sopenharmony_ci                size = 0;
494159b3361Sopenharmony_ci                mp->wordpointer = mp->bsspace[mp->bsnum] + 512;
495159b3361Sopenharmony_ci            }
496159b3361Sopenharmony_ci
497159b3361Sopenharmony_ci            /* buffer contains 'size' data right now
498159b3361Sopenharmony_ci               we want to add 'bytes' worth of data, but do not
499159b3361Sopenharmony_ci               exceed MAXFRAMESIZE, so we through away 'i' bytes */
500159b3361Sopenharmony_ci            i = (size + bytes) - MAXFRAMESIZE;
501159b3361Sopenharmony_ci            for (; i > 0; --i) {
502159b3361Sopenharmony_ci                --bytes;
503159b3361Sopenharmony_ci                read_buf_byte(mp);
504159b3361Sopenharmony_ci            }
505159b3361Sopenharmony_ci
506159b3361Sopenharmony_ci            copy_mp(mp, bytes, mp->wordpointer);
507159b3361Sopenharmony_ci            mp->fsizeold += bytes;
508159b3361Sopenharmony_ci        }
509159b3361Sopenharmony_ci
510159b3361Sopenharmony_ci        read_head(mp);
511159b3361Sopenharmony_ci        if (!decode_header(mp, &mp->fr, mp->header))
512159b3361Sopenharmony_ci            return MP3_ERR;
513159b3361Sopenharmony_ci        mp->header_parsed = 1;
514159b3361Sopenharmony_ci        mp->framesize = mp->fr.framesize;
515159b3361Sopenharmony_ci        mp->free_format = (mp->framesize == 0);
516159b3361Sopenharmony_ci
517159b3361Sopenharmony_ci        if (mp->fr.lsf)
518159b3361Sopenharmony_ci            mp->ssize = (mp->fr.stereo == 1) ? 9 : 17;
519159b3361Sopenharmony_ci        else
520159b3361Sopenharmony_ci            mp->ssize = (mp->fr.stereo == 1) ? 17 : 32;
521159b3361Sopenharmony_ci        if (mp->fr.error_protection)
522159b3361Sopenharmony_ci            mp->ssize += 2;
523159b3361Sopenharmony_ci
524159b3361Sopenharmony_ci        mp->bsnum = 1 - mp->bsnum; /* toggle buffer */
525159b3361Sopenharmony_ci        mp->wordpointer = mp->bsspace[mp->bsnum] + 512;
526159b3361Sopenharmony_ci        mp->bitindex = 0;
527159b3361Sopenharmony_ci
528159b3361Sopenharmony_ci        /* for very first header, never parse rest of data */
529159b3361Sopenharmony_ci        if (mp->fsizeold == -1) {
530159b3361Sopenharmony_ci#ifdef HIP_DEBUG
531159b3361Sopenharmony_ci            lame_report_fnc(mp->report_dbg, "hip: not parsing the rest of the data of the first header\n");
532159b3361Sopenharmony_ci#endif
533159b3361Sopenharmony_ci            return MP3_NEED_MORE;
534159b3361Sopenharmony_ci        }
535159b3361Sopenharmony_ci    }                   /* end of header parsing block */
536159b3361Sopenharmony_ci
537159b3361Sopenharmony_ci    /* now decode side information */
538159b3361Sopenharmony_ci    if (!mp->side_parsed) {
539159b3361Sopenharmony_ci
540159b3361Sopenharmony_ci        /* Layer 3 only */
541159b3361Sopenharmony_ci        if (mp->fr.lay == 3) {
542159b3361Sopenharmony_ci            if (mp->bsize < mp->ssize)
543159b3361Sopenharmony_ci                return MP3_NEED_MORE;
544159b3361Sopenharmony_ci
545159b3361Sopenharmony_ci            copy_mp(mp, mp->ssize, mp->wordpointer);
546159b3361Sopenharmony_ci
547159b3361Sopenharmony_ci            if (mp->fr.error_protection)
548159b3361Sopenharmony_ci                getbits(mp, 16);
549159b3361Sopenharmony_ci            bits = decode_layer3_sideinfo(mp);
550159b3361Sopenharmony_ci            /* bits = actual number of bits needed to parse this frame */
551159b3361Sopenharmony_ci            /* can be negative, if all bits needed are in the reservoir */
552159b3361Sopenharmony_ci            if (bits < 0)
553159b3361Sopenharmony_ci                bits = 0;
554159b3361Sopenharmony_ci
555159b3361Sopenharmony_ci            /* read just as many bytes as necessary before decoding */
556159b3361Sopenharmony_ci            mp->dsize = (bits + 7) / 8;
557159b3361Sopenharmony_ci
558159b3361Sopenharmony_ci            if (!mp->free_format) {
559159b3361Sopenharmony_ci                /* do not read more than framsize data */
560159b3361Sopenharmony_ci                int framesize = mp->fr.framesize - mp->ssize;
561159b3361Sopenharmony_ci                if (mp->dsize > framesize) {
562159b3361Sopenharmony_ci                    lame_report_fnc(mp->report_err,
563159b3361Sopenharmony_ci                            "hip: error audio data exceeds framesize by %d bytes\n",
564159b3361Sopenharmony_ci                            mp->dsize - framesize);
565159b3361Sopenharmony_ci                    mp->dsize = framesize;
566159b3361Sopenharmony_ci                }
567159b3361Sopenharmony_ci            }
568159b3361Sopenharmony_ci#ifdef HIP_DEBUG
569159b3361Sopenharmony_ci            lame_report_fnc(mp->report_dbg,
570159b3361Sopenharmony_ci                    "hip: %d bits needed to parse layer III frame, number of bytes to read before decoding dsize = %d\n",
571159b3361Sopenharmony_ci                    bits, mp->dsize);
572159b3361Sopenharmony_ci#endif
573159b3361Sopenharmony_ci
574159b3361Sopenharmony_ci            /* this will force mpglib to read entire frame before decoding */
575159b3361Sopenharmony_ci            /* mp->dsize= mp->framesize - mp->ssize; */
576159b3361Sopenharmony_ci
577159b3361Sopenharmony_ci        }
578159b3361Sopenharmony_ci        else {
579159b3361Sopenharmony_ci            /* Layers 1 and 2 */
580159b3361Sopenharmony_ci
581159b3361Sopenharmony_ci            /* check if there is enough input data */
582159b3361Sopenharmony_ci            if (mp->fr.framesize > mp->bsize)
583159b3361Sopenharmony_ci                return MP3_NEED_MORE;
584159b3361Sopenharmony_ci
585159b3361Sopenharmony_ci            /* takes care that the right amount of data is copied into wordpointer */
586159b3361Sopenharmony_ci            mp->dsize = mp->fr.framesize;
587159b3361Sopenharmony_ci            mp->ssize = 0;
588159b3361Sopenharmony_ci        }
589159b3361Sopenharmony_ci
590159b3361Sopenharmony_ci        mp->side_parsed = 1;
591159b3361Sopenharmony_ci    }
592159b3361Sopenharmony_ci
593159b3361Sopenharmony_ci    /* now decode main data */
594159b3361Sopenharmony_ci    iret = MP3_NEED_MORE;
595159b3361Sopenharmony_ci    if (!mp->data_parsed) {
596159b3361Sopenharmony_ci        if (mp->dsize > mp->bsize) {
597159b3361Sopenharmony_ci            return MP3_NEED_MORE;
598159b3361Sopenharmony_ci        }
599159b3361Sopenharmony_ci
600159b3361Sopenharmony_ci        copy_mp(mp, mp->dsize, mp->wordpointer);
601159b3361Sopenharmony_ci
602159b3361Sopenharmony_ci        *done = 0;
603159b3361Sopenharmony_ci
604159b3361Sopenharmony_ci        /*do_layer3(&mp->fr,(unsigned char *) out,done); */
605159b3361Sopenharmony_ci        switch (mp->fr.lay) {
606159b3361Sopenharmony_ci        case 1:
607159b3361Sopenharmony_ci            if (mp->fr.error_protection)
608159b3361Sopenharmony_ci                getbits(mp, 16);
609159b3361Sopenharmony_ci
610159b3361Sopenharmony_ci            if (decode_layer1_frame(mp, (unsigned char *) out, done) < 0)
611159b3361Sopenharmony_ci                return MP3_ERR;
612159b3361Sopenharmony_ci            break;
613159b3361Sopenharmony_ci
614159b3361Sopenharmony_ci        case 2:
615159b3361Sopenharmony_ci            if (mp->fr.error_protection)
616159b3361Sopenharmony_ci                getbits(mp, 16);
617159b3361Sopenharmony_ci
618159b3361Sopenharmony_ci            decode_layer2_frame(mp, (unsigned char *) out, done);
619159b3361Sopenharmony_ci            break;
620159b3361Sopenharmony_ci
621159b3361Sopenharmony_ci        case 3:
622159b3361Sopenharmony_ci            decode_layer3_frame(mp, (unsigned char *) out, done, synth_1to1_mono_ptr, synth_1to1_ptr);
623159b3361Sopenharmony_ci            break;
624159b3361Sopenharmony_ci        default:
625159b3361Sopenharmony_ci            lame_report_fnc(mp->report_err, "hip: invalid layer %d\n", mp->fr.lay);
626159b3361Sopenharmony_ci        }
627159b3361Sopenharmony_ci
628159b3361Sopenharmony_ci        mp->wordpointer = mp->bsspace[mp->bsnum] + 512 + mp->ssize + mp->dsize;
629159b3361Sopenharmony_ci
630159b3361Sopenharmony_ci        mp->data_parsed = 1;
631159b3361Sopenharmony_ci        iret = MP3_OK;
632159b3361Sopenharmony_ci    }
633159b3361Sopenharmony_ci
634159b3361Sopenharmony_ci
635159b3361Sopenharmony_ci    /* remaining bits are ancillary data, or reservoir for next frame
636159b3361Sopenharmony_ci     * If free format, scan stream looking for next frame to determine
637159b3361Sopenharmony_ci     * mp->framesize */
638159b3361Sopenharmony_ci    if (mp->free_format) {
639159b3361Sopenharmony_ci        if (mp->old_free_format) {
640159b3361Sopenharmony_ci            /* free format.  bitrate must not vary */
641159b3361Sopenharmony_ci            mp->framesize = mp->fsizeold_nopadding + (mp->fr.padding);
642159b3361Sopenharmony_ci        }
643159b3361Sopenharmony_ci        else {
644159b3361Sopenharmony_ci            bytes = sync_buffer(mp, 1);
645159b3361Sopenharmony_ci            if (bytes < 0)
646159b3361Sopenharmony_ci                return iret;
647159b3361Sopenharmony_ci            mp->framesize = bytes + mp->ssize + mp->dsize;
648159b3361Sopenharmony_ci            mp->fsizeold_nopadding = mp->framesize - mp->fr.padding;
649159b3361Sopenharmony_ci#if 0
650159b3361Sopenharmony_ci               lame_report_fnc(mp->report_dbg,"hip: freeformat bitstream:  estimated bitrate=%ikbs  \n",
651159b3361Sopenharmony_ci               8*(4+mp->framesize)*freqs[mp->fr.sampling_frequency]/
652159b3361Sopenharmony_ci               (1000*576*(2-mp->fr.lsf)));
653159b3361Sopenharmony_ci#endif
654159b3361Sopenharmony_ci        }
655159b3361Sopenharmony_ci    }
656159b3361Sopenharmony_ci
657159b3361Sopenharmony_ci    /* buffer the ancillary data and reservoir for next frame */
658159b3361Sopenharmony_ci    bytes = mp->framesize - (mp->ssize + mp->dsize);
659159b3361Sopenharmony_ci    if (bytes > mp->bsize) {
660159b3361Sopenharmony_ci        return iret;
661159b3361Sopenharmony_ci    }
662159b3361Sopenharmony_ci
663159b3361Sopenharmony_ci    if (bytes > 0) {
664159b3361Sopenharmony_ci        int     size;
665159b3361Sopenharmony_ci#if 1
666159b3361Sopenharmony_ci        /* FIXME: while loop OK ??? */
667159b3361Sopenharmony_ci        while (bytes > 512) {
668159b3361Sopenharmony_ci            read_buf_byte(mp);
669159b3361Sopenharmony_ci            bytes--;
670159b3361Sopenharmony_ci            mp->framesize--;
671159b3361Sopenharmony_ci        }
672159b3361Sopenharmony_ci#endif
673159b3361Sopenharmony_ci        copy_mp(mp, bytes, mp->wordpointer);
674159b3361Sopenharmony_ci        mp->wordpointer += bytes;
675159b3361Sopenharmony_ci
676159b3361Sopenharmony_ci        size = (int) (mp->wordpointer - (mp->bsspace[mp->bsnum] + 512));
677159b3361Sopenharmony_ci        if (size > MAXFRAMESIZE) {
678159b3361Sopenharmony_ci            lame_report_fnc(mp->report_err, "hip: fatal error.  MAXFRAMESIZE not large enough.\n");
679159b3361Sopenharmony_ci        }
680159b3361Sopenharmony_ci
681159b3361Sopenharmony_ci    }
682159b3361Sopenharmony_ci
683159b3361Sopenharmony_ci    /* the above frame is completely parsed.  start looking for next frame */
684159b3361Sopenharmony_ci    mp->fsizeold = mp->framesize;
685159b3361Sopenharmony_ci    mp->old_free_format = mp->free_format;
686159b3361Sopenharmony_ci    mp->framesize = 0;
687159b3361Sopenharmony_ci    mp->header_parsed = 0;
688159b3361Sopenharmony_ci    mp->side_parsed = 0;
689159b3361Sopenharmony_ci    mp->data_parsed = 0;
690159b3361Sopenharmony_ci
691159b3361Sopenharmony_ci    return iret;
692159b3361Sopenharmony_ci}
693159b3361Sopenharmony_ci
694159b3361Sopenharmony_ciint
695159b3361Sopenharmony_cidecodeMP3(PMPSTR mp, unsigned char *in, int isize, char *out, int osize, int *done)
696159b3361Sopenharmony_ci{
697159b3361Sopenharmony_ci    if (osize < 4608) {
698159b3361Sopenharmony_ci        lame_report_fnc(mp->report_err, "hip: Insufficient memory for decoding buffer %d\n", osize);
699159b3361Sopenharmony_ci        return MP3_ERR;
700159b3361Sopenharmony_ci    }
701159b3361Sopenharmony_ci
702159b3361Sopenharmony_ci    /* passing pointers to the functions which clip the samples */
703159b3361Sopenharmony_ci    return decodeMP3_clipchoice(mp, in, isize, out, done, synth_1to1_mono, synth_1to1);
704159b3361Sopenharmony_ci}
705159b3361Sopenharmony_ci
706159b3361Sopenharmony_ciint
707159b3361Sopenharmony_cidecodeMP3_unclipped(PMPSTR mp, unsigned char *in, int isize, char *out, int osize, int *done)
708159b3361Sopenharmony_ci{
709159b3361Sopenharmony_ci    /* we forbid input with more than 1152 samples per channel for output in unclipped mode */
710159b3361Sopenharmony_ci    if (osize < (int) (1152 * 2 * sizeof(real))) {
711159b3361Sopenharmony_ci        lame_report_fnc(mp->report_err, "hip: out space too small for unclipped mode\n");
712159b3361Sopenharmony_ci        return MP3_ERR;
713159b3361Sopenharmony_ci    }
714159b3361Sopenharmony_ci
715159b3361Sopenharmony_ci    /* passing pointers to the functions which don't clip the samples */
716159b3361Sopenharmony_ci    return decodeMP3_clipchoice(mp, in, isize, out, done, synth_1to1_mono_unclipped,
717159b3361Sopenharmony_ci                                synth_1to1_unclipped);
718159b3361Sopenharmony_ci}
719