xref: /third_party/lame/frontend/get_audio.c (revision 159b3361)
1159b3361Sopenharmony_ci/*
2159b3361Sopenharmony_ci *      Get Audio routines source file
3159b3361Sopenharmony_ci *
4159b3361Sopenharmony_ci *      Copyright (c) 1999 Albert L Faber
5159b3361Sopenharmony_ci *                    2008-2017 Robert Hegemann
6159b3361Sopenharmony_ci *
7159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or
8159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public
9159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either
10159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version.
11159b3361Sopenharmony_ci *
12159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful,
13159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15159b3361Sopenharmony_ci * Library General Public License for more details.
16159b3361Sopenharmony_ci *
17159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public
18159b3361Sopenharmony_ci * License along with this library; if not, write to the
19159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA.
21159b3361Sopenharmony_ci */
22159b3361Sopenharmony_ci
23159b3361Sopenharmony_ci/* $Id$ */
24159b3361Sopenharmony_ci
25159b3361Sopenharmony_ci
26159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H
27159b3361Sopenharmony_ci# include <config.h>
28159b3361Sopenharmony_ci#endif
29159b3361Sopenharmony_ci
30159b3361Sopenharmony_ci#include <assert.h>
31159b3361Sopenharmony_ci
32159b3361Sopenharmony_ci#ifdef HAVE_LIMITS_H
33159b3361Sopenharmony_ci# include <limits.h>
34159b3361Sopenharmony_ci#endif
35159b3361Sopenharmony_ci
36159b3361Sopenharmony_ci#include <stdio.h>
37159b3361Sopenharmony_ci
38159b3361Sopenharmony_ci#ifdef STDC_HEADERS
39159b3361Sopenharmony_ci# include <stdlib.h>
40159b3361Sopenharmony_ci# include <string.h>
41159b3361Sopenharmony_ci#else
42159b3361Sopenharmony_ci# ifndef HAVE_STRCHR
43159b3361Sopenharmony_ci#  define strchr index
44159b3361Sopenharmony_ci#  define strrchr rindex
45159b3361Sopenharmony_ci# endif
46159b3361Sopenharmony_cichar   *strchr(), *strrchr();
47159b3361Sopenharmony_ci# ifndef HAVE_MEMCPY
48159b3361Sopenharmony_ci#  define memcpy(d, s, n) bcopy ((s), (d), (n))
49159b3361Sopenharmony_ci#  define memmove(d, s, n) bcopy ((s), (d), (n))
50159b3361Sopenharmony_ci# endif
51159b3361Sopenharmony_ci#endif
52159b3361Sopenharmony_ci
53159b3361Sopenharmony_ci#ifdef HAVE_INTTYPES_H
54159b3361Sopenharmony_ci# include <inttypes.h>
55159b3361Sopenharmony_ci#else
56159b3361Sopenharmony_ci# ifdef HAVE_STDINT_H
57159b3361Sopenharmony_ci#  include <stdint.h>
58159b3361Sopenharmony_ci# endif
59159b3361Sopenharmony_ci#endif
60159b3361Sopenharmony_ci
61159b3361Sopenharmony_ci#if defined(HAVE_MPGLIB) || defined(HAVE_MPG123)
62159b3361Sopenharmony_ci#define hip_global_struct mpstr_tag
63159b3361Sopenharmony_ci#endif
64159b3361Sopenharmony_ci#ifdef HAVE_MPG123
65159b3361Sopenharmony_ci#include <mpg123.h>
66159b3361Sopenharmony_ci/* for mpstr_tag */
67159b3361Sopenharmony_ci#include "mpglib/mpglib.h"
68159b3361Sopenharmony_ci
69159b3361Sopenharmony_ci#endif
70159b3361Sopenharmony_ci
71159b3361Sopenharmony_ci#define         MAX_U_32_NUM            0xFFFFFFFF
72159b3361Sopenharmony_ci
73159b3361Sopenharmony_ci
74159b3361Sopenharmony_ci#include <math.h>
75159b3361Sopenharmony_ci
76159b3361Sopenharmony_ci#if defined(__riscos__)
77159b3361Sopenharmony_ci# include <kernel.h>
78159b3361Sopenharmony_ci# include <sys/swis.h>
79159b3361Sopenharmony_ci#elif defined(_WIN32)
80159b3361Sopenharmony_ci# include <sys/types.h>
81159b3361Sopenharmony_ci# include <sys/stat.h>
82159b3361Sopenharmony_ci#else
83159b3361Sopenharmony_ci# include <sys/stat.h>
84159b3361Sopenharmony_ci#endif
85159b3361Sopenharmony_ci
86159b3361Sopenharmony_ci#ifdef __sun__
87159b3361Sopenharmony_ci/* woraround for SunOS 4.x, it has SEEK_* defined here */
88159b3361Sopenharmony_ci#include <unistd.h>
89159b3361Sopenharmony_ci#endif
90159b3361Sopenharmony_ci
91159b3361Sopenharmony_ci#include "lame.h"
92159b3361Sopenharmony_ci#include "main.h"
93159b3361Sopenharmony_ci#include "get_audio.h"
94159b3361Sopenharmony_ci#include "lametime.h"
95159b3361Sopenharmony_ci#include "console.h"
96159b3361Sopenharmony_ci
97159b3361Sopenharmony_ci#ifdef WITH_DMALLOC
98159b3361Sopenharmony_ci#include <dmalloc.h>
99159b3361Sopenharmony_ci#endif
100159b3361Sopenharmony_ci
101159b3361Sopenharmony_ci#ifndef STR
102159b3361Sopenharmony_ci# define __STR(x)  #x
103159b3361Sopenharmony_ci# define STR(x)    __STR(x)
104159b3361Sopenharmony_ci#define __LOC__ __FILE__ "("STR(__LINE__)") : "
105159b3361Sopenharmony_ci#endif
106159b3361Sopenharmony_ci
107159b3361Sopenharmony_ci
108159b3361Sopenharmony_ci#define FLOAT_TO_UNSIGNED(f) ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))
109159b3361Sopenharmony_ci#define UNSIGNED_TO_FLOAT(u) (((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)
110159b3361Sopenharmony_ci
111159b3361Sopenharmony_cistatic uint32_t uint32_high_low(unsigned char const *bytes)
112159b3361Sopenharmony_ci{
113159b3361Sopenharmony_ci    uint32_t const hh = bytes[0];
114159b3361Sopenharmony_ci    uint32_t const hl = bytes[1];
115159b3361Sopenharmony_ci    uint32_t const lh = bytes[2];
116159b3361Sopenharmony_ci    uint32_t const ll = bytes[3];
117159b3361Sopenharmony_ci    return (hh << 24) | (hl << 16) | (lh << 8) | ll;
118159b3361Sopenharmony_ci}
119159b3361Sopenharmony_ci
120159b3361Sopenharmony_cistatic double
121159b3361Sopenharmony_ciread_ieee_extended_high_low(FILE * fp)
122159b3361Sopenharmony_ci{
123159b3361Sopenharmony_ci    unsigned char bytes[10];
124159b3361Sopenharmony_ci    memset(bytes, 0, 10);
125159b3361Sopenharmony_ci    fread(bytes, 1, 10, fp);
126159b3361Sopenharmony_ci    {
127159b3361Sopenharmony_ci        int32_t const s = (bytes[0] & 0x80);
128159b3361Sopenharmony_ci        int32_t const e_h = (bytes[0] & 0x7F);
129159b3361Sopenharmony_ci        int32_t const e_l = bytes[1];
130159b3361Sopenharmony_ci        int32_t e = (e_h << 8) | e_l;
131159b3361Sopenharmony_ci        uint32_t const hm = uint32_high_low(bytes + 2);
132159b3361Sopenharmony_ci        uint32_t const lm = uint32_high_low(bytes + 6);
133159b3361Sopenharmony_ci        double  result = 0;
134159b3361Sopenharmony_ci        if (e != 0 || hm != 0 || lm != 0) {
135159b3361Sopenharmony_ci            if (e == 0x7fff) {
136159b3361Sopenharmony_ci                result = HUGE_VAL;
137159b3361Sopenharmony_ci            }
138159b3361Sopenharmony_ci            else {
139159b3361Sopenharmony_ci                double  mantissa_h = UNSIGNED_TO_FLOAT(hm);
140159b3361Sopenharmony_ci                double  mantissa_l = UNSIGNED_TO_FLOAT(lm);
141159b3361Sopenharmony_ci                e -= 0x3fff;
142159b3361Sopenharmony_ci                e -= 31;
143159b3361Sopenharmony_ci                result = ldexp(mantissa_h, e);
144159b3361Sopenharmony_ci                e -= 32;
145159b3361Sopenharmony_ci                result += ldexp(mantissa_l, e);
146159b3361Sopenharmony_ci            }
147159b3361Sopenharmony_ci        }
148159b3361Sopenharmony_ci        return s ? -result : result;
149159b3361Sopenharmony_ci    }
150159b3361Sopenharmony_ci}
151159b3361Sopenharmony_ci
152159b3361Sopenharmony_ci
153159b3361Sopenharmony_cistatic uint16_t
154159b3361Sopenharmony_ciread_16_bits_low_high(FILE * fp)
155159b3361Sopenharmony_ci{
156159b3361Sopenharmony_ci    unsigned char bytes[2] = { 0, 0 };
157159b3361Sopenharmony_ci    fread(bytes, 1, 2, fp);
158159b3361Sopenharmony_ci    {
159159b3361Sopenharmony_ci        uint16_t const l = bytes[0];
160159b3361Sopenharmony_ci        uint16_t const h = bytes[1];
161159b3361Sopenharmony_ci        return (h << 8) | l;
162159b3361Sopenharmony_ci    }
163159b3361Sopenharmony_ci}
164159b3361Sopenharmony_ci
165159b3361Sopenharmony_ci
166159b3361Sopenharmony_cistatic uint32_t
167159b3361Sopenharmony_ciread_32_bits_low_high(FILE * fp)
168159b3361Sopenharmony_ci{
169159b3361Sopenharmony_ci    unsigned char bytes[4] = { 0, 0, 0, 0 };
170159b3361Sopenharmony_ci    fread(bytes, 1, 4, fp);
171159b3361Sopenharmony_ci    {
172159b3361Sopenharmony_ci        uint32_t const ll = bytes[0];
173159b3361Sopenharmony_ci        uint32_t const lh = bytes[1];
174159b3361Sopenharmony_ci        uint32_t const hl = bytes[2];
175159b3361Sopenharmony_ci        uint32_t const hh = bytes[3];
176159b3361Sopenharmony_ci        return (hh << 24) | (hl << 16) | (lh << 8) | ll;
177159b3361Sopenharmony_ci    }
178159b3361Sopenharmony_ci}
179159b3361Sopenharmony_ci
180159b3361Sopenharmony_cistatic uint16_t
181159b3361Sopenharmony_ciread_16_bits_high_low(FILE * fp)
182159b3361Sopenharmony_ci{
183159b3361Sopenharmony_ci    unsigned char bytes[2] = { 0, 0 };
184159b3361Sopenharmony_ci    fread(bytes, 1, 2, fp);
185159b3361Sopenharmony_ci    {
186159b3361Sopenharmony_ci        uint16_t const h = bytes[0];
187159b3361Sopenharmony_ci        uint16_t const l = bytes[1];
188159b3361Sopenharmony_ci        return (h << 8) | l;
189159b3361Sopenharmony_ci    }
190159b3361Sopenharmony_ci}
191159b3361Sopenharmony_ci
192159b3361Sopenharmony_cistatic uint32_t
193159b3361Sopenharmony_ciread_32_bits_high_low(FILE * fp)
194159b3361Sopenharmony_ci{
195159b3361Sopenharmony_ci    unsigned char bytes[4] = { 0, 0, 0, 0 };
196159b3361Sopenharmony_ci    fread(bytes, 1, 4, fp);
197159b3361Sopenharmony_ci    return uint32_high_low(bytes);
198159b3361Sopenharmony_ci}
199159b3361Sopenharmony_ci
200159b3361Sopenharmony_cistatic void
201159b3361Sopenharmony_ciwrite_16_bits_low_high(FILE * fp, int val)
202159b3361Sopenharmony_ci{
203159b3361Sopenharmony_ci    unsigned char bytes[2];
204159b3361Sopenharmony_ci    bytes[0] = (val & 0xff);
205159b3361Sopenharmony_ci    bytes[1] = ((val >> 8) & 0xff);
206159b3361Sopenharmony_ci    fwrite(bytes, 1, 2, fp);
207159b3361Sopenharmony_ci}
208159b3361Sopenharmony_ci
209159b3361Sopenharmony_cistatic void
210159b3361Sopenharmony_ciwrite_32_bits_low_high(FILE * fp, int val)
211159b3361Sopenharmony_ci{
212159b3361Sopenharmony_ci    unsigned char bytes[4];
213159b3361Sopenharmony_ci    bytes[0] = (val & 0xff);
214159b3361Sopenharmony_ci    bytes[1] = ((val >> 8) & 0xff);
215159b3361Sopenharmony_ci    bytes[2] = ((val >> 16) & 0xff);
216159b3361Sopenharmony_ci    bytes[3] = ((val >> 24) & 0xff);
217159b3361Sopenharmony_ci    fwrite(bytes, 1, 4, fp);
218159b3361Sopenharmony_ci}
219159b3361Sopenharmony_ci
220159b3361Sopenharmony_ci#ifdef LIBSNDFILE
221159b3361Sopenharmony_ci
222159b3361Sopenharmony_ci#include <sndfile.h>
223159b3361Sopenharmony_ci
224159b3361Sopenharmony_ci
225159b3361Sopenharmony_ci#else
226159b3361Sopenharmony_ci
227159b3361Sopenharmony_citypedef void SNDFILE;
228159b3361Sopenharmony_ci
229159b3361Sopenharmony_ci#endif /* ifdef LIBSNDFILE */
230159b3361Sopenharmony_ci
231159b3361Sopenharmony_ci
232159b3361Sopenharmony_ci
233159b3361Sopenharmony_citypedef struct blockAlign_struct {
234159b3361Sopenharmony_ci    uint32_t offset;
235159b3361Sopenharmony_ci    uint32_t blockSize;
236159b3361Sopenharmony_ci} blockAlign;
237159b3361Sopenharmony_ci
238159b3361Sopenharmony_citypedef struct IFF_AIFF_struct {
239159b3361Sopenharmony_ci    short   numChannels;
240159b3361Sopenharmony_ci    unsigned long numSampleFrames;
241159b3361Sopenharmony_ci    short   sampleSize;
242159b3361Sopenharmony_ci    double  sampleRate;
243159b3361Sopenharmony_ci    uint32_t sampleType;
244159b3361Sopenharmony_ci    uint32_t sampleFormat;
245159b3361Sopenharmony_ci    blockAlign blkAlgn;
246159b3361Sopenharmony_ci} IFF_AIFF;
247159b3361Sopenharmony_ci
248159b3361Sopenharmony_ci
249159b3361Sopenharmony_ci
250159b3361Sopenharmony_cistruct PcmBuffer {
251159b3361Sopenharmony_ci    void   *ch[2];           /* buffer for each channel */
252159b3361Sopenharmony_ci    int     w;               /* sample width */
253159b3361Sopenharmony_ci    int     n;               /* number samples allocated */
254159b3361Sopenharmony_ci    int     u;               /* number samples used */
255159b3361Sopenharmony_ci    int     skip_start;      /* number samples to ignore at the beginning */
256159b3361Sopenharmony_ci    int     skip_end;        /* number samples to ignore at the end */
257159b3361Sopenharmony_ci};
258159b3361Sopenharmony_ci
259159b3361Sopenharmony_citypedef struct PcmBuffer PcmBuffer;
260159b3361Sopenharmony_ci
261159b3361Sopenharmony_cistatic void
262159b3361Sopenharmony_ciinitPcmBuffer(PcmBuffer * b, int w)
263159b3361Sopenharmony_ci{
264159b3361Sopenharmony_ci    b->ch[0] = 0;
265159b3361Sopenharmony_ci    b->ch[1] = 0;
266159b3361Sopenharmony_ci    b->w = w;
267159b3361Sopenharmony_ci    b->n = 0;
268159b3361Sopenharmony_ci    b->u = 0;
269159b3361Sopenharmony_ci    b->skip_start = 0;
270159b3361Sopenharmony_ci    b->skip_end = 0;
271159b3361Sopenharmony_ci}
272159b3361Sopenharmony_ci
273159b3361Sopenharmony_cistatic void
274159b3361Sopenharmony_cifreePcmBuffer(PcmBuffer * b)
275159b3361Sopenharmony_ci{
276159b3361Sopenharmony_ci    if (b != 0) {
277159b3361Sopenharmony_ci        free(b->ch[0]);
278159b3361Sopenharmony_ci        free(b->ch[1]);
279159b3361Sopenharmony_ci        b->ch[0] = 0;
280159b3361Sopenharmony_ci        b->ch[1] = 0;
281159b3361Sopenharmony_ci        b->n = 0;
282159b3361Sopenharmony_ci        b->u = 0;
283159b3361Sopenharmony_ci    }
284159b3361Sopenharmony_ci}
285159b3361Sopenharmony_ci
286159b3361Sopenharmony_cistatic int
287159b3361Sopenharmony_ciaddPcmBuffer(PcmBuffer * b, void *a0, void *a1, int read)
288159b3361Sopenharmony_ci{
289159b3361Sopenharmony_ci    int     a_n;
290159b3361Sopenharmony_ci
291159b3361Sopenharmony_ci    if (b == 0) {
292159b3361Sopenharmony_ci        return 0;
293159b3361Sopenharmony_ci    }
294159b3361Sopenharmony_ci    if (read < 0) {
295159b3361Sopenharmony_ci        return b->u - b->skip_end;
296159b3361Sopenharmony_ci    }
297159b3361Sopenharmony_ci    if (b->skip_start >= read) {
298159b3361Sopenharmony_ci        b->skip_start -= read;
299159b3361Sopenharmony_ci        return b->u - b->skip_end;
300159b3361Sopenharmony_ci    }
301159b3361Sopenharmony_ci    a_n = read - b->skip_start;
302159b3361Sopenharmony_ci
303159b3361Sopenharmony_ci    if (a_n > 0) {
304159b3361Sopenharmony_ci        int const a_skip = b->w * b->skip_start;
305159b3361Sopenharmony_ci        int const a_want = b->w * a_n;
306159b3361Sopenharmony_ci        int const b_used = b->w * b->u;
307159b3361Sopenharmony_ci        int const b_have = b->w * b->n;
308159b3361Sopenharmony_ci        int const b_need = b->w * (b->u + a_n);
309159b3361Sopenharmony_ci        if (b_have < b_need) {
310159b3361Sopenharmony_ci            b->n = b->u + a_n;
311159b3361Sopenharmony_ci            b->ch[0] = realloc(b->ch[0], b_need);
312159b3361Sopenharmony_ci            b->ch[1] = realloc(b->ch[1], b_need);
313159b3361Sopenharmony_ci        }
314159b3361Sopenharmony_ci        b->u += a_n;
315159b3361Sopenharmony_ci        if (b->ch[0] != 0 && a0 != 0) {
316159b3361Sopenharmony_ci            char   *src = a0;
317159b3361Sopenharmony_ci            char   *dst = b->ch[0];
318159b3361Sopenharmony_ci            memcpy(dst + b_used, src + a_skip, a_want);
319159b3361Sopenharmony_ci        }
320159b3361Sopenharmony_ci        if (b->ch[1] != 0 && a1 != 0) {
321159b3361Sopenharmony_ci            char   *src = a1;
322159b3361Sopenharmony_ci            char   *dst = b->ch[1];
323159b3361Sopenharmony_ci            memcpy(dst + b_used, src + a_skip, a_want);
324159b3361Sopenharmony_ci        }
325159b3361Sopenharmony_ci    }
326159b3361Sopenharmony_ci    b->skip_start = 0;
327159b3361Sopenharmony_ci    return b->u - b->skip_end;
328159b3361Sopenharmony_ci}
329159b3361Sopenharmony_ci
330159b3361Sopenharmony_cistatic int
331159b3361Sopenharmony_citakePcmBuffer(PcmBuffer * b, void *a0, void *a1, int a_n, int mm)
332159b3361Sopenharmony_ci{
333159b3361Sopenharmony_ci    if (a_n > mm) {
334159b3361Sopenharmony_ci        a_n = mm;
335159b3361Sopenharmony_ci    }
336159b3361Sopenharmony_ci    if (b != 0 && a_n > 0) {
337159b3361Sopenharmony_ci        int const a_take = b->w * a_n;
338159b3361Sopenharmony_ci        if (a0 != 0 && b->ch[0] != 0) {
339159b3361Sopenharmony_ci            memcpy(a0, b->ch[0], a_take);
340159b3361Sopenharmony_ci        }
341159b3361Sopenharmony_ci        if (a1 != 0 && b->ch[1] != 0) {
342159b3361Sopenharmony_ci            memcpy(a1, b->ch[1], a_take);
343159b3361Sopenharmony_ci        }
344159b3361Sopenharmony_ci        b->u -= a_n;
345159b3361Sopenharmony_ci        if (b->u < 0) {
346159b3361Sopenharmony_ci            b->u = 0;
347159b3361Sopenharmony_ci            return a_n;
348159b3361Sopenharmony_ci        }
349159b3361Sopenharmony_ci        if (b->ch[0] != 0) {
350159b3361Sopenharmony_ci            memmove(b->ch[0], (char *) b->ch[0] + a_take, b->w * b->u);
351159b3361Sopenharmony_ci        }
352159b3361Sopenharmony_ci        if (b->ch[1] != 0) {
353159b3361Sopenharmony_ci            memmove(b->ch[1], (char *) b->ch[1] + a_take, b->w * b->u);
354159b3361Sopenharmony_ci        }
355159b3361Sopenharmony_ci    }
356159b3361Sopenharmony_ci    return a_n;
357159b3361Sopenharmony_ci}
358159b3361Sopenharmony_ci
359159b3361Sopenharmony_ci/* global data for get_audio.c. */
360159b3361Sopenharmony_citypedef struct get_audio_global_data_struct {
361159b3361Sopenharmony_ci    int     count_samples_carefully;
362159b3361Sopenharmony_ci    int     pcmbitwidth;
363159b3361Sopenharmony_ci    int     pcmswapbytes;
364159b3361Sopenharmony_ci    int     pcm_is_unsigned_8bit;
365159b3361Sopenharmony_ci    int     pcm_is_ieee_float;
366159b3361Sopenharmony_ci    unsigned int num_samples_read;
367159b3361Sopenharmony_ci    FILE   *music_in;
368159b3361Sopenharmony_ci    SNDFILE *snd_file;
369159b3361Sopenharmony_ci#ifdef HAVE_MPG123
370159b3361Sopenharmony_ci    mpg123_handle* mh;
371159b3361Sopenharmony_ci#endif
372159b3361Sopenharmony_ci    hip_t     hip;
373159b3361Sopenharmony_ci    PcmBuffer pcm32;
374159b3361Sopenharmony_ci    PcmBuffer pcm16;
375159b3361Sopenharmony_ci    size_t  in_id3v2_size;
376159b3361Sopenharmony_ci    unsigned char* in_id3v2_tag;
377159b3361Sopenharmony_ci} get_audio_global_data;
378159b3361Sopenharmony_ci
379159b3361Sopenharmony_cistatic get_audio_global_data global;
380159b3361Sopenharmony_ci
381159b3361Sopenharmony_ci
382159b3361Sopenharmony_ci
383159b3361Sopenharmony_ci#ifdef AMIGA_MPEGA
384159b3361Sopenharmony_ciint     lame_decode_initfile_amiga(const char *fullname, mp3data_struct * const mp3data);
385159b3361Sopenharmony_ci#else
386159b3361Sopenharmony_ciint     lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding);
387159b3361Sopenharmony_ci#endif
388159b3361Sopenharmony_ci#ifdef HAVE_MPG123
389159b3361Sopenharmony_ciint     lame123_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding);
390159b3361Sopenharmony_ci#endif
391159b3361Sopenharmony_ci
392159b3361Sopenharmony_ci/* read mp3 file until mpglib returns one frame of PCM data */
393159b3361Sopenharmony_cistatic int lame_decode_fromfile(FILE * fd, short int pcm_l[], short int pcm_r[],
394159b3361Sopenharmony_ci                                mp3data_struct * mp3data);
395159b3361Sopenharmony_ci
396159b3361Sopenharmony_ci
397159b3361Sopenharmony_cistatic int read_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read);
398159b3361Sopenharmony_cistatic int read_samples_mp3(lame_t gfp, FILE * musicin, short int mpg123pcm[2][1152]);
399159b3361Sopenharmony_ci#ifdef LIBSNDFILE
400159b3361Sopenharmony_cistatic SNDFILE *open_snd_file(lame_t gfp, char const *inPath);
401159b3361Sopenharmony_ci#endif
402159b3361Sopenharmony_cistatic FILE *open_mpeg_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding);
403159b3361Sopenharmony_cistatic FILE *open_wave_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding);
404159b3361Sopenharmony_cistatic int close_input_file(FILE * musicin);
405159b3361Sopenharmony_ci
406159b3361Sopenharmony_ci
407159b3361Sopenharmony_cistatic  size_t
408159b3361Sopenharmony_cimin_size_t(size_t a, size_t b)
409159b3361Sopenharmony_ci{
410159b3361Sopenharmony_ci    if (a < b) {
411159b3361Sopenharmony_ci        return a;
412159b3361Sopenharmony_ci    }
413159b3361Sopenharmony_ci    return b;
414159b3361Sopenharmony_ci}
415159b3361Sopenharmony_ci
416159b3361Sopenharmony_cienum ByteOrder machine_byte_order(void);
417159b3361Sopenharmony_ci
418159b3361Sopenharmony_cienum ByteOrder
419159b3361Sopenharmony_cimachine_byte_order(void)
420159b3361Sopenharmony_ci{
421159b3361Sopenharmony_ci    long    one = 1;
422159b3361Sopenharmony_ci    return !(*((char *) (&one))) ? ByteOrderBigEndian : ByteOrderLittleEndian;
423159b3361Sopenharmony_ci}
424159b3361Sopenharmony_ci
425159b3361Sopenharmony_ci
426159b3361Sopenharmony_ci
427159b3361Sopenharmony_ci/* Replacement for forward fseek(,,SEEK_CUR), because fseek() fails on pipes */
428159b3361Sopenharmony_ci
429159b3361Sopenharmony_ci
430159b3361Sopenharmony_cistatic int
431159b3361Sopenharmony_cifskip_long(FILE * fp, long offset, int whence)
432159b3361Sopenharmony_ci{
433159b3361Sopenharmony_ci#ifndef PIPE_BUF
434159b3361Sopenharmony_ci    char    buffer[4096];
435159b3361Sopenharmony_ci#else
436159b3361Sopenharmony_ci    char    buffer[PIPE_BUF];
437159b3361Sopenharmony_ci#endif
438159b3361Sopenharmony_ci
439159b3361Sopenharmony_ci/* S_ISFIFO macro is defined on newer Linuxes */
440159b3361Sopenharmony_ci#ifndef S_ISFIFO
441159b3361Sopenharmony_ci# ifdef _S_IFIFO
442159b3361Sopenharmony_ci    /* _S_IFIFO is defined on Win32 and Cygwin */
443159b3361Sopenharmony_ci#  define S_ISFIFO(m) (((m)&_S_IFIFO) == _S_IFIFO)
444159b3361Sopenharmony_ci# endif
445159b3361Sopenharmony_ci#endif
446159b3361Sopenharmony_ci
447159b3361Sopenharmony_ci#ifdef S_ISFIFO
448159b3361Sopenharmony_ci    /* fseek is known to fail on pipes with several C-Library implementations
449159b3361Sopenharmony_ci       workaround: 1) test for pipe
450159b3361Sopenharmony_ci       2) for pipes, only relatvie seeking is possible
451159b3361Sopenharmony_ci       3)            and only in forward direction!
452159b3361Sopenharmony_ci       else fallback to old code
453159b3361Sopenharmony_ci     */
454159b3361Sopenharmony_ci    {
455159b3361Sopenharmony_ci        int const fd = fileno(fp);
456159b3361Sopenharmony_ci        struct stat file_stat;
457159b3361Sopenharmony_ci
458159b3361Sopenharmony_ci        if (fstat(fd, &file_stat) == 0) {
459159b3361Sopenharmony_ci            if (S_ISFIFO(file_stat.st_mode)) {
460159b3361Sopenharmony_ci                if (whence != SEEK_CUR || offset < 0) {
461159b3361Sopenharmony_ci                    return -1;
462159b3361Sopenharmony_ci                }
463159b3361Sopenharmony_ci                while (offset > 0) {
464159b3361Sopenharmony_ci                    size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset);
465159b3361Sopenharmony_ci                    size_t const read = fread(buffer, 1, bytes_to_skip, fp);
466159b3361Sopenharmony_ci                    if (read < 1) {
467159b3361Sopenharmony_ci                        return -1;
468159b3361Sopenharmony_ci                    }
469159b3361Sopenharmony_ci                    assert( read <= LONG_MAX );
470159b3361Sopenharmony_ci                    offset -= (long) read;
471159b3361Sopenharmony_ci                }
472159b3361Sopenharmony_ci                return 0;
473159b3361Sopenharmony_ci            }
474159b3361Sopenharmony_ci        }
475159b3361Sopenharmony_ci    }
476159b3361Sopenharmony_ci#endif
477159b3361Sopenharmony_ci    if (0 == fseek(fp, offset, whence)) {
478159b3361Sopenharmony_ci        return 0;
479159b3361Sopenharmony_ci    }
480159b3361Sopenharmony_ci
481159b3361Sopenharmony_ci    if (whence != SEEK_CUR || offset < 0) {
482159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
483159b3361Sopenharmony_ci            error_printf
484159b3361Sopenharmony_ci                ("fskip problem: Mostly the return status of functions is not evaluated, so it is more secure to pollute <stderr>.\n");
485159b3361Sopenharmony_ci        }
486159b3361Sopenharmony_ci        return -1;
487159b3361Sopenharmony_ci    }
488159b3361Sopenharmony_ci
489159b3361Sopenharmony_ci    while (offset > 0) {
490159b3361Sopenharmony_ci        size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset);
491159b3361Sopenharmony_ci        size_t const read = fread(buffer, 1, bytes_to_skip, fp);
492159b3361Sopenharmony_ci        if (read < 1) {
493159b3361Sopenharmony_ci            return -1;
494159b3361Sopenharmony_ci        }
495159b3361Sopenharmony_ci        assert( read <= LONG_MAX );
496159b3361Sopenharmony_ci        offset -= (long) read;
497159b3361Sopenharmony_ci    }
498159b3361Sopenharmony_ci
499159b3361Sopenharmony_ci    return 0;
500159b3361Sopenharmony_ci}
501159b3361Sopenharmony_ci
502159b3361Sopenharmony_cistatic int
503159b3361Sopenharmony_cifskip_uint32(FILE * fp, uint32_t offset)
504159b3361Sopenharmony_ci{
505159b3361Sopenharmony_ci    int   ret = 0;
506159b3361Sopenharmony_ci    while (offset > INT_MAX && ret == 0) {
507159b3361Sopenharmony_ci        offset -= INT_MAX;
508159b3361Sopenharmony_ci        ret = fskip_long(fp, INT_MAX, SEEK_CUR);
509159b3361Sopenharmony_ci    }
510159b3361Sopenharmony_ci    if (offset > 0 && ret == 0) {
511159b3361Sopenharmony_ci        ret = fskip_long(fp, offset, SEEK_CUR);
512159b3361Sopenharmony_ci    }
513159b3361Sopenharmony_ci    return ret;
514159b3361Sopenharmony_ci}
515159b3361Sopenharmony_ci
516159b3361Sopenharmony_cistatic  off_t
517159b3361Sopenharmony_cilame_get_file_size(FILE * fp)
518159b3361Sopenharmony_ci{
519159b3361Sopenharmony_ci    struct stat sb;
520159b3361Sopenharmony_ci    int     fd = fileno(fp);
521159b3361Sopenharmony_ci
522159b3361Sopenharmony_ci    if (0 == fstat(fd, &sb))
523159b3361Sopenharmony_ci        return sb.st_size;
524159b3361Sopenharmony_ci    return (off_t) - 1;
525159b3361Sopenharmony_ci}
526159b3361Sopenharmony_ci
527159b3361Sopenharmony_ci
528159b3361Sopenharmony_ciFILE   *
529159b3361Sopenharmony_ciinit_outfile(char const *outPath, int decode)
530159b3361Sopenharmony_ci{
531159b3361Sopenharmony_ci    FILE   *outf;
532159b3361Sopenharmony_ci
533159b3361Sopenharmony_ci    /* open the output file */
534159b3361Sopenharmony_ci    if (0 == strcmp(outPath, "-")) {
535159b3361Sopenharmony_ci        outf = stdout;
536159b3361Sopenharmony_ci        lame_set_stream_binary_mode(outf);
537159b3361Sopenharmony_ci    }
538159b3361Sopenharmony_ci    else {
539159b3361Sopenharmony_ci        outf = lame_fopen(outPath, "w+b");
540159b3361Sopenharmony_ci#ifdef __riscos__
541159b3361Sopenharmony_ci        /* Assign correct file type */
542159b3361Sopenharmony_ci        if (outf != NULL) {
543159b3361Sopenharmony_ci            char   *p, *out_path = strdup(outPath);
544159b3361Sopenharmony_ci            for (p = out_path; *p; p++) { /* ugly, ugly to modify a string */
545159b3361Sopenharmony_ci                switch (*p) {
546159b3361Sopenharmony_ci                case '.':
547159b3361Sopenharmony_ci                    *p = '/';
548159b3361Sopenharmony_ci                    break;
549159b3361Sopenharmony_ci                case '/':
550159b3361Sopenharmony_ci                    *p = '.';
551159b3361Sopenharmony_ci                    break;
552159b3361Sopenharmony_ci                }
553159b3361Sopenharmony_ci            }
554159b3361Sopenharmony_ci            SetFiletype(out_path, decode ? 0xFB1 /*WAV*/ : 0x1AD /*AMPEG*/);
555159b3361Sopenharmony_ci            free(out_path);
556159b3361Sopenharmony_ci        }
557159b3361Sopenharmony_ci#else
558159b3361Sopenharmony_ci        (void) decode;
559159b3361Sopenharmony_ci#endif
560159b3361Sopenharmony_ci    }
561159b3361Sopenharmony_ci    return outf;
562159b3361Sopenharmony_ci}
563159b3361Sopenharmony_ci
564159b3361Sopenharmony_ci
565159b3361Sopenharmony_cistatic void
566159b3361Sopenharmony_cisetSkipStartAndEnd(lame_t gfp, int enc_delay, int enc_padding)
567159b3361Sopenharmony_ci{
568159b3361Sopenharmony_ci    int     skip_start = 0, skip_end = 0;
569159b3361Sopenharmony_ci    long dec_delay = -1;
570159b3361Sopenharmony_ci
571159b3361Sopenharmony_ci    if (global_decoder.mp3_delay_set)
572159b3361Sopenharmony_ci        skip_start = global_decoder.mp3_delay;
573159b3361Sopenharmony_ci
574159b3361Sopenharmony_ci#if 0
575159b3361Sopenharmony_ci    /* We should ask mpg123 for the delay, but we know it is 529 samples and
576159b3361Sopenharmony_ci       will not change unless we enable gapless mode. Also, global.hip is not
577159b3361Sopenharmony_ci       always the correct handle, so avoid this for now. */
578159b3361Sopenharmony_ci    /* Will use it for layer III only, mpg123 does not deal with layer I and II
579159b3361Sopenharmony_ci       gapless stuff (yet?) */
580159b3361Sopenharmony_ci    mpg123_getstate(global.hip->mh, MPG123_DEC_DELAY, &dec_delay, NULL);
581159b3361Sopenharmony_ci#else
582159b3361Sopenharmony_ci    if(dec_delay < 0)
583159b3361Sopenharmony_ci        dec_delay = 528 + 1; /* Same value as above, actually. */
584159b3361Sopenharmony_ci#endif
585159b3361Sopenharmony_ci
586159b3361Sopenharmony_ci    switch (global_reader.input_format) {
587159b3361Sopenharmony_ci    case sf_mp123:
588159b3361Sopenharmony_ci        break;
589159b3361Sopenharmony_ci
590159b3361Sopenharmony_ci    case sf_mp3:
591159b3361Sopenharmony_ci        if (skip_start == 0) {
592159b3361Sopenharmony_ci            if (enc_delay > -1 || enc_padding > -1) {
593159b3361Sopenharmony_ci                if (enc_delay > -1)
594159b3361Sopenharmony_ci                    skip_start = enc_delay + dec_delay;
595159b3361Sopenharmony_ci                if (enc_padding > -1)
596159b3361Sopenharmony_ci                    skip_end = enc_padding - dec_delay;
597159b3361Sopenharmony_ci            }
598159b3361Sopenharmony_ci            else
599159b3361Sopenharmony_ci                skip_start = lame_get_encoder_delay(gfp) + dec_delay;
600159b3361Sopenharmony_ci        }
601159b3361Sopenharmony_ci        else {
602159b3361Sopenharmony_ci            /* user specified a value of skip. just add for decoder */
603159b3361Sopenharmony_ci            skip_start += dec_delay; /* mp3 decoder has a 528 sample delay, plus user supplied "skip" */
604159b3361Sopenharmony_ci        }
605159b3361Sopenharmony_ci        break;
606159b3361Sopenharmony_ci    case sf_mp2:
607159b3361Sopenharmony_ci        skip_start += 240 + 1;
608159b3361Sopenharmony_ci        break;
609159b3361Sopenharmony_ci    case sf_mp1:
610159b3361Sopenharmony_ci        skip_start += 240 + 1;
611159b3361Sopenharmony_ci        break;
612159b3361Sopenharmony_ci    case sf_raw:
613159b3361Sopenharmony_ci        skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
614159b3361Sopenharmony_ci        break;
615159b3361Sopenharmony_ci    case sf_wave:
616159b3361Sopenharmony_ci        skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
617159b3361Sopenharmony_ci        break;
618159b3361Sopenharmony_ci    case sf_aiff:
619159b3361Sopenharmony_ci        skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
620159b3361Sopenharmony_ci        break;
621159b3361Sopenharmony_ci    default:
622159b3361Sopenharmony_ci        skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
623159b3361Sopenharmony_ci        break;
624159b3361Sopenharmony_ci    }
625159b3361Sopenharmony_ci    skip_start = skip_start < 0 ? 0 : skip_start;
626159b3361Sopenharmony_ci    skip_end = skip_end < 0 ? 0 : skip_end;
627159b3361Sopenharmony_ci    global. pcm16.skip_start = global.pcm32.skip_start = skip_start;
628159b3361Sopenharmony_ci    global. pcm16.skip_end = global.pcm32.skip_end = skip_end;
629159b3361Sopenharmony_ci}
630159b3361Sopenharmony_ci
631159b3361Sopenharmony_ci
632159b3361Sopenharmony_ci
633159b3361Sopenharmony_ciint
634159b3361Sopenharmony_ciinit_infile(lame_t gfp, char const *inPath)
635159b3361Sopenharmony_ci{
636159b3361Sopenharmony_ci    int     enc_delay = 0, enc_padding = 0;
637159b3361Sopenharmony_ci    /* open the input file */
638159b3361Sopenharmony_ci    global. count_samples_carefully = 0;
639159b3361Sopenharmony_ci    global. num_samples_read = 0;
640159b3361Sopenharmony_ci    global. pcmbitwidth = global_raw_pcm.in_bitwidth;
641159b3361Sopenharmony_ci    global. pcmswapbytes = global_reader.swapbytes;
642159b3361Sopenharmony_ci    global. pcm_is_unsigned_8bit = global_raw_pcm.in_signed == 1 ? 0 : 1;
643159b3361Sopenharmony_ci    global. pcm_is_ieee_float = 0;
644159b3361Sopenharmony_ci    global. hip = 0;
645159b3361Sopenharmony_ci    global. music_in = 0;
646159b3361Sopenharmony_ci    global. snd_file = 0;
647159b3361Sopenharmony_ci    global. in_id3v2_size = 0;
648159b3361Sopenharmony_ci    global. in_id3v2_tag = 0;
649159b3361Sopenharmony_ci    if (is_mpeg_file_format(global_reader.input_format)) {
650159b3361Sopenharmony_ci        global. music_in = open_mpeg_file(gfp, inPath, &enc_delay, &enc_padding);
651159b3361Sopenharmony_ci    }
652159b3361Sopenharmony_ci    else {
653159b3361Sopenharmony_ci#ifdef LIBSNDFILE
654159b3361Sopenharmony_ci        if (strcmp(inPath, "-") != 0) { /* not for stdin */
655159b3361Sopenharmony_ci            global. snd_file = open_snd_file(gfp, inPath);
656159b3361Sopenharmony_ci        }
657159b3361Sopenharmony_ci#endif
658159b3361Sopenharmony_ci        if (global.snd_file == 0) {
659159b3361Sopenharmony_ci            global. music_in = open_wave_file(gfp, inPath, &enc_delay, &enc_padding);
660159b3361Sopenharmony_ci        }
661159b3361Sopenharmony_ci    }
662159b3361Sopenharmony_ci    initPcmBuffer(&global.pcm32, sizeof(int));
663159b3361Sopenharmony_ci    initPcmBuffer(&global.pcm16, sizeof(short));
664159b3361Sopenharmony_ci    setSkipStartAndEnd(gfp, enc_delay, enc_padding);
665159b3361Sopenharmony_ci    {
666159b3361Sopenharmony_ci        unsigned long n = lame_get_num_samples(gfp);
667159b3361Sopenharmony_ci        if (n != MAX_U_32_NUM) {
668159b3361Sopenharmony_ci            unsigned long const discard = global.pcm32.skip_start + global.pcm32.skip_end;
669159b3361Sopenharmony_ci            lame_set_num_samples(gfp, n > discard ? n - discard : 0);
670159b3361Sopenharmony_ci        }
671159b3361Sopenharmony_ci    }
672159b3361Sopenharmony_ci    return (global.snd_file != NULL || global.music_in != NULL) ? 1 : -1;
673159b3361Sopenharmony_ci}
674159b3361Sopenharmony_ci
675159b3361Sopenharmony_ciint
676159b3361Sopenharmony_cisamples_to_skip_at_start(void)
677159b3361Sopenharmony_ci{
678159b3361Sopenharmony_ci    return global.pcm32.skip_start;
679159b3361Sopenharmony_ci}
680159b3361Sopenharmony_ci
681159b3361Sopenharmony_ciint
682159b3361Sopenharmony_cisamples_to_skip_at_end(void)
683159b3361Sopenharmony_ci{
684159b3361Sopenharmony_ci    return global.pcm32.skip_end;
685159b3361Sopenharmony_ci}
686159b3361Sopenharmony_ci
687159b3361Sopenharmony_civoid
688159b3361Sopenharmony_ciclose_infile(void)
689159b3361Sopenharmony_ci{
690159b3361Sopenharmony_ci#if defined(HAVE_MPGLIB) || defined(HAVE_MPG123)
691159b3361Sopenharmony_ci    if (global.hip != 0) {
692159b3361Sopenharmony_ci        hip_decode_exit(global.hip); /* release mp3decoder memory */
693159b3361Sopenharmony_ci        global. hip = 0;
694159b3361Sopenharmony_ci    }
695159b3361Sopenharmony_ci#endif
696159b3361Sopenharmony_ci    close_input_file(global.music_in);
697159b3361Sopenharmony_ci#ifdef LIBSNDFILE
698159b3361Sopenharmony_ci    if (global.snd_file) {
699159b3361Sopenharmony_ci        if (sf_close(global.snd_file) != 0) {
700159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
701159b3361Sopenharmony_ci                error_printf("Could not close sound file \n");
702159b3361Sopenharmony_ci            }
703159b3361Sopenharmony_ci        }
704159b3361Sopenharmony_ci        global. snd_file = 0;
705159b3361Sopenharmony_ci    }
706159b3361Sopenharmony_ci#endif
707159b3361Sopenharmony_ci    freePcmBuffer(&global.pcm32);
708159b3361Sopenharmony_ci    freePcmBuffer(&global.pcm16);
709159b3361Sopenharmony_ci    global. music_in = 0;
710159b3361Sopenharmony_ci    free(global.in_id3v2_tag);
711159b3361Sopenharmony_ci    global.in_id3v2_tag = 0;
712159b3361Sopenharmony_ci    global.in_id3v2_size = 0;
713159b3361Sopenharmony_ci}
714159b3361Sopenharmony_ci
715159b3361Sopenharmony_ci
716159b3361Sopenharmony_cistatic int
717159b3361Sopenharmony_ci        get_audio_common(lame_t gfp, int buffer[2][1152], short buffer16[2][1152]);
718159b3361Sopenharmony_ci
719159b3361Sopenharmony_ci/************************************************************************
720159b3361Sopenharmony_ci*
721159b3361Sopenharmony_ci* get_audio()
722159b3361Sopenharmony_ci*
723159b3361Sopenharmony_ci* PURPOSE:  reads a frame of audio data from a file to the buffer,
724159b3361Sopenharmony_ci*   aligns the data for future processing, and separates the
725159b3361Sopenharmony_ci*   left and right channels
726159b3361Sopenharmony_ci*
727159b3361Sopenharmony_ci************************************************************************/
728159b3361Sopenharmony_ciint
729159b3361Sopenharmony_ciget_audio(lame_t gfp, int buffer[2][1152])
730159b3361Sopenharmony_ci{
731159b3361Sopenharmony_ci    int     used = 0, read = 0;
732159b3361Sopenharmony_ci    do {
733159b3361Sopenharmony_ci        read = get_audio_common(gfp, buffer, NULL);
734159b3361Sopenharmony_ci        used = addPcmBuffer(&global.pcm32, buffer[0], buffer[1], read);
735159b3361Sopenharmony_ci    } while (used <= 0 && read > 0);
736159b3361Sopenharmony_ci    if (read < 0) {
737159b3361Sopenharmony_ci        return read;
738159b3361Sopenharmony_ci    }
739159b3361Sopenharmony_ci    if (global_reader.swap_channel == 0)
740159b3361Sopenharmony_ci        return takePcmBuffer(&global.pcm32, buffer[0], buffer[1], used, 1152);
741159b3361Sopenharmony_ci    else
742159b3361Sopenharmony_ci        return takePcmBuffer(&global.pcm32, buffer[1], buffer[0], used, 1152);
743159b3361Sopenharmony_ci}
744159b3361Sopenharmony_ci
745159b3361Sopenharmony_ci/*
746159b3361Sopenharmony_ci  get_audio16 - behave as the original get_audio function, with a limited
747159b3361Sopenharmony_ci                16 bit per sample output
748159b3361Sopenharmony_ci*/
749159b3361Sopenharmony_ciint
750159b3361Sopenharmony_ciget_audio16(lame_t gfp, short buffer[2][1152])
751159b3361Sopenharmony_ci{
752159b3361Sopenharmony_ci    int     used = 0, read = 0;
753159b3361Sopenharmony_ci    do {
754159b3361Sopenharmony_ci        read = get_audio_common(gfp, NULL, buffer);
755159b3361Sopenharmony_ci        used = addPcmBuffer(&global.pcm16, buffer[0], buffer[1], read);
756159b3361Sopenharmony_ci    } while (used <= 0 && read > 0);
757159b3361Sopenharmony_ci    if (read < 0) {
758159b3361Sopenharmony_ci        return read;
759159b3361Sopenharmony_ci    }
760159b3361Sopenharmony_ci    if (global_reader.swap_channel == 0)
761159b3361Sopenharmony_ci        return takePcmBuffer(&global.pcm16, buffer[0], buffer[1], used, 1152);
762159b3361Sopenharmony_ci    else
763159b3361Sopenharmony_ci        return takePcmBuffer(&global.pcm16, buffer[1], buffer[0], used, 1152);
764159b3361Sopenharmony_ci}
765159b3361Sopenharmony_ci
766159b3361Sopenharmony_ci/************************************************************************
767159b3361Sopenharmony_ci  get_audio_common - central functionality of get_audio*
768159b3361Sopenharmony_ci    in: gfp
769159b3361Sopenharmony_ci        buffer    output to the int buffer or 16-bit buffer
770159b3361Sopenharmony_ci   out: buffer    int output    (if buffer != NULL)
771159b3361Sopenharmony_ci        buffer16  16-bit output (if buffer == NULL)
772159b3361Sopenharmony_cireturns: samples read
773159b3361Sopenharmony_cinote: either buffer or buffer16 must be allocated upon call
774159b3361Sopenharmony_ci*/
775159b3361Sopenharmony_cistatic int
776159b3361Sopenharmony_ciget_audio_common(lame_t gfp, int buffer[2][1152], short buffer16[2][1152])
777159b3361Sopenharmony_ci{
778159b3361Sopenharmony_ci    const int num_channels = lame_get_num_channels(gfp);
779159b3361Sopenharmony_ci    const int framesize = lame_get_framesize(gfp);
780159b3361Sopenharmony_ci    int     insamp[2 * 1152];
781159b3361Sopenharmony_ci    short   buf_tmp16[2][1152];
782159b3361Sopenharmony_ci    int     samples_read;
783159b3361Sopenharmony_ci    int     samples_to_read;
784159b3361Sopenharmony_ci    int     i;
785159b3361Sopenharmony_ci
786159b3361Sopenharmony_ci    /* sanity checks, that's what we expect to be true */
787159b3361Sopenharmony_ci    if ((num_channels < 1 || 2 < num_channels)
788159b3361Sopenharmony_ci      ||(framesize < 1 || 1152 < framesize)) {
789159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
790159b3361Sopenharmony_ci            error_printf("Error: internal problem!\n");
791159b3361Sopenharmony_ci        }
792159b3361Sopenharmony_ci        return -1;
793159b3361Sopenharmony_ci    }
794159b3361Sopenharmony_ci
795159b3361Sopenharmony_ci    /*
796159b3361Sopenharmony_ci     * NOTE: LAME can now handle arbritray size input data packets,
797159b3361Sopenharmony_ci     * so there is no reason to read the input data in chuncks of
798159b3361Sopenharmony_ci     * size "framesize".  EXCEPT:  the LAME graphical frame analyzer
799159b3361Sopenharmony_ci     * will get out of sync if we read more than framesize worth of data.
800159b3361Sopenharmony_ci     */
801159b3361Sopenharmony_ci
802159b3361Sopenharmony_ci    samples_to_read = framesize;
803159b3361Sopenharmony_ci
804159b3361Sopenharmony_ci    /* if this flag has been set, then we are carefull to read
805159b3361Sopenharmony_ci     * exactly num_samples and no more.  This is useful for .wav and .aiff
806159b3361Sopenharmony_ci     * files which have id3 or other tags at the end.  Note that if you
807159b3361Sopenharmony_ci     * are using LIBSNDFILE, this is not necessary
808159b3361Sopenharmony_ci     */
809159b3361Sopenharmony_ci    if (global.count_samples_carefully) {
810159b3361Sopenharmony_ci        unsigned int tmp_num_samples, remaining;
811159b3361Sopenharmony_ci        /* get num_samples */
812159b3361Sopenharmony_ci        if (is_mpeg_file_format(global_reader.input_format)) {
813159b3361Sopenharmony_ci            tmp_num_samples = global_decoder.mp3input_data.nsamp;
814159b3361Sopenharmony_ci        }
815159b3361Sopenharmony_ci        else {
816159b3361Sopenharmony_ci            tmp_num_samples = lame_get_num_samples(gfp);
817159b3361Sopenharmony_ci        }
818159b3361Sopenharmony_ci        if (global.num_samples_read < tmp_num_samples) {
819159b3361Sopenharmony_ci            remaining = tmp_num_samples - global.num_samples_read;
820159b3361Sopenharmony_ci        }
821159b3361Sopenharmony_ci        else {
822159b3361Sopenharmony_ci            remaining = 0;
823159b3361Sopenharmony_ci        }
824159b3361Sopenharmony_ci        if (remaining < (unsigned int) framesize && 0 != tmp_num_samples)
825159b3361Sopenharmony_ci            /* in case the input is a FIFO (at least it's reproducible with
826159b3361Sopenharmony_ci               a FIFO) tmp_num_samples may be 0 and therefore remaining
827159b3361Sopenharmony_ci               would be 0, but we need to read some samples, so don't
828159b3361Sopenharmony_ci               change samples_to_read to the wrong value in this case */
829159b3361Sopenharmony_ci            samples_to_read = remaining;
830159b3361Sopenharmony_ci    }
831159b3361Sopenharmony_ci
832159b3361Sopenharmony_ci    if (is_mpeg_file_format(global_reader.input_format)) {
833159b3361Sopenharmony_ci        if (buffer != NULL)
834159b3361Sopenharmony_ci            samples_read = read_samples_mp3(gfp, global.music_in, buf_tmp16);
835159b3361Sopenharmony_ci        else
836159b3361Sopenharmony_ci            samples_read = read_samples_mp3(gfp, global.music_in, buffer16);
837159b3361Sopenharmony_ci        if (samples_read < 0) {
838159b3361Sopenharmony_ci            return samples_read;
839159b3361Sopenharmony_ci        }
840159b3361Sopenharmony_ci    }
841159b3361Sopenharmony_ci    else {
842159b3361Sopenharmony_ci        int    *p;
843159b3361Sopenharmony_ci        if (global.snd_file) {
844159b3361Sopenharmony_ci#ifdef LIBSNDFILE
845159b3361Sopenharmony_ci            samples_read = sf_read_int(global.snd_file, insamp, num_channels * samples_to_read);
846159b3361Sopenharmony_ci#else
847159b3361Sopenharmony_ci            samples_read = 0;
848159b3361Sopenharmony_ci#endif
849159b3361Sopenharmony_ci        }
850159b3361Sopenharmony_ci        else {
851159b3361Sopenharmony_ci            samples_read =
852159b3361Sopenharmony_ci                read_samples_pcm(global.music_in, insamp, num_channels * samples_to_read);
853159b3361Sopenharmony_ci        }
854159b3361Sopenharmony_ci        if (samples_read < 0) {
855159b3361Sopenharmony_ci            return samples_read;
856159b3361Sopenharmony_ci        }
857159b3361Sopenharmony_ci        p = insamp + samples_read;
858159b3361Sopenharmony_ci        samples_read /= num_channels;
859159b3361Sopenharmony_ci        if (buffer != NULL) { /* output to int buffer */
860159b3361Sopenharmony_ci            if (num_channels == 2) {
861159b3361Sopenharmony_ci                for (i = samples_read; --i >= 0;) {
862159b3361Sopenharmony_ci                    buffer[1][i] = *--p;
863159b3361Sopenharmony_ci                    buffer[0][i] = *--p;
864159b3361Sopenharmony_ci                }
865159b3361Sopenharmony_ci            }
866159b3361Sopenharmony_ci            else if (num_channels == 1) {
867159b3361Sopenharmony_ci                memset(buffer[1], 0, samples_read * sizeof(int));
868159b3361Sopenharmony_ci                for (i = samples_read; --i >= 0;) {
869159b3361Sopenharmony_ci                    buffer[0][i] = *--p;
870159b3361Sopenharmony_ci                }
871159b3361Sopenharmony_ci            }
872159b3361Sopenharmony_ci            else
873159b3361Sopenharmony_ci                assert(0);
874159b3361Sopenharmony_ci        }
875159b3361Sopenharmony_ci        else {          /* convert from int; output to 16-bit buffer */
876159b3361Sopenharmony_ci            if (num_channels == 2) {
877159b3361Sopenharmony_ci                for (i = samples_read; --i >= 0;) {
878159b3361Sopenharmony_ci                    buffer16[1][i] = *--p >> (8 * sizeof(int) - 16);
879159b3361Sopenharmony_ci                    buffer16[0][i] = *--p >> (8 * sizeof(int) - 16);
880159b3361Sopenharmony_ci                }
881159b3361Sopenharmony_ci            }
882159b3361Sopenharmony_ci            else if (num_channels == 1) {
883159b3361Sopenharmony_ci                memset(buffer16[1], 0, samples_read * sizeof(short));
884159b3361Sopenharmony_ci                for (i = samples_read; --i >= 0;) {
885159b3361Sopenharmony_ci                    buffer16[0][i] = *--p >> (8 * sizeof(int) - 16);
886159b3361Sopenharmony_ci                }
887159b3361Sopenharmony_ci            }
888159b3361Sopenharmony_ci            else
889159b3361Sopenharmony_ci                assert(0);
890159b3361Sopenharmony_ci        }
891159b3361Sopenharmony_ci    }
892159b3361Sopenharmony_ci
893159b3361Sopenharmony_ci    /* LAME mp3 output 16bit -  convert to int, if necessary */
894159b3361Sopenharmony_ci    if (is_mpeg_file_format(global_reader.input_format)) {
895159b3361Sopenharmony_ci        if (buffer != NULL) {
896159b3361Sopenharmony_ci            for (i = samples_read; --i >= 0;)
897159b3361Sopenharmony_ci                buffer[0][i] = buf_tmp16[0][i] << (8 * sizeof(int) - 16);
898159b3361Sopenharmony_ci            if (num_channels == 2) {
899159b3361Sopenharmony_ci                for (i = samples_read; --i >= 0;)
900159b3361Sopenharmony_ci                    buffer[1][i] = buf_tmp16[1][i] << (8 * sizeof(int) - 16);
901159b3361Sopenharmony_ci            }
902159b3361Sopenharmony_ci            else if (num_channels == 1) {
903159b3361Sopenharmony_ci                memset(buffer[1], 0, samples_read * sizeof(int));
904159b3361Sopenharmony_ci            }
905159b3361Sopenharmony_ci            else
906159b3361Sopenharmony_ci                assert(0);
907159b3361Sopenharmony_ci        }
908159b3361Sopenharmony_ci    }
909159b3361Sopenharmony_ci
910159b3361Sopenharmony_ci
911159b3361Sopenharmony_ci    /* if ... then it is considered infinitely long.
912159b3361Sopenharmony_ci       Don't count the samples */
913159b3361Sopenharmony_ci    if (global.count_samples_carefully)
914159b3361Sopenharmony_ci        global. num_samples_read += samples_read;
915159b3361Sopenharmony_ci
916159b3361Sopenharmony_ci    return samples_read;
917159b3361Sopenharmony_ci}
918159b3361Sopenharmony_ci
919159b3361Sopenharmony_ci
920159b3361Sopenharmony_ci
921159b3361Sopenharmony_cistatic int
922159b3361Sopenharmony_ciread_samples_mp3(lame_t gfp, FILE * musicin, short int mpg123pcm[2][1152])
923159b3361Sopenharmony_ci{
924159b3361Sopenharmony_ci    int     out;
925159b3361Sopenharmony_ci#ifdef HAVE_MPG123
926159b3361Sopenharmony_ci    short int *outbuf;
927159b3361Sopenharmony_ci    size_t outbytes;
928159b3361Sopenharmony_ci#endif
929159b3361Sopenharmony_ci#if defined(AMIGA_MPEGA)  ||  defined(HAVE_MPGLIB) || defined(HAVE_MPG123)
930159b3361Sopenharmony_ci    int     samplerate;
931159b3361Sopenharmony_ci    static const char type_name[] = "MP3 file";
932159b3361Sopenharmony_ci
933159b3361Sopenharmony_ci#ifdef HAVE_MPG123
934159b3361Sopenharmony_ci    /* Need to deinterleave so rather use mpg123_decode_frame() to decode the
935159b3361Sopenharmony_ci       current frame and deinterleave from the internal buffer. */
936159b3361Sopenharmony_ci    out = mpg123_decode_frame(global.hip->mh, NULL, (unsigned char**)&outbuf, &outbytes);
937159b3361Sopenharmony_ci    if (out != MPG123_OK && out != MPG123_DONE)
938159b3361Sopenharmony_ci    {
939159b3361Sopenharmony_ci        if (out == MPG123_NEW_FORMAT)
940159b3361Sopenharmony_ci        {
941159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
942159b3361Sopenharmony_ci                error_printf("Error: format changed in %s - not supported\n",
943159b3361Sopenharmony_ci                    type_name);
944159b3361Sopenharmony_ci            }
945159b3361Sopenharmony_ci        }
946159b3361Sopenharmony_ci        return -1;
947159b3361Sopenharmony_ci    }
948159b3361Sopenharmony_ci    out = outbytes/(sizeof(short)*global_decoder.mp3input_data.stereo);
949159b3361Sopenharmony_ci    if (global_decoder.mp3input_data.stereo == 2) {
950159b3361Sopenharmony_ci        int i;
951159b3361Sopenharmony_ci        for (i=0; i<out; ++i) {
952159b3361Sopenharmony_ci            mpg123pcm[0][i] = *outbuf++;
953159b3361Sopenharmony_ci            mpg123pcm[1][i] = *outbuf++;
954159b3361Sopenharmony_ci        }
955159b3361Sopenharmony_ci    }
956159b3361Sopenharmony_ci    else
957159b3361Sopenharmony_ci        memcpy(mpg123pcm[0], outbuf, sizeof(short)*out);
958159b3361Sopenharmony_ci    if(global.hip->pinfo)
959159b3361Sopenharmony_ci        hip_finish_pinfo(global.hip);
960159b3361Sopenharmony_ci#else
961159b3361Sopenharmony_ci    out = lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1], &global_decoder.mp3input_data);
962159b3361Sopenharmony_ci    /*
963159b3361Sopenharmony_ci     * out < 0:  error, probably EOF
964159b3361Sopenharmony_ci     * out = 0:  not possible with lame_decode_fromfile() ???
965159b3361Sopenharmony_ci     * out > 0:  number of output samples
966159b3361Sopenharmony_ci     */
967159b3361Sopenharmony_ci    if (out < 0) {
968159b3361Sopenharmony_ci        memset(mpg123pcm, 0, sizeof(**mpg123pcm) * 2 * 1152);
969159b3361Sopenharmony_ci        return 0;
970159b3361Sopenharmony_ci    }
971159b3361Sopenharmony_ci
972159b3361Sopenharmony_ci    if (lame_get_num_channels(gfp) != global_decoder.mp3input_data.stereo) {
973159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
974159b3361Sopenharmony_ci            error_printf("Error: number of channels has changed in %s - not supported\n",
975159b3361Sopenharmony_ci                         type_name);
976159b3361Sopenharmony_ci        }
977159b3361Sopenharmony_ci        out = -1;
978159b3361Sopenharmony_ci    }
979159b3361Sopenharmony_ci    samplerate = global_reader.input_samplerate;
980159b3361Sopenharmony_ci    if (samplerate == 0) {
981159b3361Sopenharmony_ci        samplerate = global_decoder.mp3input_data.samplerate;
982159b3361Sopenharmony_ci    }
983159b3361Sopenharmony_ci    if (lame_get_in_samplerate(gfp) != samplerate) {
984159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
985159b3361Sopenharmony_ci            error_printf("Error: sample frequency has changed in %s - not supported\n", type_name);
986159b3361Sopenharmony_ci        }
987159b3361Sopenharmony_ci        out = -1;
988159b3361Sopenharmony_ci    }
989159b3361Sopenharmony_ci#endif
990159b3361Sopenharmony_ci#else
991159b3361Sopenharmony_ci    out = -1;
992159b3361Sopenharmony_ci#endif
993159b3361Sopenharmony_ci    return out;
994159b3361Sopenharmony_ci}
995159b3361Sopenharmony_ci
996159b3361Sopenharmony_cistatic
997159b3361Sopenharmony_ciint set_input_num_channels(lame_t gfp, int num_channels)
998159b3361Sopenharmony_ci{
999159b3361Sopenharmony_ci    if (gfp) {
1000159b3361Sopenharmony_ci        if (-1 == lame_set_num_channels(gfp, num_channels)) {
1001159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1002159b3361Sopenharmony_ci                error_printf("Unsupported number of channels: %d\n", num_channels);
1003159b3361Sopenharmony_ci            }
1004159b3361Sopenharmony_ci            return 0;
1005159b3361Sopenharmony_ci        }
1006159b3361Sopenharmony_ci    }
1007159b3361Sopenharmony_ci    return 1;
1008159b3361Sopenharmony_ci}
1009159b3361Sopenharmony_ci
1010159b3361Sopenharmony_cistatic
1011159b3361Sopenharmony_ciint set_input_samplerate(lame_t gfp, int input_samplerate)
1012159b3361Sopenharmony_ci{
1013159b3361Sopenharmony_ci    if (gfp) {
1014159b3361Sopenharmony_ci        int sr = global_reader.input_samplerate;
1015159b3361Sopenharmony_ci        if (sr == 0) sr = input_samplerate;
1016159b3361Sopenharmony_ci        if (-1 == lame_set_in_samplerate(gfp, sr)) {
1017159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1018159b3361Sopenharmony_ci                error_printf("Unsupported sample rate: %d\n", sr);
1019159b3361Sopenharmony_ci            }
1020159b3361Sopenharmony_ci            return 0;
1021159b3361Sopenharmony_ci        }
1022159b3361Sopenharmony_ci    }
1023159b3361Sopenharmony_ci    return 1;
1024159b3361Sopenharmony_ci}
1025159b3361Sopenharmony_ci
1026159b3361Sopenharmony_ciint
1027159b3361Sopenharmony_ciWriteWaveHeader(FILE * const fp, int pcmbytes, int freq, int channels, int bits)
1028159b3361Sopenharmony_ci{
1029159b3361Sopenharmony_ci    int     bytes = (bits + 7) / 8;
1030159b3361Sopenharmony_ci
1031159b3361Sopenharmony_ci    /* quick and dirty, but documented */
1032159b3361Sopenharmony_ci    fwrite("RIFF", 1, 4, fp); /* label */
1033159b3361Sopenharmony_ci    write_32_bits_low_high(fp, pcmbytes + 44 - 8); /* length in bytes without header */
1034159b3361Sopenharmony_ci    fwrite("WAVEfmt ", 2, 4, fp); /* 2 labels */
1035159b3361Sopenharmony_ci    write_32_bits_low_high(fp, 2 + 2 + 4 + 4 + 2 + 2); /* length of PCM format declaration area */
1036159b3361Sopenharmony_ci    write_16_bits_low_high(fp, 1); /* is PCM? */
1037159b3361Sopenharmony_ci    write_16_bits_low_high(fp, channels); /* number of channels */
1038159b3361Sopenharmony_ci    write_32_bits_low_high(fp, freq); /* sample frequency in [Hz] */
1039159b3361Sopenharmony_ci    write_32_bits_low_high(fp, freq * channels * bytes); /* bytes per second */
1040159b3361Sopenharmony_ci    write_16_bits_low_high(fp, channels * bytes); /* bytes per sample time */
1041159b3361Sopenharmony_ci    write_16_bits_low_high(fp, bits); /* bits per sample */
1042159b3361Sopenharmony_ci    fwrite("data", 1, 4, fp); /* label */
1043159b3361Sopenharmony_ci    write_32_bits_low_high(fp, pcmbytes); /* length in bytes of raw PCM data */
1044159b3361Sopenharmony_ci
1045159b3361Sopenharmony_ci    return ferror(fp) ? -1 : 0;
1046159b3361Sopenharmony_ci}
1047159b3361Sopenharmony_ci
1048159b3361Sopenharmony_ci
1049159b3361Sopenharmony_ci
1050159b3361Sopenharmony_ci
1051159b3361Sopenharmony_ci#if defined(LIBSNDFILE)
1052159b3361Sopenharmony_ci
1053159b3361Sopenharmony_ciextern SNDFILE *sf_wchar_open(wchar_t const *wpath, int mode, SF_INFO * sfinfo);
1054159b3361Sopenharmony_ci
1055159b3361Sopenharmony_cistatic SNDFILE *
1056159b3361Sopenharmony_ciopen_snd_file(lame_t gfp, char const *inPath)
1057159b3361Sopenharmony_ci{
1058159b3361Sopenharmony_ci    char const *lpszFileName = inPath;
1059159b3361Sopenharmony_ci    SNDFILE *gs_pSndFileIn = NULL;
1060159b3361Sopenharmony_ci    SF_INFO gs_wfInfo;
1061159b3361Sopenharmony_ci
1062159b3361Sopenharmony_ci    {
1063159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__)
1064159b3361Sopenharmony_ci        wchar_t *file_name = utf8ToUnicode(lpszFileName);
1065159b3361Sopenharmony_ci#endif
1066159b3361Sopenharmony_ci        /* Try to open the sound file */
1067159b3361Sopenharmony_ci        memset(&gs_wfInfo, 0, sizeof(gs_wfInfo));
1068159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__)
1069159b3361Sopenharmony_ci        gs_pSndFileIn = sf_wchar_open(file_name, SFM_READ, &gs_wfInfo);
1070159b3361Sopenharmony_ci#else
1071159b3361Sopenharmony_ci        gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo);
1072159b3361Sopenharmony_ci#endif
1073159b3361Sopenharmony_ci
1074159b3361Sopenharmony_ci        if (gs_pSndFileIn == NULL) {
1075159b3361Sopenharmony_ci            if (global_raw_pcm.in_signed == 0 && global_raw_pcm.in_bitwidth != 8) {
1076159b3361Sopenharmony_ci                error_printf("Unsigned input only supported with bitwidth 8\n");
1077159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__)
1078159b3361Sopenharmony_ci                free(file_name);
1079159b3361Sopenharmony_ci#endif
1080159b3361Sopenharmony_ci                return 0;
1081159b3361Sopenharmony_ci            }
1082159b3361Sopenharmony_ci            /* set some defaults incase input is raw PCM */
1083159b3361Sopenharmony_ci            gs_wfInfo.seekable = (global_reader.input_format != sf_raw); /* if user specified -r, set to not seekable */
1084159b3361Sopenharmony_ci            gs_wfInfo.samplerate = lame_get_in_samplerate(gfp);
1085159b3361Sopenharmony_ci            gs_wfInfo.channels = lame_get_num_channels(gfp);
1086159b3361Sopenharmony_ci            gs_wfInfo.format = SF_FORMAT_RAW;
1087159b3361Sopenharmony_ci            if ((global_raw_pcm.in_endian == ByteOrderLittleEndian) ^ (global_reader.swapbytes !=
1088159b3361Sopenharmony_ci                                                                       0)) {
1089159b3361Sopenharmony_ci                gs_wfInfo.format |= SF_ENDIAN_LITTLE;
1090159b3361Sopenharmony_ci            }
1091159b3361Sopenharmony_ci            else {
1092159b3361Sopenharmony_ci                gs_wfInfo.format |= SF_ENDIAN_BIG;
1093159b3361Sopenharmony_ci            }
1094159b3361Sopenharmony_ci            switch (global_raw_pcm.in_bitwidth) {
1095159b3361Sopenharmony_ci            case 8:
1096159b3361Sopenharmony_ci                gs_wfInfo.format |=
1097159b3361Sopenharmony_ci                    global_raw_pcm.in_signed == 0 ? SF_FORMAT_PCM_U8 : SF_FORMAT_PCM_S8;
1098159b3361Sopenharmony_ci                break;
1099159b3361Sopenharmony_ci            case 16:
1100159b3361Sopenharmony_ci                gs_wfInfo.format |= SF_FORMAT_PCM_16;
1101159b3361Sopenharmony_ci                break;
1102159b3361Sopenharmony_ci            case 24:
1103159b3361Sopenharmony_ci                gs_wfInfo.format |= SF_FORMAT_PCM_24;
1104159b3361Sopenharmony_ci                break;
1105159b3361Sopenharmony_ci            case 32:
1106159b3361Sopenharmony_ci                gs_wfInfo.format |= SF_FORMAT_PCM_32;
1107159b3361Sopenharmony_ci                break;
1108159b3361Sopenharmony_ci            default:
1109159b3361Sopenharmony_ci                break;
1110159b3361Sopenharmony_ci            }
1111159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__)
1112159b3361Sopenharmony_ci            gs_pSndFileIn = sf_wchar_open(file_name, SFM_READ, &gs_wfInfo);
1113159b3361Sopenharmony_ci#else
1114159b3361Sopenharmony_ci            gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo);
1115159b3361Sopenharmony_ci#endif
1116159b3361Sopenharmony_ci        }
1117159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__)
1118159b3361Sopenharmony_ci        free(file_name);
1119159b3361Sopenharmony_ci#endif
1120159b3361Sopenharmony_ci
1121159b3361Sopenharmony_ci        /* Check result */
1122159b3361Sopenharmony_ci        if (gs_pSndFileIn == NULL) {
1123159b3361Sopenharmony_ci            sf_perror(gs_pSndFileIn);
1124159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1125159b3361Sopenharmony_ci                error_printf("Could not open sound file \"%s\".\n", lpszFileName);
1126159b3361Sopenharmony_ci            }
1127159b3361Sopenharmony_ci            return 0;
1128159b3361Sopenharmony_ci        }
1129159b3361Sopenharmony_ci        sf_command(gs_pSndFileIn, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
1130159b3361Sopenharmony_ci
1131159b3361Sopenharmony_ci        if ((gs_wfInfo.format & SF_FORMAT_RAW) == SF_FORMAT_RAW) {
1132159b3361Sopenharmony_ci            global_reader.input_format = sf_raw;
1133159b3361Sopenharmony_ci        }
1134159b3361Sopenharmony_ci
1135159b3361Sopenharmony_ci#ifdef _DEBUG_SND_FILE
1136159b3361Sopenharmony_ci        printf("\n\nSF_INFO structure\n");
1137159b3361Sopenharmony_ci        printf("samplerate        :%d\n", gs_wfInfo.samplerate);
1138159b3361Sopenharmony_ci        printf("samples           :%d\n", gs_wfInfo.frames);
1139159b3361Sopenharmony_ci        printf("channels          :%d\n", gs_wfInfo.channels);
1140159b3361Sopenharmony_ci        printf("format            :");
1141159b3361Sopenharmony_ci
1142159b3361Sopenharmony_ci        /* new formats from sbellon@sbellon.de  1/2000 */
1143159b3361Sopenharmony_ci
1144159b3361Sopenharmony_ci        switch (gs_wfInfo.format & SF_FORMAT_TYPEMASK) {
1145159b3361Sopenharmony_ci        case SF_FORMAT_WAV:
1146159b3361Sopenharmony_ci            printf("Microsoft WAV format (big endian). ");
1147159b3361Sopenharmony_ci            break;
1148159b3361Sopenharmony_ci        case SF_FORMAT_AIFF:
1149159b3361Sopenharmony_ci            printf("Apple/SGI AIFF format (little endian). ");
1150159b3361Sopenharmony_ci            break;
1151159b3361Sopenharmony_ci        case SF_FORMAT_AU:
1152159b3361Sopenharmony_ci            printf("Sun/NeXT AU format (big endian). ");
1153159b3361Sopenharmony_ci            break;
1154159b3361Sopenharmony_ci            /*
1155159b3361Sopenharmony_ci               case SF_FORMAT_AULE:
1156159b3361Sopenharmony_ci               DEBUGF("DEC AU format (little endian). ");
1157159b3361Sopenharmony_ci               break;
1158159b3361Sopenharmony_ci             */
1159159b3361Sopenharmony_ci        case SF_FORMAT_RAW:
1160159b3361Sopenharmony_ci            printf("RAW PCM data. ");
1161159b3361Sopenharmony_ci            break;
1162159b3361Sopenharmony_ci        case SF_FORMAT_PAF:
1163159b3361Sopenharmony_ci            printf("Ensoniq PARIS file format. ");
1164159b3361Sopenharmony_ci            break;
1165159b3361Sopenharmony_ci        case SF_FORMAT_SVX:
1166159b3361Sopenharmony_ci            printf("Amiga IFF / SVX8 / SV16 format. ");
1167159b3361Sopenharmony_ci            break;
1168159b3361Sopenharmony_ci        case SF_FORMAT_NIST:
1169159b3361Sopenharmony_ci            printf("Sphere NIST format. ");
1170159b3361Sopenharmony_ci            break;
1171159b3361Sopenharmony_ci        default:
1172159b3361Sopenharmony_ci            assert(0);
1173159b3361Sopenharmony_ci            break;
1174159b3361Sopenharmony_ci        }
1175159b3361Sopenharmony_ci
1176159b3361Sopenharmony_ci        switch (gs_wfInfo.format & SF_FORMAT_SUBMASK) {
1177159b3361Sopenharmony_ci            /*
1178159b3361Sopenharmony_ci               case SF_FORMAT_PCM:
1179159b3361Sopenharmony_ci               DEBUGF("PCM data in 8, 16, 24 or 32 bits.");
1180159b3361Sopenharmony_ci               break;
1181159b3361Sopenharmony_ci             */
1182159b3361Sopenharmony_ci        case SF_FORMAT_FLOAT:
1183159b3361Sopenharmony_ci            printf("32 bit Intel x86 floats.");
1184159b3361Sopenharmony_ci            break;
1185159b3361Sopenharmony_ci        case SF_FORMAT_ULAW:
1186159b3361Sopenharmony_ci            printf("U-Law encoded.");
1187159b3361Sopenharmony_ci            break;
1188159b3361Sopenharmony_ci        case SF_FORMAT_ALAW:
1189159b3361Sopenharmony_ci            printf("A-Law encoded.");
1190159b3361Sopenharmony_ci            break;
1191159b3361Sopenharmony_ci        case SF_FORMAT_IMA_ADPCM:
1192159b3361Sopenharmony_ci            printf("IMA ADPCM.");
1193159b3361Sopenharmony_ci            break;
1194159b3361Sopenharmony_ci        case SF_FORMAT_MS_ADPCM:
1195159b3361Sopenharmony_ci            printf("Microsoft ADPCM.");
1196159b3361Sopenharmony_ci            break;
1197159b3361Sopenharmony_ci            /*
1198159b3361Sopenharmony_ci               case SF_FORMAT_PCM_BE:
1199159b3361Sopenharmony_ci               DEBUGF("Big endian PCM data.");
1200159b3361Sopenharmony_ci               break;
1201159b3361Sopenharmony_ci               case SF_FORMAT_PCM_LE:
1202159b3361Sopenharmony_ci               DEBUGF("Little endian PCM data.");
1203159b3361Sopenharmony_ci               break;
1204159b3361Sopenharmony_ci             */
1205159b3361Sopenharmony_ci        case SF_FORMAT_PCM_S8:
1206159b3361Sopenharmony_ci            printf("Signed 8 bit PCM.");
1207159b3361Sopenharmony_ci            break;
1208159b3361Sopenharmony_ci        case SF_FORMAT_PCM_U8:
1209159b3361Sopenharmony_ci            printf("Unsigned 8 bit PCM.");
1210159b3361Sopenharmony_ci            break;
1211159b3361Sopenharmony_ci        case SF_FORMAT_PCM_16:
1212159b3361Sopenharmony_ci            printf("Signed 16 bit PCM.");
1213159b3361Sopenharmony_ci            break;
1214159b3361Sopenharmony_ci        case SF_FORMAT_PCM_24:
1215159b3361Sopenharmony_ci            printf("Signed 24 bit PCM.");
1216159b3361Sopenharmony_ci            break;
1217159b3361Sopenharmony_ci        case SF_FORMAT_PCM_32:
1218159b3361Sopenharmony_ci            printf("Signed 32 bit PCM.");
1219159b3361Sopenharmony_ci            break;
1220159b3361Sopenharmony_ci            /*
1221159b3361Sopenharmony_ci               case SF_FORMAT_SVX_FIB:
1222159b3361Sopenharmony_ci               DEBUGF("SVX Fibonacci Delta encoding.");
1223159b3361Sopenharmony_ci               break;
1224159b3361Sopenharmony_ci               case SF_FORMAT_SVX_EXP:
1225159b3361Sopenharmony_ci               DEBUGF("SVX Exponential Delta encoding.");
1226159b3361Sopenharmony_ci               break;
1227159b3361Sopenharmony_ci             */
1228159b3361Sopenharmony_ci        default:
1229159b3361Sopenharmony_ci            assert(0);
1230159b3361Sopenharmony_ci            break;
1231159b3361Sopenharmony_ci        }
1232159b3361Sopenharmony_ci
1233159b3361Sopenharmony_ci        printf("\n");
1234159b3361Sopenharmony_ci        printf("sections          :%d\n", gs_wfInfo.sections);
1235159b3361Sopenharmony_ci        printf("seekable          :%d\n", gs_wfInfo.seekable);
1236159b3361Sopenharmony_ci#endif
1237159b3361Sopenharmony_ci        /* Check result */
1238159b3361Sopenharmony_ci        if (gs_pSndFileIn == NULL) {
1239159b3361Sopenharmony_ci            sf_perror(gs_pSndFileIn);
1240159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1241159b3361Sopenharmony_ci                error_printf("Could not open sound file \"%s\".\n", lpszFileName);
1242159b3361Sopenharmony_ci            }
1243159b3361Sopenharmony_ci            return 0;
1244159b3361Sopenharmony_ci        }
1245159b3361Sopenharmony_ci
1246159b3361Sopenharmony_ci
1247159b3361Sopenharmony_ci        if(gs_wfInfo.frames >= 0 && gs_wfInfo.frames < (sf_count_t)(unsigned)MAX_U_32_NUM)
1248159b3361Sopenharmony_ci            (void) lame_set_num_samples(gfp, gs_wfInfo.frames);
1249159b3361Sopenharmony_ci        else
1250159b3361Sopenharmony_ci            (void) lame_set_num_samples(gfp, MAX_U_32_NUM);
1251159b3361Sopenharmony_ci        if (!set_input_num_channels(gfp, gs_wfInfo.channels)) {
1252159b3361Sopenharmony_ci            sf_close(gs_pSndFileIn);
1253159b3361Sopenharmony_ci            return 0;
1254159b3361Sopenharmony_ci        }
1255159b3361Sopenharmony_ci        if (!set_input_samplerate(gfp, gs_wfInfo.samplerate)) {
1256159b3361Sopenharmony_ci            sf_close(gs_pSndFileIn);
1257159b3361Sopenharmony_ci            return 0;
1258159b3361Sopenharmony_ci        }
1259159b3361Sopenharmony_ci        global. pcmbitwidth = 32;
1260159b3361Sopenharmony_ci    }
1261159b3361Sopenharmony_ci#if 0
1262159b3361Sopenharmony_ci    if (lame_get_num_samples(gfp) == MAX_U_32_NUM) {
1263159b3361Sopenharmony_ci        /* try to figure out num_samples */
1264159b3361Sopenharmony_ci        double const flen = lame_get_file_size(lpszFileName);
1265159b3361Sopenharmony_ci        if (flen >= 0) {
1266159b3361Sopenharmony_ci            /* try file size, assume 2 bytes per sample */
1267159b3361Sopenharmony_ci            lame_set_num_samples(gfp, flen / (2 * lame_get_num_channels(gfp)));
1268159b3361Sopenharmony_ci        }
1269159b3361Sopenharmony_ci    }
1270159b3361Sopenharmony_ci#endif
1271159b3361Sopenharmony_ci    return gs_pSndFileIn;
1272159b3361Sopenharmony_ci}
1273159b3361Sopenharmony_ci
1274159b3361Sopenharmony_ci#endif /* defined(LIBSNDFILE) */
1275159b3361Sopenharmony_ci
1276159b3361Sopenharmony_ci
1277159b3361Sopenharmony_ci
1278159b3361Sopenharmony_ci/************************************************************************
1279159b3361Sopenharmony_ciunpack_read_samples - read and unpack signed low-to-high byte or unsigned
1280159b3361Sopenharmony_ci                      single byte input. (used for read_samples function)
1281159b3361Sopenharmony_ci                      Output integers are stored in the native byte order
1282159b3361Sopenharmony_ci                      (little or big endian).  -jd
1283159b3361Sopenharmony_ci  in: samples_to_read
1284159b3361Sopenharmony_ci      bytes_per_sample
1285159b3361Sopenharmony_ci      swap_order    - set for high-to-low byte order input stream
1286159b3361Sopenharmony_ci i/o: pcm_in
1287159b3361Sopenharmony_ci out: sample_buffer  (must be allocated up to samples_to_read upon call)
1288159b3361Sopenharmony_cireturns: number of samples read
1289159b3361Sopenharmony_ci*/
1290159b3361Sopenharmony_cistatic int
1291159b3361Sopenharmony_ciunpack_read_samples(const int samples_to_read, const int bytes_per_sample,
1292159b3361Sopenharmony_ci                    const int swap_order, int *sample_buffer, FILE * pcm_in)
1293159b3361Sopenharmony_ci{
1294159b3361Sopenharmony_ci    int     samples_read;
1295159b3361Sopenharmony_ci    int     i;
1296159b3361Sopenharmony_ci    int    *op;              /* output pointer */
1297159b3361Sopenharmony_ci    unsigned char *ip = (unsigned char *) sample_buffer; /* input pointer */
1298159b3361Sopenharmony_ci    const int b = sizeof(int) * 8;
1299159b3361Sopenharmony_ci
1300159b3361Sopenharmony_ci    {
1301159b3361Sopenharmony_ci        size_t  samples_read_ = fread(sample_buffer, bytes_per_sample, samples_to_read, pcm_in);
1302159b3361Sopenharmony_ci        assert( samples_read_ <= INT_MAX );
1303159b3361Sopenharmony_ci        samples_read = (int) samples_read_;
1304159b3361Sopenharmony_ci    }
1305159b3361Sopenharmony_ci    op = sample_buffer + samples_read;
1306159b3361Sopenharmony_ci
1307159b3361Sopenharmony_ci#define GA_URS_IFLOOP( ga_urs_bps ) \
1308159b3361Sopenharmony_ci    if( bytes_per_sample == ga_urs_bps ) \
1309159b3361Sopenharmony_ci      for( i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >=0;)
1310159b3361Sopenharmony_ci
1311159b3361Sopenharmony_ci    if (swap_order == 0) {
1312159b3361Sopenharmony_ci        GA_URS_IFLOOP(1)
1313159b3361Sopenharmony_ci            * --op = ip[i] << (b - 8);
1314159b3361Sopenharmony_ci        GA_URS_IFLOOP(2)
1315159b3361Sopenharmony_ci            * --op = ip[i] << (b - 16) | ip[i + 1] << (b - 8);
1316159b3361Sopenharmony_ci        GA_URS_IFLOOP(3)
1317159b3361Sopenharmony_ci            * --op = ip[i] << (b - 24) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 8);
1318159b3361Sopenharmony_ci        GA_URS_IFLOOP(4)
1319159b3361Sopenharmony_ci            * --op =
1320159b3361Sopenharmony_ci            ip[i] << (b - 32) | ip[i + 1] << (b - 24) | ip[i + 2] << (b - 16) | ip[i + 3] << (b -
1321159b3361Sopenharmony_ci                                                                                              8);
1322159b3361Sopenharmony_ci    }
1323159b3361Sopenharmony_ci    else {
1324159b3361Sopenharmony_ci        GA_URS_IFLOOP(1)
1325159b3361Sopenharmony_ci            * --op = (ip[i] ^ 0x80) << (b - 8) | 0x7f << (b - 16); /* convert from unsigned */
1326159b3361Sopenharmony_ci        GA_URS_IFLOOP(2)
1327159b3361Sopenharmony_ci            * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16);
1328159b3361Sopenharmony_ci        GA_URS_IFLOOP(3)
1329159b3361Sopenharmony_ci            * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24);
1330159b3361Sopenharmony_ci        GA_URS_IFLOOP(4)
1331159b3361Sopenharmony_ci            * --op =
1332159b3361Sopenharmony_ci            ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24) | ip[i + 3] << (b -
1333159b3361Sopenharmony_ci                                                                                             32);
1334159b3361Sopenharmony_ci    }
1335159b3361Sopenharmony_ci#undef GA_URS_IFLOOP
1336159b3361Sopenharmony_ci    if (global.pcm_is_ieee_float) {
1337159b3361Sopenharmony_ci        ieee754_float32_t const m_max = INT_MAX;
1338159b3361Sopenharmony_ci        ieee754_float32_t const m_min = -(ieee754_float32_t) INT_MIN;
1339159b3361Sopenharmony_ci        ieee754_float32_t *x = (ieee754_float32_t *) sample_buffer;
1340159b3361Sopenharmony_ci        assert(sizeof(ieee754_float32_t) == sizeof(int));
1341159b3361Sopenharmony_ci        for (i = 0; i < samples_to_read; ++i) {
1342159b3361Sopenharmony_ci            ieee754_float32_t const u = x[i];
1343159b3361Sopenharmony_ci            int     v;
1344159b3361Sopenharmony_ci            if (u >= 1) {
1345159b3361Sopenharmony_ci                v = INT_MAX;
1346159b3361Sopenharmony_ci            }
1347159b3361Sopenharmony_ci            else if (u <= -1) {
1348159b3361Sopenharmony_ci                v = INT_MIN;
1349159b3361Sopenharmony_ci            }
1350159b3361Sopenharmony_ci            else if (u >= 0) {
1351159b3361Sopenharmony_ci                v = (int) (u * m_max + 0.5f);
1352159b3361Sopenharmony_ci            }
1353159b3361Sopenharmony_ci            else {
1354159b3361Sopenharmony_ci                v = (int) (u * m_min - 0.5f);
1355159b3361Sopenharmony_ci            }
1356159b3361Sopenharmony_ci            sample_buffer[i] = v;
1357159b3361Sopenharmony_ci        }
1358159b3361Sopenharmony_ci    }
1359159b3361Sopenharmony_ci    return (samples_read);
1360159b3361Sopenharmony_ci}
1361159b3361Sopenharmony_ci
1362159b3361Sopenharmony_ci
1363159b3361Sopenharmony_ci
1364159b3361Sopenharmony_ci/************************************************************************
1365159b3361Sopenharmony_ci*
1366159b3361Sopenharmony_ci* read_samples()
1367159b3361Sopenharmony_ci*
1368159b3361Sopenharmony_ci* PURPOSE:  reads the PCM samples from a file to the buffer
1369159b3361Sopenharmony_ci*
1370159b3361Sopenharmony_ci*  SEMANTICS:
1371159b3361Sopenharmony_ci* Reads #samples_read# number of shorts from #musicin# filepointer
1372159b3361Sopenharmony_ci* into #sample_buffer[]#.  Returns the number of samples read.
1373159b3361Sopenharmony_ci*
1374159b3361Sopenharmony_ci************************************************************************/
1375159b3361Sopenharmony_ci
1376159b3361Sopenharmony_cistatic int
1377159b3361Sopenharmony_ciread_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read)
1378159b3361Sopenharmony_ci{
1379159b3361Sopenharmony_ci    int     samples_read;
1380159b3361Sopenharmony_ci    int     bytes_per_sample = global.pcmbitwidth / 8;
1381159b3361Sopenharmony_ci    int     swap_byte_order; /* byte order of input stream */
1382159b3361Sopenharmony_ci
1383159b3361Sopenharmony_ci    switch (global.pcmbitwidth) {
1384159b3361Sopenharmony_ci    case 32:
1385159b3361Sopenharmony_ci    case 24:
1386159b3361Sopenharmony_ci    case 16:
1387159b3361Sopenharmony_ci        if (global_raw_pcm.in_signed == 0) {
1388159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1389159b3361Sopenharmony_ci                error_printf("Unsigned input only supported with bitwidth 8\n");
1390159b3361Sopenharmony_ci            }
1391159b3361Sopenharmony_ci            return -1;
1392159b3361Sopenharmony_ci        }
1393159b3361Sopenharmony_ci        swap_byte_order = (global_raw_pcm.in_endian != ByteOrderLittleEndian) ? 1 : 0;
1394159b3361Sopenharmony_ci        if (global.pcmswapbytes) {
1395159b3361Sopenharmony_ci            swap_byte_order = !swap_byte_order;
1396159b3361Sopenharmony_ci        }
1397159b3361Sopenharmony_ci        break;
1398159b3361Sopenharmony_ci
1399159b3361Sopenharmony_ci    case 8:
1400159b3361Sopenharmony_ci        swap_byte_order = global.pcm_is_unsigned_8bit;
1401159b3361Sopenharmony_ci        break;
1402159b3361Sopenharmony_ci
1403159b3361Sopenharmony_ci    default:
1404159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1405159b3361Sopenharmony_ci            error_printf("Only 8, 16, 24 and 32 bit input files supported \n");
1406159b3361Sopenharmony_ci        }
1407159b3361Sopenharmony_ci        return -1;
1408159b3361Sopenharmony_ci    }
1409159b3361Sopenharmony_ci    if (samples_to_read < 0 || samples_to_read > 2304) {
1410159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1411159b3361Sopenharmony_ci            error_printf("Error: unexpected number of samples to read: %d\n", samples_to_read);
1412159b3361Sopenharmony_ci        }
1413159b3361Sopenharmony_ci        return -1;
1414159b3361Sopenharmony_ci    }
1415159b3361Sopenharmony_ci    samples_read = unpack_read_samples(samples_to_read, bytes_per_sample, swap_byte_order,
1416159b3361Sopenharmony_ci                                       sample_buffer, musicin);
1417159b3361Sopenharmony_ci    if (ferror(musicin)) {
1418159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1419159b3361Sopenharmony_ci            error_printf("Error reading input file\n");
1420159b3361Sopenharmony_ci        }
1421159b3361Sopenharmony_ci        return -1;
1422159b3361Sopenharmony_ci    }
1423159b3361Sopenharmony_ci
1424159b3361Sopenharmony_ci    return samples_read;
1425159b3361Sopenharmony_ci}
1426159b3361Sopenharmony_ci
1427159b3361Sopenharmony_ci
1428159b3361Sopenharmony_ci
1429159b3361Sopenharmony_ci/* AIFF Definitions */
1430159b3361Sopenharmony_ci
1431159b3361Sopenharmony_cistatic uint32_t const IFF_ID_FORM = 0x464f524d; /* "FORM" */
1432159b3361Sopenharmony_cistatic uint32_t const IFF_ID_AIFF = 0x41494646; /* "AIFF" */
1433159b3361Sopenharmony_cistatic uint32_t const IFF_ID_AIFC = 0x41494643; /* "AIFC" */
1434159b3361Sopenharmony_cistatic uint32_t const IFF_ID_COMM = 0x434f4d4d; /* "COMM" */
1435159b3361Sopenharmony_cistatic uint32_t const IFF_ID_SSND = 0x53534e44; /* "SSND" */
1436159b3361Sopenharmony_cistatic uint32_t const IFF_ID_MPEG = 0x4d504547; /* "MPEG" */
1437159b3361Sopenharmony_ci
1438159b3361Sopenharmony_cistatic uint32_t const IFF_ID_NONE = 0x4e4f4e45; /* "NONE" *//* AIFF-C data format */
1439159b3361Sopenharmony_cistatic uint32_t const IFF_ID_2CBE = 0x74776f73; /* "twos" *//* AIFF-C data format */
1440159b3361Sopenharmony_cistatic uint32_t const IFF_ID_2CLE = 0x736f7774; /* "sowt" *//* AIFF-C data format */
1441159b3361Sopenharmony_cistatic uint32_t const IFF_ID_FL32 = 0x666C3332; /* "fl32" *//* AIFF-C data format */
1442159b3361Sopenharmony_cistatic uint32_t const IFF_ID_FL64 = 0x666C3634; /* "fl64" *//* AIFF-C data format */
1443159b3361Sopenharmony_ci
1444159b3361Sopenharmony_cistatic uint32_t const WAV_ID_RIFF = 0x52494646; /* "RIFF" */
1445159b3361Sopenharmony_cistatic uint32_t const WAV_ID_WAVE = 0x57415645; /* "WAVE" */
1446159b3361Sopenharmony_cistatic uint32_t const WAV_ID_FMT = 0x666d7420; /* "fmt " */
1447159b3361Sopenharmony_cistatic uint32_t const WAV_ID_DATA = 0x64617461; /* "data" */
1448159b3361Sopenharmony_ci
1449159b3361Sopenharmony_ci#ifndef WAVE_FORMAT_PCM
1450159b3361Sopenharmony_cistatic uint16_t const WAVE_FORMAT_PCM = 0x0001;
1451159b3361Sopenharmony_ci#endif
1452159b3361Sopenharmony_ci#ifndef WAVE_FORMAT_IEEE_FLOAT
1453159b3361Sopenharmony_cistatic uint16_t const WAVE_FORMAT_IEEE_FLOAT = 0x0003;
1454159b3361Sopenharmony_ci#endif
1455159b3361Sopenharmony_ci#ifndef WAVE_FORMAT_EXTENSIBLE
1456159b3361Sopenharmony_cistatic uint16_t const WAVE_FORMAT_EXTENSIBLE = 0xFFFE;
1457159b3361Sopenharmony_ci#endif
1458159b3361Sopenharmony_ci
1459159b3361Sopenharmony_ci
1460159b3361Sopenharmony_cistatic uint32_t
1461159b3361Sopenharmony_cimake_even_number_of_bytes_in_length(uint32_t x)
1462159b3361Sopenharmony_ci{
1463159b3361Sopenharmony_ci    return x + (x & 0x01);
1464159b3361Sopenharmony_ci}
1465159b3361Sopenharmony_ci
1466159b3361Sopenharmony_ci
1467159b3361Sopenharmony_ci/*****************************************************************************
1468159b3361Sopenharmony_ci *
1469159b3361Sopenharmony_ci *	Read Microsoft Wave headers
1470159b3361Sopenharmony_ci *
1471159b3361Sopenharmony_ci *	By the time we get here the first 32-bits of the file have already been
1472159b3361Sopenharmony_ci *	read, and we're pretty sure that we're looking at a WAV file.
1473159b3361Sopenharmony_ci *
1474159b3361Sopenharmony_ci *****************************************************************************/
1475159b3361Sopenharmony_ci
1476159b3361Sopenharmony_cistatic int
1477159b3361Sopenharmony_ciparse_wave_header(lame_global_flags * gfp, FILE * sf)
1478159b3361Sopenharmony_ci{
1479159b3361Sopenharmony_ci    uint32_t ui32_nSamplesPerSec = 0;
1480159b3361Sopenharmony_ci    uint32_t ui32_DataChunkSize = 0;
1481159b3361Sopenharmony_ci    uint16_t ui16_wFormatTag = 0;
1482159b3361Sopenharmony_ci    uint16_t ui16_nChannels = 0;
1483159b3361Sopenharmony_ci    uint16_t ui16_wBitsPerSample = 0;
1484159b3361Sopenharmony_ci
1485159b3361Sopenharmony_ci    int     is_wav = 0;
1486159b3361Sopenharmony_ci    int     loop_sanity = 0;
1487159b3361Sopenharmony_ci
1488159b3361Sopenharmony_ci    uint32_t ui32_chunkSize = read_32_bits_high_low(sf); /* file_length */
1489159b3361Sopenharmony_ci    uint32_t ui32_WAVEID    = read_32_bits_high_low(sf);
1490159b3361Sopenharmony_ci    if (ui32_WAVEID != WAV_ID_WAVE || ui32_chunkSize < 1)
1491159b3361Sopenharmony_ci        return -1;
1492159b3361Sopenharmony_ci
1493159b3361Sopenharmony_ci    for (loop_sanity = 0; loop_sanity < 20; ++loop_sanity) {
1494159b3361Sopenharmony_ci        uint32_t ui32_ckID = read_32_bits_high_low(sf);
1495159b3361Sopenharmony_ci        if (ui32_ckID == WAV_ID_FMT) {
1496159b3361Sopenharmony_ci            uint32_t ui32_nAvgBytesPerSec = 0;
1497159b3361Sopenharmony_ci            uint32_t ui32_cksize = 0;
1498159b3361Sopenharmony_ci            uint16_t ui16_nBlockAlign = 0;
1499159b3361Sopenharmony_ci
1500159b3361Sopenharmony_ci            ui32_cksize = read_32_bits_low_high(sf);
1501159b3361Sopenharmony_ci            ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize);
1502159b3361Sopenharmony_ci            if (ui32_cksize < 16u) {
1503159b3361Sopenharmony_ci                /*DEBUGF("'fmt' chunk too short (only %ld bytes)!", ui32_cksize);*/
1504159b3361Sopenharmony_ci                return -1;
1505159b3361Sopenharmony_ci            }
1506159b3361Sopenharmony_ci            ui16_wFormatTag      = read_16_bits_low_high(sf);
1507159b3361Sopenharmony_ci            ui16_nChannels       = read_16_bits_low_high(sf);
1508159b3361Sopenharmony_ci            ui32_nSamplesPerSec  = read_32_bits_low_high(sf);
1509159b3361Sopenharmony_ci            ui32_nAvgBytesPerSec = read_32_bits_low_high(sf);
1510159b3361Sopenharmony_ci            ui16_nBlockAlign     = read_16_bits_low_high(sf);
1511159b3361Sopenharmony_ci            ui16_wBitsPerSample  = read_16_bits_low_high(sf);
1512159b3361Sopenharmony_ci            ui32_cksize -= 16u;
1513159b3361Sopenharmony_ci            /* WAVE_FORMAT_EXTENSIBLE support */
1514159b3361Sopenharmony_ci            if ((ui32_cksize > 9u) && (ui16_wFormatTag == WAVE_FORMAT_EXTENSIBLE)) {
1515159b3361Sopenharmony_ci                uint16_t ui16_cbSize              = read_16_bits_low_high(sf);
1516159b3361Sopenharmony_ci                uint16_t ui16_wValidBitsPerSample = read_16_bits_low_high(sf);
1517159b3361Sopenharmony_ci                uint32_t ui32_dwChannelMask       = read_32_bits_low_high(sf);
1518159b3361Sopenharmony_ci                uint16_t ui16_SubFormat           = read_16_bits_low_high(sf);
1519159b3361Sopenharmony_ci                ui32_cksize -= 10u;
1520159b3361Sopenharmony_ci                ui16_wFormatTag = ui16_SubFormat; /* SubType coincident with format_tag for PCM int or float */
1521159b3361Sopenharmony_ci                (void) (ui16_cbSize, ui16_wValidBitsPerSample, ui32_dwChannelMask); /* unused */
1522159b3361Sopenharmony_ci            }
1523159b3361Sopenharmony_ci            /* DEBUGF("   skipping %d bytes\n", ui32_cksize); */
1524159b3361Sopenharmony_ci            if (ui32_cksize > 0) {
1525159b3361Sopenharmony_ci                if (fskip_uint32(sf, ui32_cksize) != 0)
1526159b3361Sopenharmony_ci                    return -1;
1527159b3361Sopenharmony_ci            };
1528159b3361Sopenharmony_ci        }
1529159b3361Sopenharmony_ci        else if (ui32_ckID == WAV_ID_DATA) {
1530159b3361Sopenharmony_ci            ui32_DataChunkSize = read_32_bits_low_high(sf);
1531159b3361Sopenharmony_ci            is_wav = 1;
1532159b3361Sopenharmony_ci            /* We've found the audio data. Read no further! */
1533159b3361Sopenharmony_ci            break;
1534159b3361Sopenharmony_ci        }
1535159b3361Sopenharmony_ci        else {
1536159b3361Sopenharmony_ci            uint32_t ui32_cksize = read_32_bits_low_high(sf);
1537159b3361Sopenharmony_ci            ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize);
1538159b3361Sopenharmony_ci            if (fskip_uint32(sf, ui32_cksize) != 0) {
1539159b3361Sopenharmony_ci                return -1;
1540159b3361Sopenharmony_ci            }
1541159b3361Sopenharmony_ci        }
1542159b3361Sopenharmony_ci    }
1543159b3361Sopenharmony_ci    if (is_wav) {
1544159b3361Sopenharmony_ci        if (ui16_wFormatTag == 0x0050 || ui16_wFormatTag == 0x0055) {
1545159b3361Sopenharmony_ci            return sf_mp123;
1546159b3361Sopenharmony_ci        }
1547159b3361Sopenharmony_ci        if (ui16_wFormatTag != WAVE_FORMAT_PCM && ui16_wFormatTag != WAVE_FORMAT_IEEE_FLOAT) {
1548159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1549159b3361Sopenharmony_ci                error_printf("Unsupported data format: 0x%04X\n", ui16_wFormatTag);
1550159b3361Sopenharmony_ci            }
1551159b3361Sopenharmony_ci            return 0;   /* oh no! non-supported format  */
1552159b3361Sopenharmony_ci        }
1553159b3361Sopenharmony_ci
1554159b3361Sopenharmony_ci        /* make sure the header is sane */
1555159b3361Sopenharmony_ci        if (!set_input_num_channels(gfp, ui16_nChannels))
1556159b3361Sopenharmony_ci            return 0;
1557159b3361Sopenharmony_ci        if (!set_input_samplerate(gfp, ui32_nSamplesPerSec))
1558159b3361Sopenharmony_ci            return 0;
1559159b3361Sopenharmony_ci        /* avoid division by zero */
1560159b3361Sopenharmony_ci        if (ui16_wBitsPerSample < 1) {
1561159b3361Sopenharmony_ci            if (global_ui_config.silent < 10)
1562159b3361Sopenharmony_ci                error_printf("Unsupported bits per sample: %d\n", ui16_wBitsPerSample);
1563159b3361Sopenharmony_ci            return -1;
1564159b3361Sopenharmony_ci        }
1565159b3361Sopenharmony_ci        global. pcmbitwidth = ui16_wBitsPerSample;
1566159b3361Sopenharmony_ci        global. pcm_is_unsigned_8bit = 1;
1567159b3361Sopenharmony_ci        global. pcm_is_ieee_float = (ui16_wFormatTag == WAVE_FORMAT_IEEE_FLOAT ? 1 : 0);
1568159b3361Sopenharmony_ci        if (ui32_DataChunkSize == MAX_U_32_NUM)
1569159b3361Sopenharmony_ci            (void) lame_set_num_samples(gfp, MAX_U_32_NUM);
1570159b3361Sopenharmony_ci        else
1571159b3361Sopenharmony_ci            (void) lame_set_num_samples(gfp, ui32_DataChunkSize / (ui16_nChannels * ((ui16_wBitsPerSample + 7u) / 8u)));
1572159b3361Sopenharmony_ci        return 1;
1573159b3361Sopenharmony_ci    }
1574159b3361Sopenharmony_ci    return -1;
1575159b3361Sopenharmony_ci}
1576159b3361Sopenharmony_ci
1577159b3361Sopenharmony_ci
1578159b3361Sopenharmony_ci
1579159b3361Sopenharmony_ci/************************************************************************
1580159b3361Sopenharmony_ci* aiff_check2
1581159b3361Sopenharmony_ci*
1582159b3361Sopenharmony_ci* PURPOSE:	Checks AIFF header information to make sure it is valid.
1583159b3361Sopenharmony_ci*	        returns 0 on success, 1 on errors
1584159b3361Sopenharmony_ci************************************************************************/
1585159b3361Sopenharmony_ci
1586159b3361Sopenharmony_cistatic int
1587159b3361Sopenharmony_ciaiff_check2(IFF_AIFF * const pcm_aiff_data)
1588159b3361Sopenharmony_ci{
1589159b3361Sopenharmony_ci    if (pcm_aiff_data->sampleType != IFF_ID_SSND) {
1590159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1591159b3361Sopenharmony_ci            error_printf("ERROR: input sound data is not PCM\n");
1592159b3361Sopenharmony_ci        }
1593159b3361Sopenharmony_ci        return 1;
1594159b3361Sopenharmony_ci    }
1595159b3361Sopenharmony_ci    switch (pcm_aiff_data->sampleSize) {
1596159b3361Sopenharmony_ci    case 32:
1597159b3361Sopenharmony_ci    case 24:
1598159b3361Sopenharmony_ci    case 16:
1599159b3361Sopenharmony_ci    case 8:
1600159b3361Sopenharmony_ci        break;
1601159b3361Sopenharmony_ci    default:
1602159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1603159b3361Sopenharmony_ci            error_printf("ERROR: input sound data is not 8, 16, 24 or 32 bits\n");
1604159b3361Sopenharmony_ci        }
1605159b3361Sopenharmony_ci        return 1;
1606159b3361Sopenharmony_ci    }
1607159b3361Sopenharmony_ci    if (pcm_aiff_data->numChannels != 1 && pcm_aiff_data->numChannels != 2) {
1608159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1609159b3361Sopenharmony_ci            error_printf("ERROR: input sound data is not mono or stereo\n");
1610159b3361Sopenharmony_ci        }
1611159b3361Sopenharmony_ci        return 1;
1612159b3361Sopenharmony_ci    }
1613159b3361Sopenharmony_ci    if (pcm_aiff_data->blkAlgn.blockSize != 0) {
1614159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1615159b3361Sopenharmony_ci            error_printf("ERROR: block size of input sound data is not 0 bytes\n");
1616159b3361Sopenharmony_ci        }
1617159b3361Sopenharmony_ci        return 1;
1618159b3361Sopenharmony_ci    }
1619159b3361Sopenharmony_ci    /* A bug, since we correctly skip the offset earlier in the code.
1620159b3361Sopenharmony_ci       if (pcm_aiff_data->blkAlgn.offset != 0) {
1621159b3361Sopenharmony_ci       error_printf("Block offset is not 0 bytes in '%s'\n", file_name);
1622159b3361Sopenharmony_ci       return 1;
1623159b3361Sopenharmony_ci       } */
1624159b3361Sopenharmony_ci
1625159b3361Sopenharmony_ci    return 0;
1626159b3361Sopenharmony_ci}
1627159b3361Sopenharmony_ci
1628159b3361Sopenharmony_ci
1629159b3361Sopenharmony_ci/*****************************************************************************
1630159b3361Sopenharmony_ci *
1631159b3361Sopenharmony_ci *	Read Audio Interchange File Format (AIFF) headers.
1632159b3361Sopenharmony_ci *
1633159b3361Sopenharmony_ci *	By the time we get here the first 32 bits of the file have already been
1634159b3361Sopenharmony_ci *	read, and we're pretty sure that we're looking at an AIFF file.
1635159b3361Sopenharmony_ci *
1636159b3361Sopenharmony_ci *****************************************************************************/
1637159b3361Sopenharmony_ci
1638159b3361Sopenharmony_cistatic int
1639159b3361Sopenharmony_ciparse_aiff_header(lame_global_flags * gfp, FILE * sf)
1640159b3361Sopenharmony_ci{
1641159b3361Sopenharmony_ci    uint32_t  ui32_ChunkSize = 0;
1642159b3361Sopenharmony_ci    uint32_t  ui32_TypeID = 0;
1643159b3361Sopenharmony_ci    IFF_AIFF aiff_info;
1644159b3361Sopenharmony_ci    int     seen_comm_chunk = 0, seen_ssnd_chunk = 0;
1645159b3361Sopenharmony_ci    long    pcm_data_pos = -1;
1646159b3361Sopenharmony_ci
1647159b3361Sopenharmony_ci    memset(&aiff_info, 0, sizeof(aiff_info));
1648159b3361Sopenharmony_ci    aiff_info.sampleFormat = IFF_ID_NONE;
1649159b3361Sopenharmony_ci    ui32_ChunkSize = read_32_bits_high_low(sf);
1650159b3361Sopenharmony_ci
1651159b3361Sopenharmony_ci    ui32_TypeID = read_32_bits_high_low(sf);
1652159b3361Sopenharmony_ci    ui32_ChunkSize -= 4;
1653159b3361Sopenharmony_ci    if ((ui32_TypeID != IFF_ID_AIFF) && (ui32_TypeID != IFF_ID_AIFC))
1654159b3361Sopenharmony_ci        return -1;
1655159b3361Sopenharmony_ci
1656159b3361Sopenharmony_ci    while (ui32_ChunkSize >= 8) {
1657159b3361Sopenharmony_ci        uint32_t ui32_type = read_32_bits_high_low(sf);
1658159b3361Sopenharmony_ci        ui32_ChunkSize -= 4;
1659159b3361Sopenharmony_ci
1660159b3361Sopenharmony_ci        /* DEBUGF(
1661159b3361Sopenharmony_ci           "found chunk type %08x '%4.4s'\n", ui32_type, (char*)&ui32_type); */
1662159b3361Sopenharmony_ci
1663159b3361Sopenharmony_ci        /* don't use a switch here to make it easier to use 'break' for SSND */
1664159b3361Sopenharmony_ci        if (ui32_type == IFF_ID_COMM) {
1665159b3361Sopenharmony_ci            uint32_t ui32_cksize = read_32_bits_high_low(sf);
1666159b3361Sopenharmony_ci            ui32_ChunkSize -= 4;
1667159b3361Sopenharmony_ci            ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize);
1668159b3361Sopenharmony_ci            if (ui32_cksize < 18 || ui32_ChunkSize < ui32_cksize)
1669159b3361Sopenharmony_ci                return -1;
1670159b3361Sopenharmony_ci            ui32_ChunkSize -= ui32_cksize;
1671159b3361Sopenharmony_ci            seen_comm_chunk = seen_ssnd_chunk + 1;
1672159b3361Sopenharmony_ci
1673159b3361Sopenharmony_ci            aiff_info.numChannels = read_16_bits_high_low(sf);
1674159b3361Sopenharmony_ci            aiff_info.numSampleFrames = read_32_bits_high_low(sf);
1675159b3361Sopenharmony_ci            aiff_info.sampleSize = read_16_bits_high_low(sf);
1676159b3361Sopenharmony_ci            aiff_info.sampleRate = read_ieee_extended_high_low(sf);
1677159b3361Sopenharmony_ci            ui32_cksize -= 18;
1678159b3361Sopenharmony_ci            if (ui32_TypeID == IFF_ID_AIFC) {
1679159b3361Sopenharmony_ci                if (ui32_cksize < 4)
1680159b3361Sopenharmony_ci                    return -1;
1681159b3361Sopenharmony_ci                aiff_info.sampleFormat = read_32_bits_high_low(sf);
1682159b3361Sopenharmony_ci                ui32_cksize -= 4;
1683159b3361Sopenharmony_ci            }
1684159b3361Sopenharmony_ci            if (fskip_uint32(sf, ui32_cksize) != 0)
1685159b3361Sopenharmony_ci                return -1;
1686159b3361Sopenharmony_ci        }
1687159b3361Sopenharmony_ci        else if (ui32_type == IFF_ID_SSND) {
1688159b3361Sopenharmony_ci            uint32_t ui32_cksize = read_32_bits_high_low(sf);
1689159b3361Sopenharmony_ci            ui32_ChunkSize -= 4;
1690159b3361Sopenharmony_ci            ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize);
1691159b3361Sopenharmony_ci            if (ui32_cksize < 8 || ui32_ChunkSize < ui32_cksize)
1692159b3361Sopenharmony_ci                return -1;
1693159b3361Sopenharmony_ci            ui32_ChunkSize -= ui32_cksize;
1694159b3361Sopenharmony_ci            seen_ssnd_chunk = 1;
1695159b3361Sopenharmony_ci
1696159b3361Sopenharmony_ci            aiff_info.sampleType = IFF_ID_SSND;
1697159b3361Sopenharmony_ci            aiff_info.blkAlgn.offset = read_32_bits_high_low(sf);
1698159b3361Sopenharmony_ci            aiff_info.blkAlgn.blockSize = read_32_bits_high_low(sf);
1699159b3361Sopenharmony_ci            ui32_cksize -= 8;
1700159b3361Sopenharmony_ci            if (seen_comm_chunk > 0) {
1701159b3361Sopenharmony_ci                if (fskip_uint32(sf, aiff_info.blkAlgn.offset) != 0)
1702159b3361Sopenharmony_ci                    return -1;
1703159b3361Sopenharmony_ci                /* We've found the audio data. Read no further! */
1704159b3361Sopenharmony_ci                break;
1705159b3361Sopenharmony_ci            }
1706159b3361Sopenharmony_ci            pcm_data_pos = ftell(sf);
1707159b3361Sopenharmony_ci            if (pcm_data_pos >= 0) {
1708159b3361Sopenharmony_ci                pcm_data_pos += aiff_info.blkAlgn.offset;
1709159b3361Sopenharmony_ci            }
1710159b3361Sopenharmony_ci            if (fskip_uint32(sf, ui32_cksize) != 0)
1711159b3361Sopenharmony_ci                return -1;
1712159b3361Sopenharmony_ci        }
1713159b3361Sopenharmony_ci        else {
1714159b3361Sopenharmony_ci            uint32_t ui32_cksize;
1715159b3361Sopenharmony_ci            ui32_cksize = read_32_bits_high_low(sf);
1716159b3361Sopenharmony_ci            ui32_ChunkSize -= 4;
1717159b3361Sopenharmony_ci            ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize);
1718159b3361Sopenharmony_ci            if (ui32_ChunkSize < ui32_cksize)
1719159b3361Sopenharmony_ci                return -1;
1720159b3361Sopenharmony_ci            ui32_ChunkSize -= ui32_cksize;
1721159b3361Sopenharmony_ci            if (fskip_uint32(sf, ui32_cksize) != 0)
1722159b3361Sopenharmony_ci                return -1;
1723159b3361Sopenharmony_ci        }
1724159b3361Sopenharmony_ci    }
1725159b3361Sopenharmony_ci    if (aiff_info.sampleFormat == IFF_ID_2CLE) {
1726159b3361Sopenharmony_ci        global. pcm_is_ieee_float = 0;
1727159b3361Sopenharmony_ci        global. pcmswapbytes = global_reader.swapbytes;
1728159b3361Sopenharmony_ci    }
1729159b3361Sopenharmony_ci    else if (aiff_info.sampleFormat == IFF_ID_2CBE) {
1730159b3361Sopenharmony_ci        global. pcm_is_ieee_float = 0;
1731159b3361Sopenharmony_ci        global. pcmswapbytes = !global_reader.swapbytes;
1732159b3361Sopenharmony_ci    }
1733159b3361Sopenharmony_ci    else if (aiff_info.sampleFormat == IFF_ID_NONE) {
1734159b3361Sopenharmony_ci        global. pcm_is_ieee_float = 0;
1735159b3361Sopenharmony_ci        global. pcmswapbytes = !global_reader.swapbytes;
1736159b3361Sopenharmony_ci    }
1737159b3361Sopenharmony_ci    else if (aiff_info.sampleFormat == IFF_ID_FL32) {
1738159b3361Sopenharmony_ci        global. pcm_is_ieee_float = 1;
1739159b3361Sopenharmony_ci        global. pcmswapbytes = !global_reader.swapbytes;
1740159b3361Sopenharmony_ci    }
1741159b3361Sopenharmony_ci    /*  64 bit floating point reading is still missing
1742159b3361Sopenharmony_ci    else if (aiff_info.sampleFormat == IFF_ID_FL64) {
1743159b3361Sopenharmony_ci        global. pcm_is_ieee_float = 1;
1744159b3361Sopenharmony_ci        global. pcmswapbytes = !global_reader.swapbytes;
1745159b3361Sopenharmony_ci    }
1746159b3361Sopenharmony_ci    */
1747159b3361Sopenharmony_ci    else {
1748159b3361Sopenharmony_ci        return -1;
1749159b3361Sopenharmony_ci    }
1750159b3361Sopenharmony_ci
1751159b3361Sopenharmony_ci    /* DEBUGF("Parsed AIFF %d\n", is_aiff); */
1752159b3361Sopenharmony_ci    if (seen_comm_chunk && (seen_ssnd_chunk > 0 || aiff_info.numSampleFrames == 0)) {
1753159b3361Sopenharmony_ci        /* make sure the header is sane */
1754159b3361Sopenharmony_ci        if (0 != aiff_check2(&aiff_info))
1755159b3361Sopenharmony_ci            return 0;
1756159b3361Sopenharmony_ci        if (!set_input_num_channels(gfp, aiff_info.numChannels))
1757159b3361Sopenharmony_ci            return 0;
1758159b3361Sopenharmony_ci        if (!set_input_samplerate(gfp, (int) aiff_info.sampleRate))
1759159b3361Sopenharmony_ci            return 0;
1760159b3361Sopenharmony_ci        (void) lame_set_num_samples(gfp, aiff_info.numSampleFrames);
1761159b3361Sopenharmony_ci        global. pcmbitwidth = aiff_info.sampleSize;
1762159b3361Sopenharmony_ci        global. pcm_is_unsigned_8bit = 0;
1763159b3361Sopenharmony_ci        if (pcm_data_pos >= 0) {
1764159b3361Sopenharmony_ci            if (fseek(sf, pcm_data_pos, SEEK_SET) != 0) {
1765159b3361Sopenharmony_ci                if (global_ui_config.silent < 10) {
1766159b3361Sopenharmony_ci                    error_printf("Can't rewind stream to audio data position\n");
1767159b3361Sopenharmony_ci                }
1768159b3361Sopenharmony_ci                return 0;
1769159b3361Sopenharmony_ci            }
1770159b3361Sopenharmony_ci        }
1771159b3361Sopenharmony_ci
1772159b3361Sopenharmony_ci        return 1;
1773159b3361Sopenharmony_ci    }
1774159b3361Sopenharmony_ci    return -1;
1775159b3361Sopenharmony_ci}
1776159b3361Sopenharmony_ci
1777159b3361Sopenharmony_ci
1778159b3361Sopenharmony_ci
1779159b3361Sopenharmony_ci/************************************************************************
1780159b3361Sopenharmony_ci*
1781159b3361Sopenharmony_ci* parse_file_header
1782159b3361Sopenharmony_ci*
1783159b3361Sopenharmony_ci* PURPOSE: Read the header from a bytestream.  Try to determine whether
1784159b3361Sopenharmony_ci*          it's a WAV file or AIFF without rewinding, since rewind
1785159b3361Sopenharmony_ci*          doesn't work on pipes and there's a good chance we're reading
1786159b3361Sopenharmony_ci*          from stdin (otherwise we'd probably be using libsndfile).
1787159b3361Sopenharmony_ci*
1788159b3361Sopenharmony_ci* When this function returns, the file offset will be positioned at the
1789159b3361Sopenharmony_ci* beginning of the sound data.
1790159b3361Sopenharmony_ci*
1791159b3361Sopenharmony_ci************************************************************************/
1792159b3361Sopenharmony_ci
1793159b3361Sopenharmony_cistatic int
1794159b3361Sopenharmony_ciparse_file_header(lame_global_flags * gfp, FILE * sf)
1795159b3361Sopenharmony_ci{
1796159b3361Sopenharmony_ci    uint32_t ui32_type = read_32_bits_high_low(sf);
1797159b3361Sopenharmony_ci    /*
1798159b3361Sopenharmony_ci       DEBUGF(
1799159b3361Sopenharmony_ci       "First word of input stream: %08x '%4.4s'\n", ui32_type, (char*) &type);
1800159b3361Sopenharmony_ci     */
1801159b3361Sopenharmony_ci    global. count_samples_carefully = 0;
1802159b3361Sopenharmony_ci    global. pcm_is_unsigned_8bit = global_raw_pcm.in_signed == 1 ? 0 : 1;
1803159b3361Sopenharmony_ci    /*global_reader.input_format = sf_raw; commented out, because it is better to fail
1804159b3361Sopenharmony_ci       here as to encode some hundreds of input files not supported by LAME
1805159b3361Sopenharmony_ci       If you know you have RAW PCM data, use the -r switch
1806159b3361Sopenharmony_ci     */
1807159b3361Sopenharmony_ci
1808159b3361Sopenharmony_ci    if (ui32_type == WAV_ID_RIFF) {
1809159b3361Sopenharmony_ci        /* It's probably a WAV file */
1810159b3361Sopenharmony_ci        int const ret = parse_wave_header(gfp, sf);
1811159b3361Sopenharmony_ci        if (ret == sf_mp123) {
1812159b3361Sopenharmony_ci            global. count_samples_carefully = 1;
1813159b3361Sopenharmony_ci            return sf_mp123;
1814159b3361Sopenharmony_ci        }
1815159b3361Sopenharmony_ci        if (ret > 0) {
1816159b3361Sopenharmony_ci            if (lame_get_num_samples(gfp) == MAX_U_32_NUM || global_reader.ignorewavlength == 1)
1817159b3361Sopenharmony_ci            {
1818159b3361Sopenharmony_ci                global. count_samples_carefully = 0;
1819159b3361Sopenharmony_ci                lame_set_num_samples(gfp, MAX_U_32_NUM);
1820159b3361Sopenharmony_ci            }
1821159b3361Sopenharmony_ci            else
1822159b3361Sopenharmony_ci                global. count_samples_carefully = 1;
1823159b3361Sopenharmony_ci            return sf_wave;
1824159b3361Sopenharmony_ci        }
1825159b3361Sopenharmony_ci        if (ret < 0) {
1826159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1827159b3361Sopenharmony_ci                error_printf("Warning: corrupt or unsupported WAVE format\n");
1828159b3361Sopenharmony_ci            }
1829159b3361Sopenharmony_ci        }
1830159b3361Sopenharmony_ci    }
1831159b3361Sopenharmony_ci    else if (ui32_type == IFF_ID_FORM) {
1832159b3361Sopenharmony_ci        /* It's probably an AIFF file */
1833159b3361Sopenharmony_ci        int const ret = parse_aiff_header(gfp, sf);
1834159b3361Sopenharmony_ci        if (ret > 0) {
1835159b3361Sopenharmony_ci            global. count_samples_carefully = 1;
1836159b3361Sopenharmony_ci            return sf_aiff;
1837159b3361Sopenharmony_ci        }
1838159b3361Sopenharmony_ci        if (ret < 0) {
1839159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1840159b3361Sopenharmony_ci                error_printf("Warning: corrupt or unsupported AIFF format\n");
1841159b3361Sopenharmony_ci            }
1842159b3361Sopenharmony_ci        }
1843159b3361Sopenharmony_ci    }
1844159b3361Sopenharmony_ci    else {
1845159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1846159b3361Sopenharmony_ci            error_printf("Warning: unsupported audio format\n");
1847159b3361Sopenharmony_ci        }
1848159b3361Sopenharmony_ci    }
1849159b3361Sopenharmony_ci    return sf_unknown;
1850159b3361Sopenharmony_ci}
1851159b3361Sopenharmony_ci
1852159b3361Sopenharmony_ci
1853159b3361Sopenharmony_cistatic int
1854159b3361Sopenharmony_ciopen_mpeg_file_part2(lame_t gfp, FILE* musicin, char const *inPath, int *enc_delay, int *enc_padding)
1855159b3361Sopenharmony_ci{
1856159b3361Sopenharmony_ci#ifdef HAVE_MPG123
1857159b3361Sopenharmony_ci    if (-1 == lame123_decode_initfile(musicin, &global_decoder.mp3input_data, enc_delay, enc_padding)) {
1858159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1859159b3361Sopenharmony_ci            error_printf("Error opening MPEG input file %s.\n", inPath);
1860159b3361Sopenharmony_ci        }
1861159b3361Sopenharmony_ci        return 0;
1862159b3361Sopenharmony_ci    }
1863159b3361Sopenharmony_ci#else
1864159b3361Sopenharmony_ci#ifdef HAVE_MPGLIB
1865159b3361Sopenharmony_ci    if (-1 == lame_decode_initfile(musicin, &global_decoder.mp3input_data, enc_delay, enc_padding)) {
1866159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1867159b3361Sopenharmony_ci            error_printf("Error reading headers in mp3 input file %s.\n", inPath);
1868159b3361Sopenharmony_ci        }
1869159b3361Sopenharmony_ci        return 0;
1870159b3361Sopenharmony_ci    }
1871159b3361Sopenharmony_ci#endif
1872159b3361Sopenharmony_ci#endif
1873159b3361Sopenharmony_ci    if (!set_input_num_channels(gfp, global_decoder.mp3input_data.stereo)) {
1874159b3361Sopenharmony_ci        return 0;
1875159b3361Sopenharmony_ci    }
1876159b3361Sopenharmony_ci    if (!set_input_samplerate(gfp, global_decoder.mp3input_data.samplerate)) {
1877159b3361Sopenharmony_ci        return 0;
1878159b3361Sopenharmony_ci    }
1879159b3361Sopenharmony_ci    (void) lame_set_num_samples(gfp, global_decoder.mp3input_data.nsamp);
1880159b3361Sopenharmony_ci    return 1;
1881159b3361Sopenharmony_ci}
1882159b3361Sopenharmony_ci
1883159b3361Sopenharmony_ci
1884159b3361Sopenharmony_cistatic FILE *
1885159b3361Sopenharmony_ciopen_wave_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding)
1886159b3361Sopenharmony_ci{
1887159b3361Sopenharmony_ci    FILE   *musicin;
1888159b3361Sopenharmony_ci
1889159b3361Sopenharmony_ci    /* set the defaults from info incase we cannot determine them from file */
1890159b3361Sopenharmony_ci    lame_set_num_samples(gfp, MAX_U_32_NUM);
1891159b3361Sopenharmony_ci
1892159b3361Sopenharmony_ci    if (!strcmp(inPath, "-")) {
1893159b3361Sopenharmony_ci        lame_set_stream_binary_mode(musicin = stdin); /* Read from standard input. */
1894159b3361Sopenharmony_ci    }
1895159b3361Sopenharmony_ci    else {
1896159b3361Sopenharmony_ci        if ((musicin = lame_fopen(inPath, "rb")) == NULL) {
1897159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1898159b3361Sopenharmony_ci                error_printf("Could not find \"%s\".\n", inPath);
1899159b3361Sopenharmony_ci            }
1900159b3361Sopenharmony_ci            return 0;
1901159b3361Sopenharmony_ci        }
1902159b3361Sopenharmony_ci    }
1903159b3361Sopenharmony_ci
1904159b3361Sopenharmony_ci    if (global_reader.input_format == sf_ogg) {
1905159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1906159b3361Sopenharmony_ci            error_printf("sorry, vorbis support in LAME is deprecated.\n");
1907159b3361Sopenharmony_ci        }
1908159b3361Sopenharmony_ci        close_input_file(musicin);
1909159b3361Sopenharmony_ci        return 0;
1910159b3361Sopenharmony_ci    }
1911159b3361Sopenharmony_ci    else if (global_reader.input_format == sf_raw) {
1912159b3361Sopenharmony_ci        /* assume raw PCM */
1913159b3361Sopenharmony_ci        if (global_ui_config.silent < 9) {
1914159b3361Sopenharmony_ci            console_printf("Assuming raw pcm input file");
1915159b3361Sopenharmony_ci            if (global_reader.swapbytes)
1916159b3361Sopenharmony_ci                console_printf(" : Forcing byte-swapping\n");
1917159b3361Sopenharmony_ci            else
1918159b3361Sopenharmony_ci                console_printf("\n");
1919159b3361Sopenharmony_ci        }
1920159b3361Sopenharmony_ci        global. pcmswapbytes = global_reader.swapbytes;
1921159b3361Sopenharmony_ci    }
1922159b3361Sopenharmony_ci    else {
1923159b3361Sopenharmony_ci        global_reader.input_format = parse_file_header(gfp, musicin);
1924159b3361Sopenharmony_ci    }
1925159b3361Sopenharmony_ci    if (global_reader.input_format == sf_mp123) {
1926159b3361Sopenharmony_ci        if (open_mpeg_file_part2(gfp, musicin, inPath, enc_delay, enc_padding))
1927159b3361Sopenharmony_ci            return musicin;
1928159b3361Sopenharmony_ci        close_input_file(musicin);
1929159b3361Sopenharmony_ci        return 0;
1930159b3361Sopenharmony_ci    }
1931159b3361Sopenharmony_ci    if (global_reader.input_format == sf_unknown) {
1932159b3361Sopenharmony_ci        close_input_file(musicin);
1933159b3361Sopenharmony_ci        return 0;
1934159b3361Sopenharmony_ci    }
1935159b3361Sopenharmony_ci
1936159b3361Sopenharmony_ci    if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) {
1937159b3361Sopenharmony_ci        int const tmp_num_channels = lame_get_num_channels(gfp);
1938159b3361Sopenharmony_ci        double const flen = lame_get_file_size(musicin); /* try to figure out num_samples */
1939159b3361Sopenharmony_ci        if (flen >= 0 && tmp_num_channels > 0 ) {
1940159b3361Sopenharmony_ci            /* try file size, assume 2 bytes per sample */
1941159b3361Sopenharmony_ci            unsigned long fsize = (unsigned long) (flen / (2 * tmp_num_channels));
1942159b3361Sopenharmony_ci            (void) lame_set_num_samples(gfp, fsize);
1943159b3361Sopenharmony_ci            global. count_samples_carefully = 0;
1944159b3361Sopenharmony_ci        }
1945159b3361Sopenharmony_ci    }
1946159b3361Sopenharmony_ci    return musicin;
1947159b3361Sopenharmony_ci}
1948159b3361Sopenharmony_ci
1949159b3361Sopenharmony_ci
1950159b3361Sopenharmony_ci
1951159b3361Sopenharmony_cistatic FILE *
1952159b3361Sopenharmony_ciopen_mpeg_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding)
1953159b3361Sopenharmony_ci{
1954159b3361Sopenharmony_ci    FILE   *musicin;
1955159b3361Sopenharmony_ci
1956159b3361Sopenharmony_ci    /* set the defaults from info incase we cannot determine them from file */
1957159b3361Sopenharmony_ci    lame_set_num_samples(gfp, MAX_U_32_NUM);
1958159b3361Sopenharmony_ci
1959159b3361Sopenharmony_ci    if (strcmp(inPath, "-") == 0) {
1960159b3361Sopenharmony_ci        musicin = stdin;
1961159b3361Sopenharmony_ci        lame_set_stream_binary_mode(musicin); /* Read from standard input. */
1962159b3361Sopenharmony_ci    }
1963159b3361Sopenharmony_ci    else {
1964159b3361Sopenharmony_ci        musicin = lame_fopen(inPath, "rb");
1965159b3361Sopenharmony_ci        if (musicin == NULL) {
1966159b3361Sopenharmony_ci            if (global_ui_config.silent < 10) {
1967159b3361Sopenharmony_ci                error_printf("Could not find \"%s\".\n", inPath);
1968159b3361Sopenharmony_ci            }
1969159b3361Sopenharmony_ci            return 0;
1970159b3361Sopenharmony_ci        }
1971159b3361Sopenharmony_ci    }
1972159b3361Sopenharmony_ci#ifdef AMIGA_MPEGA
1973159b3361Sopenharmony_ci    if (-1 == lame_decode_initfile_amiga(inPath, &global_decoder.mp3input_data)) {
1974159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
1975159b3361Sopenharmony_ci            error_printf("Error reading headers in mp3 input file %s.\n", inPath);
1976159b3361Sopenharmony_ci        }
1977159b3361Sopenharmony_ci        close_input_file(musicin);
1978159b3361Sopenharmony_ci        return 0;
1979159b3361Sopenharmony_ci    }
1980159b3361Sopenharmony_ci#endif
1981159b3361Sopenharmony_ci    if ( 0 == open_mpeg_file_part2(gfp, musicin, inPath, enc_delay, enc_padding) ) {
1982159b3361Sopenharmony_ci        close_input_file(musicin);
1983159b3361Sopenharmony_ci        return 0;
1984159b3361Sopenharmony_ci    }
1985159b3361Sopenharmony_ci    if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) {
1986159b3361Sopenharmony_ci        double  flen = lame_get_file_size(musicin); /* try to figure out num_samples */
1987159b3361Sopenharmony_ci        if (flen >= 0) {
1988159b3361Sopenharmony_ci            /* try file size, assume 2 bytes per sample */
1989159b3361Sopenharmony_ci            if (global_decoder.mp3input_data.bitrate > 0) {
1990159b3361Sopenharmony_ci                double  totalseconds =
1991159b3361Sopenharmony_ci                    (flen * 8.0 / (1000.0 * global_decoder.mp3input_data.bitrate));
1992159b3361Sopenharmony_ci                unsigned long tmp_num_samples =
1993159b3361Sopenharmony_ci                    (unsigned long) (totalseconds * lame_get_in_samplerate(gfp));
1994159b3361Sopenharmony_ci
1995159b3361Sopenharmony_ci                (void) lame_set_num_samples(gfp, tmp_num_samples);
1996159b3361Sopenharmony_ci                global_decoder.mp3input_data.nsamp = tmp_num_samples;
1997159b3361Sopenharmony_ci                global. count_samples_carefully = 0;
1998159b3361Sopenharmony_ci            }
1999159b3361Sopenharmony_ci        }
2000159b3361Sopenharmony_ci    }
2001159b3361Sopenharmony_ci    return musicin;
2002159b3361Sopenharmony_ci}
2003159b3361Sopenharmony_ci
2004159b3361Sopenharmony_ci
2005159b3361Sopenharmony_cistatic int
2006159b3361Sopenharmony_ciclose_input_file(FILE * musicin)
2007159b3361Sopenharmony_ci{
2008159b3361Sopenharmony_ci    int     ret = 0;
2009159b3361Sopenharmony_ci
2010159b3361Sopenharmony_ci    if (musicin != stdin && musicin != 0) {
2011159b3361Sopenharmony_ci        ret = fclose(musicin);
2012159b3361Sopenharmony_ci    }
2013159b3361Sopenharmony_ci    if (ret != 0) {
2014159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
2015159b3361Sopenharmony_ci            error_printf("Could not close audio input file\n");
2016159b3361Sopenharmony_ci        }
2017159b3361Sopenharmony_ci    }
2018159b3361Sopenharmony_ci    return ret;
2019159b3361Sopenharmony_ci}
2020159b3361Sopenharmony_ci
2021159b3361Sopenharmony_ci
2022159b3361Sopenharmony_ci
2023159b3361Sopenharmony_ci#if defined(HAVE_MPGLIB)
2024159b3361Sopenharmony_cistatic int
2025159b3361Sopenharmony_cicheck_aid(const unsigned char *header)
2026159b3361Sopenharmony_ci{
2027159b3361Sopenharmony_ci    return 0 == memcmp(header, "AiD\1", 4);
2028159b3361Sopenharmony_ci}
2029159b3361Sopenharmony_ci
2030159b3361Sopenharmony_ci/*
2031159b3361Sopenharmony_ci * Please check this and don't kill me if there's a bug
2032159b3361Sopenharmony_ci * This is a (nearly?) complete header analysis for a MPEG-1/2/2.5 Layer I, II or III
2033159b3361Sopenharmony_ci * data stream
2034159b3361Sopenharmony_ci */
2035159b3361Sopenharmony_ci
2036159b3361Sopenharmony_cistatic int
2037159b3361Sopenharmony_ciis_syncword_mp123(const void *const headerptr)
2038159b3361Sopenharmony_ci{
2039159b3361Sopenharmony_ci    const unsigned char *const p = headerptr;
2040159b3361Sopenharmony_ci    static const char abl2[16] = { 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8 };
2041159b3361Sopenharmony_ci
2042159b3361Sopenharmony_ci    if ((p[0] & 0xFF) != 0xFF)
2043159b3361Sopenharmony_ci        return 0;       /* first 8 bits must be '1' */
2044159b3361Sopenharmony_ci    if ((p[1] & 0xE0) != 0xE0)
2045159b3361Sopenharmony_ci        return 0;       /* next 3 bits are also */
2046159b3361Sopenharmony_ci    if ((p[1] & 0x18) == 0x08)
2047159b3361Sopenharmony_ci        return 0;       /* no MPEG-1, -2 or -2.5 */
2048159b3361Sopenharmony_ci    switch (p[1] & 0x06) {
2049159b3361Sopenharmony_ci    default:
2050159b3361Sopenharmony_ci    case 0x00:         /* illegal Layer */
2051159b3361Sopenharmony_ci        return 0;
2052159b3361Sopenharmony_ci
2053159b3361Sopenharmony_ci    case 0x02:         /* Layer3 */
2054159b3361Sopenharmony_ci        if (global_reader.input_format != sf_mp3 && global_reader.input_format != sf_mp123) {
2055159b3361Sopenharmony_ci            return 0;
2056159b3361Sopenharmony_ci        }
2057159b3361Sopenharmony_ci        global_reader.input_format = sf_mp3;
2058159b3361Sopenharmony_ci        break;
2059159b3361Sopenharmony_ci
2060159b3361Sopenharmony_ci    case 0x04:         /* Layer2 */
2061159b3361Sopenharmony_ci        if (global_reader.input_format != sf_mp2 && global_reader.input_format != sf_mp123) {
2062159b3361Sopenharmony_ci            return 0;
2063159b3361Sopenharmony_ci        }
2064159b3361Sopenharmony_ci        global_reader.input_format = sf_mp2;
2065159b3361Sopenharmony_ci        break;
2066159b3361Sopenharmony_ci
2067159b3361Sopenharmony_ci    case 0x06:         /* Layer1 */
2068159b3361Sopenharmony_ci        if (global_reader.input_format != sf_mp1 && global_reader.input_format != sf_mp123) {
2069159b3361Sopenharmony_ci            return 0;
2070159b3361Sopenharmony_ci        }
2071159b3361Sopenharmony_ci        global_reader.input_format = sf_mp1;
2072159b3361Sopenharmony_ci        break;
2073159b3361Sopenharmony_ci    }
2074159b3361Sopenharmony_ci    if ((p[1] & 0x06) == 0x00)
2075159b3361Sopenharmony_ci        return 0;       /* no Layer I, II and III */
2076159b3361Sopenharmony_ci    if ((p[2] & 0xF0) == 0xF0)
2077159b3361Sopenharmony_ci        return 0;       /* bad bitrate */
2078159b3361Sopenharmony_ci    if ((p[2] & 0x0C) == 0x0C)
2079159b3361Sopenharmony_ci        return 0;       /* no sample frequency with (32,44.1,48)/(1,2,4)     */
2080159b3361Sopenharmony_ci    if ((p[1] & 0x18) == 0x18 && (p[1] & 0x06) == 0x04 && abl2[p[2] >> 4] & (1 << (p[3] >> 6)))
2081159b3361Sopenharmony_ci        return 0;
2082159b3361Sopenharmony_ci    if ((p[3] & 3) == 2)
2083159b3361Sopenharmony_ci        return 0;       /* reserved enphasis mode */
2084159b3361Sopenharmony_ci    return 1;
2085159b3361Sopenharmony_ci}
2086159b3361Sopenharmony_ci
2087159b3361Sopenharmony_cistatic size_t
2088159b3361Sopenharmony_cilenOfId3v2Tag(unsigned char const* buf)
2089159b3361Sopenharmony_ci{
2090159b3361Sopenharmony_ci    unsigned int b0 = buf[0] & 127;
2091159b3361Sopenharmony_ci    unsigned int b1 = buf[1] & 127;
2092159b3361Sopenharmony_ci    unsigned int b2 = buf[2] & 127;
2093159b3361Sopenharmony_ci    unsigned int b3 = buf[3] & 127;
2094159b3361Sopenharmony_ci    return (((((b0 << 7) + b1) << 7) + b2) << 7) + b3;
2095159b3361Sopenharmony_ci}
2096159b3361Sopenharmony_ci#endif
2097159b3361Sopenharmony_ci
2098159b3361Sopenharmony_ci#ifdef HAVE_MPG123
2099159b3361Sopenharmony_ci#define CHECK123(code) if(MPG123_OK != (code)) return -1
2100159b3361Sopenharmony_ci
2101159b3361Sopenharmony_ci#ifdef _WIN32
2102159b3361Sopenharmony_cistatic ssize_t lame123_read_from_file(void* handle, void* buffer, size_t size)
2103159b3361Sopenharmony_ci{
2104159b3361Sopenharmony_ci   return fread(buffer, 1, size, (FILE*)handle);
2105159b3361Sopenharmony_ci}
2106159b3361Sopenharmony_ci
2107159b3361Sopenharmony_cistatic off_t lame123_seek_in_file(void* handle, off_t offset, int direction)
2108159b3361Sopenharmony_ci{
2109159b3361Sopenharmony_ci   if (fseek((FILE*)handle, offset, direction) != 0)
2110159b3361Sopenharmony_ci      return (off_t)-1;
2111159b3361Sopenharmony_ci   return ftell((FILE*)handle);
2112159b3361Sopenharmony_ci}
2113159b3361Sopenharmony_ci
2114159b3361Sopenharmony_cistatic void lame123_cleanup_file(void* handle)
2115159b3361Sopenharmony_ci{
2116159b3361Sopenharmony_ci   /* don't call fclose(); close_input_file() will do that */
2117159b3361Sopenharmony_ci}
2118159b3361Sopenharmony_ci#endif
2119159b3361Sopenharmony_ci
2120159b3361Sopenharmony_ciint lame123_decode_initfile(FILE *fd, mp3data_struct *mp3data, int *enc_delay, int *enc_padding)
2121159b3361Sopenharmony_ci{
2122159b3361Sopenharmony_ci    off_t len;
2123159b3361Sopenharmony_ci    unsigned char *id3buf;
2124159b3361Sopenharmony_ci    size_t id3size;
2125159b3361Sopenharmony_ci    struct mpg123_frameinfo fi;
2126159b3361Sopenharmony_ci    long rate, val;
2127159b3361Sopenharmony_ci    int channels;
2128159b3361Sopenharmony_ci
2129159b3361Sopenharmony_ci    mpg123_init();
2130159b3361Sopenharmony_ci    memset(mp3data, 0, sizeof(mp3data_struct));
2131159b3361Sopenharmony_ci    if (global.hip) {
2132159b3361Sopenharmony_ci        hip_decode_exit(global.hip);
2133159b3361Sopenharmony_ci    }
2134159b3361Sopenharmony_ci    global. hip = hip_decode_init();
2135159b3361Sopenharmony_ci    if(!global.hip->mh)
2136159b3361Sopenharmony_ci        return -1;
2137159b3361Sopenharmony_ci    /* TODO: enforce float format ... optionally be careful for builds
2138159b3361Sopenharmony_ci       that only know 16 bit output. */
2139159b3361Sopenharmony_ci    mpg123_param(global.hip->mh, MPG123_ADD_FLAGS, MPG123_STORE_RAW_ID3, 0.);
2140159b3361Sopenharmony_ci    mpg123_param(global.hip->mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0.);
2141159b3361Sopenharmony_ci    mpg123_format_none(global.hip->mh);
2142159b3361Sopenharmony_ci    /* TODO: switch to MPG123_ENC_FLOAT_32, always! */
2143159b3361Sopenharmony_ci    CHECK123(mpg123_format2(global.hip->mh,
2144159b3361Sopenharmony_ci        0, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16));
2145159b3361Sopenharmony_ci    /* TODO: verboseness / silence set up */
2146159b3361Sopenharmony_ci#ifdef _WIN32
2147159b3361Sopenharmony_ci    /* On Win32 compiles it can happen that lame.exe and libmp3lame.dll use
2148159b3361Sopenharmony_ci       different C++ runtimes, which maintail different FILE* lists, and
2149159b3361Sopenharmony_ci       fileno() would produce invalid file numbers for those msvcrt instances.
2150159b3361Sopenharmony_ci       So use mpg123_replace_reader_handle() / mpg123_open_handle() here
2151159b3361Sopenharmony_ci       instead of mpg123_open_fd(). */
2152159b3361Sopenharmony_ci    CHECK123(mpg123_replace_reader_handle(global.hip->mh, lame123_read_from_file, lame123_seek_in_file, lame123_cleanup_file));
2153159b3361Sopenharmony_ci    CHECK123(mpg123_open_handle(global.hip->mh, fd));
2154159b3361Sopenharmony_ci#else
2155159b3361Sopenharmony_ci    CHECK123(mpg123_open_fd(global.hip->mh, fileno(fd)));
2156159b3361Sopenharmony_ci#endif
2157159b3361Sopenharmony_ci    /* Seek to get past Info frame and ID3v2. */
2158159b3361Sopenharmony_ci    CHECK123(mpg123_seek(global.hip->mh, SEEK_SET, 0));
2159159b3361Sopenharmony_ci    /* TODO: Figure out if MPG123_GAPLESS is desired or not. */
2160159b3361Sopenharmony_ci    /* Guessing seems to be OK, so we do not have to insist on knowing
2161159b3361Sopenharmony_ci       if libmpg123 got that info from Info tag or not. */
2162159b3361Sopenharmony_ci    /* I am paranoid about off_t being larger than long or int. */
2163159b3361Sopenharmony_ci    len = mpg123_framelength(global.hip->mh);
2164159b3361Sopenharmony_ci    if(len <= (unsigned long)-1)
2165159b3361Sopenharmony_ci        mp3data->totalframes = len;
2166159b3361Sopenharmony_ci    else
2167159b3361Sopenharmony_ci        return -1;
2168159b3361Sopenharmony_ci    len = mpg123_length(global.hip->mh);
2169159b3361Sopenharmony_ci    if(len <= ((unsigned int)-1)/2)
2170159b3361Sopenharmony_ci        mp3data->nsamp = len;
2171159b3361Sopenharmony_ci    else
2172159b3361Sopenharmony_ci        return -1;
2173159b3361Sopenharmony_ci    /* Encoder delay and padding are not needed when libmpg123 handles gapless
2174159b3361Sopenharmony_ci       decoding itself. So let's see if we get away with that. */
2175159b3361Sopenharmony_ci    mpg123_getstate(global.hip->mh, MPG123_ENC_DELAY, &val, NULL);
2176159b3361Sopenharmony_ci    *enc_delay = val;
2177159b3361Sopenharmony_ci    mpg123_getstate(global.hip->mh, MPG123_ENC_PADDING, &val, NULL);
2178159b3361Sopenharmony_ci    *enc_padding = val;
2179159b3361Sopenharmony_ci    if(global.in_id3v2_tag)
2180159b3361Sopenharmony_ci        free(global.in_id3v2_tag);
2181159b3361Sopenharmony_ci    global.in_id3v2_size = 0;
2182159b3361Sopenharmony_ci    if( MPG123_OK == mpg123_id3_raw(global.hip->mh, NULL, NULL,
2183159b3361Sopenharmony_ci        &id3buf, &id3size) && id3buf && id3size ) {
2184159b3361Sopenharmony_ci        global.in_id3v2_tag = malloc(id3size);
2185159b3361Sopenharmony_ci        if(global.in_id3v2_tag) {
2186159b3361Sopenharmony_ci            memcpy(global.in_id3v2_tag, id3buf, id3size);
2187159b3361Sopenharmony_ci            global.in_id3v2_size = id3size;
2188159b3361Sopenharmony_ci        }
2189159b3361Sopenharmony_ci    }
2190159b3361Sopenharmony_ci    CHECK123(mpg123_info(global.hip->mh, &fi));
2191159b3361Sopenharmony_ci    CHECK123(mpg123_getformat(global.hip->mh, &rate, &channels, NULL));
2192159b3361Sopenharmony_ci    /* How much of this is actually needed for the frontend? */
2193159b3361Sopenharmony_ci    mp3data->header_parsed = 1;
2194159b3361Sopenharmony_ci    mp3data->stereo = channels; /* Channel count correct? Or is dual mono different? */
2195159b3361Sopenharmony_ci    mp3data->samplerate = rate;
2196159b3361Sopenharmony_ci    mp3data->mode = fi.mode;
2197159b3361Sopenharmony_ci    mp3data->mode_ext = fi.mode_ext;
2198159b3361Sopenharmony_ci    mp3data->framesize = mpg123_spf(global.hip->mh);
2199159b3361Sopenharmony_ci    mp3data->bitrate = fi.bitrate;
2200159b3361Sopenharmony_ci    if(global_reader.input_format == sf_mp123) switch(fi.layer) {
2201159b3361Sopenharmony_ci        case 1:
2202159b3361Sopenharmony_ci            global_reader.input_format = sf_mp1;
2203159b3361Sopenharmony_ci        break;
2204159b3361Sopenharmony_ci        case 2:
2205159b3361Sopenharmony_ci            global_reader.input_format = sf_mp2;
2206159b3361Sopenharmony_ci        break;
2207159b3361Sopenharmony_ci        case 3:
2208159b3361Sopenharmony_ci            global_reader.input_format = sf_mp3;
2209159b3361Sopenharmony_ci        break;
2210159b3361Sopenharmony_ci    }
2211159b3361Sopenharmony_ci
2212159b3361Sopenharmony_ci    return 0;
2213159b3361Sopenharmony_ci}
2214159b3361Sopenharmony_ci#endif
2215159b3361Sopenharmony_ci
2216159b3361Sopenharmony_ci#ifdef HAVE_MPGLIB
2217159b3361Sopenharmony_ciint
2218159b3361Sopenharmony_cilame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding)
2219159b3361Sopenharmony_ci{
2220159b3361Sopenharmony_ci    /*  VBRTAGDATA pTagData; */
2221159b3361Sopenharmony_ci    /* int xing_header,len2,num_frames; */
2222159b3361Sopenharmony_ci    unsigned char buf[100];
2223159b3361Sopenharmony_ci    int     ret;
2224159b3361Sopenharmony_ci    size_t  len;
2225159b3361Sopenharmony_ci    int     aid_header;
2226159b3361Sopenharmony_ci    short int pcm_l[1152], pcm_r[1152];
2227159b3361Sopenharmony_ci    int     freeformat = 0;
2228159b3361Sopenharmony_ci
2229159b3361Sopenharmony_ci    memset(mp3data, 0, sizeof(mp3data_struct));
2230159b3361Sopenharmony_ci    if (global.hip) {
2231159b3361Sopenharmony_ci        hip_decode_exit(global.hip);
2232159b3361Sopenharmony_ci    }
2233159b3361Sopenharmony_ci    global. hip = hip_decode_init();
2234159b3361Sopenharmony_ci    hip_set_msgf(global.hip, global_ui_config.silent < 10 ? &frontend_msgf : 0);
2235159b3361Sopenharmony_ci    hip_set_errorf(global.hip, global_ui_config.silent < 10 ? &frontend_errorf : 0);
2236159b3361Sopenharmony_ci    hip_set_debugf(global.hip, &frontend_debugf);
2237159b3361Sopenharmony_ci
2238159b3361Sopenharmony_ci    len = 4;
2239159b3361Sopenharmony_ci    if (fread(buf, 1, len, fd) != len)
2240159b3361Sopenharmony_ci        return -1;      /* failed */
2241159b3361Sopenharmony_ci    while (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {
2242159b3361Sopenharmony_ci        len = 6;
2243159b3361Sopenharmony_ci        if (fread(&buf[4], 1, len, fd) != len)
2244159b3361Sopenharmony_ci            return -1;  /* failed */
2245159b3361Sopenharmony_ci        len = lenOfId3v2Tag(&buf[6]);
2246159b3361Sopenharmony_ci        if (global.in_id3v2_size < 1) {
2247159b3361Sopenharmony_ci            global.in_id3v2_size = 10 + len;
2248159b3361Sopenharmony_ci            global.in_id3v2_tag = malloc(global.in_id3v2_size);
2249159b3361Sopenharmony_ci            if (global.in_id3v2_tag) {
2250159b3361Sopenharmony_ci                memcpy(global.in_id3v2_tag, buf, 10);
2251159b3361Sopenharmony_ci                if (fread(&global.in_id3v2_tag[10], 1, len, fd) != len)
2252159b3361Sopenharmony_ci                    return -1;  /* failed */
2253159b3361Sopenharmony_ci                len = 0; /* copied, nothing to skip */
2254159b3361Sopenharmony_ci            }
2255159b3361Sopenharmony_ci            else {
2256159b3361Sopenharmony_ci                global.in_id3v2_size = 0;
2257159b3361Sopenharmony_ci            }
2258159b3361Sopenharmony_ci        }
2259159b3361Sopenharmony_ci        if (len > LONG_MAX)
2260159b3361Sopenharmony_ci            return -1;
2261159b3361Sopenharmony_ci        if (fskip_long(fd, (long) len, SEEK_CUR) != 0)
2262159b3361Sopenharmony_ci            return -1;
2263159b3361Sopenharmony_ci        len = 4;
2264159b3361Sopenharmony_ci        if (fread(&buf, 1, len, fd) != len)
2265159b3361Sopenharmony_ci            return -1;  /* failed */
2266159b3361Sopenharmony_ci    }
2267159b3361Sopenharmony_ci    aid_header = check_aid(buf);
2268159b3361Sopenharmony_ci    if (aid_header) {
2269159b3361Sopenharmony_ci        if (fread(&buf, 1, 2, fd) != 2)
2270159b3361Sopenharmony_ci            return -1;  /* failed */
2271159b3361Sopenharmony_ci        aid_header = (unsigned char) buf[0] + 256 * (unsigned char) buf[1];
2272159b3361Sopenharmony_ci        if (global_ui_config.silent < 9) {
2273159b3361Sopenharmony_ci            console_printf("Album ID found.  length=%i \n", aid_header);
2274159b3361Sopenharmony_ci        }
2275159b3361Sopenharmony_ci        /* skip rest of AID, except for 6 bytes we have already read */
2276159b3361Sopenharmony_ci        fskip_long(fd, aid_header - 6, SEEK_CUR);
2277159b3361Sopenharmony_ci
2278159b3361Sopenharmony_ci        /* read 4 more bytes to set up buffer for MP3 header check */
2279159b3361Sopenharmony_ci        if (fread(&buf, 1, len, fd) != len)
2280159b3361Sopenharmony_ci            return -1;  /* failed */
2281159b3361Sopenharmony_ci    }
2282159b3361Sopenharmony_ci    len = 4;
2283159b3361Sopenharmony_ci    while (!is_syncword_mp123(buf)) {
2284159b3361Sopenharmony_ci        unsigned int i;
2285159b3361Sopenharmony_ci        for (i = 0; i < len - 1; i++)
2286159b3361Sopenharmony_ci            buf[i] = buf[i + 1];
2287159b3361Sopenharmony_ci        if (fread(buf + len - 1, 1, 1, fd) != 1)
2288159b3361Sopenharmony_ci            return -1;  /* failed */
2289159b3361Sopenharmony_ci    }
2290159b3361Sopenharmony_ci
2291159b3361Sopenharmony_ci    if ((buf[2] & 0xf0) == 0) {
2292159b3361Sopenharmony_ci        if (global_ui_config.silent < 9) {
2293159b3361Sopenharmony_ci            console_printf("Input file is freeformat.\n");
2294159b3361Sopenharmony_ci        }
2295159b3361Sopenharmony_ci        freeformat = 1;
2296159b3361Sopenharmony_ci    }
2297159b3361Sopenharmony_ci    /* now parse the current buffer looking for MP3 headers.    */
2298159b3361Sopenharmony_ci    /* (as of 11/00: mpglib modified so that for the first frame where  */
2299159b3361Sopenharmony_ci    /* headers are parsed, no data will be decoded.   */
2300159b3361Sopenharmony_ci    /* However, for freeformat, we need to decode an entire frame, */
2301159b3361Sopenharmony_ci    /* so mp3data->bitrate will be 0 until we have decoded the first */
2302159b3361Sopenharmony_ci    /* frame.  Cannot decode first frame here because we are not */
2303159b3361Sopenharmony_ci    /* yet prepared to handle the output. */
2304159b3361Sopenharmony_ci    ret = hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, enc_padding);
2305159b3361Sopenharmony_ci    if (-1 == ret)
2306159b3361Sopenharmony_ci        return -1;
2307159b3361Sopenharmony_ci
2308159b3361Sopenharmony_ci    /* repeat until we decode a valid mp3 header.  */
2309159b3361Sopenharmony_ci    while (!mp3data->header_parsed) {
2310159b3361Sopenharmony_ci        len = fread(buf, 1, sizeof(buf), fd);
2311159b3361Sopenharmony_ci        if (len != sizeof(buf))
2312159b3361Sopenharmony_ci            return -1;
2313159b3361Sopenharmony_ci        ret =
2314159b3361Sopenharmony_ci            hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay,
2315159b3361Sopenharmony_ci                                 enc_padding);
2316159b3361Sopenharmony_ci        if (-1 == ret)
2317159b3361Sopenharmony_ci            return -1;
2318159b3361Sopenharmony_ci    }
2319159b3361Sopenharmony_ci
2320159b3361Sopenharmony_ci    if (mp3data->bitrate == 0 && !freeformat) {
2321159b3361Sopenharmony_ci        if (global_ui_config.silent < 10) {
2322159b3361Sopenharmony_ci            error_printf("fail to sync...\n");
2323159b3361Sopenharmony_ci        }
2324159b3361Sopenharmony_ci        return lame_decode_initfile(fd, mp3data, enc_delay, enc_padding);
2325159b3361Sopenharmony_ci    }
2326159b3361Sopenharmony_ci
2327159b3361Sopenharmony_ci    if (mp3data->totalframes > 0) {
2328159b3361Sopenharmony_ci        /* mpglib found a Xing VBR header and computed nsamp & totalframes */
2329159b3361Sopenharmony_ci    }
2330159b3361Sopenharmony_ci    else {
2331159b3361Sopenharmony_ci        /* set as unknown.  Later, we will take a guess based on file size
2332159b3361Sopenharmony_ci         * ant bitrate */
2333159b3361Sopenharmony_ci        mp3data->nsamp = MAX_U_32_NUM;
2334159b3361Sopenharmony_ci    }
2335159b3361Sopenharmony_ci
2336159b3361Sopenharmony_ci
2337159b3361Sopenharmony_ci    /*
2338159b3361Sopenharmony_ci       report_printf("ret = %i NEED_MORE=%i \n",ret,MP3_NEED_MORE);
2339159b3361Sopenharmony_ci       report_printf("stereo = %i \n",mp.fr.stereo);
2340159b3361Sopenharmony_ci       report_printf("samp = %i  \n",freqs[mp.fr.sampling_frequency]);
2341159b3361Sopenharmony_ci       report_printf("framesize = %i  \n",framesize);
2342159b3361Sopenharmony_ci       report_printf("bitrate = %i  \n",mp3data->bitrate);
2343159b3361Sopenharmony_ci       report_printf("num frames = %ui  \n",num_frames);
2344159b3361Sopenharmony_ci       report_printf("num samp = %ui  \n",mp3data->nsamp);
2345159b3361Sopenharmony_ci       report_printf("mode     = %i  \n",mp.fr.mode);
2346159b3361Sopenharmony_ci     */
2347159b3361Sopenharmony_ci
2348159b3361Sopenharmony_ci    return 0;
2349159b3361Sopenharmony_ci}
2350159b3361Sopenharmony_ci
2351159b3361Sopenharmony_ci/*
2352159b3361Sopenharmony_ciFor lame_decode_fromfile:  return code
2353159b3361Sopenharmony_ci  -1     error
2354159b3361Sopenharmony_ci   n     number of samples output.  either 576 or 1152 depending on MP3 file.
2355159b3361Sopenharmony_ci
2356159b3361Sopenharmony_ci
2357159b3361Sopenharmony_ciFor lame_decode1_headers():  return code
2358159b3361Sopenharmony_ci  -1     error
2359159b3361Sopenharmony_ci   0     ok, but need more data before outputing any samples
2360159b3361Sopenharmony_ci   n     number of samples output.  either 576 or 1152 depending on MP3 file.
2361159b3361Sopenharmony_ci*/
2362159b3361Sopenharmony_cistatic int
2363159b3361Sopenharmony_cilame_decode_fromfile(FILE * fd, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
2364159b3361Sopenharmony_ci{
2365159b3361Sopenharmony_ci    int     ret = 0;
2366159b3361Sopenharmony_ci    size_t  len = 0;
2367159b3361Sopenharmony_ci    unsigned char buf[1024];
2368159b3361Sopenharmony_ci
2369159b3361Sopenharmony_ci    /* first see if we still have data buffered in the decoder: */
2370159b3361Sopenharmony_ci    ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
2371159b3361Sopenharmony_ci    if (ret != 0)
2372159b3361Sopenharmony_ci        return ret;
2373159b3361Sopenharmony_ci
2374159b3361Sopenharmony_ci
2375159b3361Sopenharmony_ci    /* read until we get a valid output frame */
2376159b3361Sopenharmony_ci    for (;;) {
2377159b3361Sopenharmony_ci        len = fread(buf, 1, 1024, fd);
2378159b3361Sopenharmony_ci        if (len == 0) {
2379159b3361Sopenharmony_ci            /* we are done reading the file, but check for buffered data */
2380159b3361Sopenharmony_ci            ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
2381159b3361Sopenharmony_ci            if (ret <= 0) {
2382159b3361Sopenharmony_ci                return -1; /* done with file */
2383159b3361Sopenharmony_ci            }
2384159b3361Sopenharmony_ci            break;
2385159b3361Sopenharmony_ci        }
2386159b3361Sopenharmony_ci
2387159b3361Sopenharmony_ci        ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
2388159b3361Sopenharmony_ci        if (ret == -1) {
2389159b3361Sopenharmony_ci            return -1;
2390159b3361Sopenharmony_ci        }
2391159b3361Sopenharmony_ci        if (ret > 0)
2392159b3361Sopenharmony_ci            break;
2393159b3361Sopenharmony_ci    }
2394159b3361Sopenharmony_ci    return ret;
2395159b3361Sopenharmony_ci}
2396159b3361Sopenharmony_ci#endif /* defined(HAVE_MPGLIB) */
2397159b3361Sopenharmony_ci
2398159b3361Sopenharmony_ci
2399159b3361Sopenharmony_ciint
2400159b3361Sopenharmony_ciis_mpeg_file_format(int input_file_format)
2401159b3361Sopenharmony_ci{
2402159b3361Sopenharmony_ci    switch (input_file_format) {
2403159b3361Sopenharmony_ci    case sf_mp1:
2404159b3361Sopenharmony_ci        return 1;
2405159b3361Sopenharmony_ci    case sf_mp2:
2406159b3361Sopenharmony_ci        return 2;
2407159b3361Sopenharmony_ci    case sf_mp3:
2408159b3361Sopenharmony_ci        return 3;
2409159b3361Sopenharmony_ci    case sf_mp123:
2410159b3361Sopenharmony_ci        return -1;
2411159b3361Sopenharmony_ci    default:
2412159b3361Sopenharmony_ci        break;
2413159b3361Sopenharmony_ci    }
2414159b3361Sopenharmony_ci    return 0;
2415159b3361Sopenharmony_ci}
2416159b3361Sopenharmony_ci
2417159b3361Sopenharmony_ci
2418159b3361Sopenharmony_ci#define LOW__BYTE(x) (x & 0x00ff)
2419159b3361Sopenharmony_ci#define HIGH_BYTE(x) ((x >> 8) & 0x00ff)
2420159b3361Sopenharmony_ci
2421159b3361Sopenharmony_civoid
2422159b3361Sopenharmony_ciput_audio16(FILE * outf, short Buffer[2][1152], int iread, int nch)
2423159b3361Sopenharmony_ci{
2424159b3361Sopenharmony_ci    char    data[2 * 1152 * 2];
2425159b3361Sopenharmony_ci    int     i, m = 0;
2426159b3361Sopenharmony_ci
2427159b3361Sopenharmony_ci    if (global_decoder.disable_wav_header && global_reader.swapbytes) {
2428159b3361Sopenharmony_ci        if (nch == 1) {
2429159b3361Sopenharmony_ci            for (i = 0; i < iread; i++) {
2430159b3361Sopenharmony_ci                short   x = Buffer[0][i];
2431159b3361Sopenharmony_ci                /* write 16 Bits High Low */
2432159b3361Sopenharmony_ci                data[m++] = HIGH_BYTE(x);
2433159b3361Sopenharmony_ci                data[m++] = LOW__BYTE(x);
2434159b3361Sopenharmony_ci            }
2435159b3361Sopenharmony_ci        }
2436159b3361Sopenharmony_ci        else {
2437159b3361Sopenharmony_ci            for (i = 0; i < iread; i++) {
2438159b3361Sopenharmony_ci                short   x = Buffer[0][i], y = Buffer[1][i];
2439159b3361Sopenharmony_ci                /* write 16 Bits High Low */
2440159b3361Sopenharmony_ci                data[m++] = HIGH_BYTE(x);
2441159b3361Sopenharmony_ci                data[m++] = LOW__BYTE(x);
2442159b3361Sopenharmony_ci                /* write 16 Bits High Low */
2443159b3361Sopenharmony_ci                data[m++] = HIGH_BYTE(y);
2444159b3361Sopenharmony_ci                data[m++] = LOW__BYTE(y);
2445159b3361Sopenharmony_ci            }
2446159b3361Sopenharmony_ci        }
2447159b3361Sopenharmony_ci    }
2448159b3361Sopenharmony_ci    else {
2449159b3361Sopenharmony_ci        if (nch == 1) {
2450159b3361Sopenharmony_ci            for (i = 0; i < iread; i++) {
2451159b3361Sopenharmony_ci                short   x = Buffer[0][i];
2452159b3361Sopenharmony_ci                /* write 16 Bits Low High */
2453159b3361Sopenharmony_ci                data[m++] = LOW__BYTE(x);
2454159b3361Sopenharmony_ci                data[m++] = HIGH_BYTE(x);
2455159b3361Sopenharmony_ci            }
2456159b3361Sopenharmony_ci        }
2457159b3361Sopenharmony_ci        else {
2458159b3361Sopenharmony_ci            for (i = 0; i < iread; i++) {
2459159b3361Sopenharmony_ci                short   x = Buffer[0][i], y = Buffer[1][i];
2460159b3361Sopenharmony_ci                /* write 16 Bits Low High */
2461159b3361Sopenharmony_ci                data[m++] = LOW__BYTE(x);
2462159b3361Sopenharmony_ci                data[m++] = HIGH_BYTE(x);
2463159b3361Sopenharmony_ci                /* write 16 Bits Low High */
2464159b3361Sopenharmony_ci                data[m++] = LOW__BYTE(y);
2465159b3361Sopenharmony_ci                data[m++] = HIGH_BYTE(y);
2466159b3361Sopenharmony_ci            }
2467159b3361Sopenharmony_ci        }
2468159b3361Sopenharmony_ci    }
2469159b3361Sopenharmony_ci    if (m > 0) {
2470159b3361Sopenharmony_ci        fwrite(data, 1, m, outf);
2471159b3361Sopenharmony_ci    }
2472159b3361Sopenharmony_ci    if (global_writer.flush_write == 1) {
2473159b3361Sopenharmony_ci        fflush(outf);
2474159b3361Sopenharmony_ci    }
2475159b3361Sopenharmony_ci}
2476159b3361Sopenharmony_ci
2477159b3361Sopenharmony_cihip_t
2478159b3361Sopenharmony_ciget_hip(void)
2479159b3361Sopenharmony_ci{
2480159b3361Sopenharmony_ci    return global.hip;
2481159b3361Sopenharmony_ci}
2482159b3361Sopenharmony_ci
2483159b3361Sopenharmony_cisize_t
2484159b3361Sopenharmony_cisizeOfOldTag(lame_t gf)
2485159b3361Sopenharmony_ci{
2486159b3361Sopenharmony_ci    (void) gf;
2487159b3361Sopenharmony_ci    return global.in_id3v2_size;
2488159b3361Sopenharmony_ci}
2489159b3361Sopenharmony_ci
2490159b3361Sopenharmony_ciunsigned char*
2491159b3361Sopenharmony_cigetOldTag(lame_t gf)
2492159b3361Sopenharmony_ci{
2493159b3361Sopenharmony_ci    (void) gf;
2494159b3361Sopenharmony_ci    return global.in_id3v2_tag;
2495159b3361Sopenharmony_ci}
2496159b3361Sopenharmony_ci
2497159b3361Sopenharmony_ci/* end of get_audio.c */
2498