mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-14 01:49:05 +00:00
libsndfile: update to 1.0.19 (LBSNDF-7)
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0186 http://www.mega-nerd.com/libsndfile/libsndfile-1.0.19.tar.gz This will likely require a fresh boostrap to updated source checkouts. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13415 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2005 David Viens <davidv@plogue.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
@@ -58,6 +58,8 @@
|
||||
#define sowt_MARKER (MAKE_MARKER ('s', 'o', 'w', 't'))
|
||||
#define twos_MARKER (MAKE_MARKER ('t', 'w', 'o', 's'))
|
||||
#define raw_MARKER (MAKE_MARKER ('r', 'a', 'w', ' '))
|
||||
#define in24_MARKER (MAKE_MARKER ('i', 'n', '2', '4'))
|
||||
#define ni24_MARKER (MAKE_MARKER ('4', '2', 'n', '1'))
|
||||
#define in32_MARKER (MAKE_MARKER ('i', 'n', '3', '2'))
|
||||
#define ni32_MARKER (MAKE_MARKER ('2', '3', 'n', 'i'))
|
||||
|
||||
@@ -75,6 +77,14 @@
|
||||
#define GSM_MARKER (MAKE_MARKER ('G', 'S', 'M', ' '))
|
||||
#define ima4_MARKER (MAKE_MARKER ('i', 'm', 'a', '4'))
|
||||
|
||||
/*
|
||||
** This value is officially assigned to Mega Nerd Pty Ltd by Apple
|
||||
** Corportation as the Application marker for libsndfile.
|
||||
**
|
||||
** See : http://developer.apple.com/faq/datatype.html
|
||||
*/
|
||||
#define m3ga_MARKER (MAKE_MARKER ('m', '3', 'g', 'a'))
|
||||
|
||||
/* Unsupported AIFC encodings.*/
|
||||
|
||||
#define MAC3_MARKER (MAKE_MARKER ('M', 'A', 'C', '3'))
|
||||
@@ -172,8 +182,12 @@ typedef struct
|
||||
} MARK_ID_POS ;
|
||||
|
||||
typedef struct
|
||||
{ sf_count_t comm_offset ;
|
||||
{ PRIV_CHUNK4 chunk4 ;
|
||||
|
||||
sf_count_t comm_offset ;
|
||||
sf_count_t ssnd_offset ;
|
||||
|
||||
MARK_ID_POS *markstr ;
|
||||
} AIFF_PRIVATE ;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
@@ -214,7 +228,7 @@ aiff_open (SF_PRIVATE *psf)
|
||||
|
||||
memset (&comm_fmt, 0, sizeof (comm_fmt)) ;
|
||||
|
||||
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
|
||||
subformat = SF_CODEC (psf->sf.format) ;
|
||||
|
||||
if ((psf->container_data = calloc (1, sizeof (AIFF_PRIVATE))) == NULL)
|
||||
return SFE_MALLOC_FAILED ;
|
||||
@@ -222,7 +236,6 @@ aiff_open (SF_PRIVATE *psf)
|
||||
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
|
||||
{ if ((error = aiff_read_header (psf, &comm_fmt)))
|
||||
return error ;
|
||||
|
||||
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
|
||||
} ;
|
||||
|
||||
@@ -230,7 +243,7 @@ aiff_open (SF_PRIVATE *psf)
|
||||
{ if (psf->is_pipe)
|
||||
return SFE_NO_PIPE_WRITE ;
|
||||
|
||||
if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AIFF)
|
||||
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_AIFF)
|
||||
return SFE_BAD_OPEN_FORMAT ;
|
||||
|
||||
if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
|
||||
@@ -257,7 +270,7 @@ aiff_open (SF_PRIVATE *psf)
|
||||
psf->container_close = aiff_close ;
|
||||
psf->command = aiff_command ;
|
||||
|
||||
switch (psf->sf.format & SF_FORMAT_SUBMASK)
|
||||
switch (SF_CODEC (psf->sf.format))
|
||||
{ case SF_FORMAT_PCM_U8 :
|
||||
error = pcm_init (psf) ;
|
||||
break ;
|
||||
@@ -353,13 +366,15 @@ marker_to_position (const MARK_ID_POS *m, unsigned short n, int marksize)
|
||||
static int
|
||||
aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
{ SSND_CHUNK ssnd_fmt ;
|
||||
MARK_ID_POS *markstr = NULL ;
|
||||
AIFF_PRIVATE *paiff ;
|
||||
unsigned marker, dword, FORMsize, SSNDsize, bytesread ;
|
||||
int k, found_chunk = 0, done = 0, error = 0 ;
|
||||
char *cptr, byte ;
|
||||
int instr_found = 0, mark_found = 0, mark_count = 0 ;
|
||||
|
||||
if (psf->filelength > SF_PLATFORM_S64 (0xffffffff))
|
||||
psf_log_printf (psf, "Warning : filelength > 0xffffffff. This is bad!!!!\n") ;
|
||||
|
||||
if ((paiff = psf->container_data) == NULL)
|
||||
return SFE_INTERNAL ;
|
||||
|
||||
@@ -390,6 +405,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
return SFE_AIFF_NO_FORM ;
|
||||
|
||||
psf_binheader_readf (psf, "E4", &FORMsize) ;
|
||||
pchk4_store (&(paiff->chunk4), marker, psf->headindex - 8, FORMsize) ;
|
||||
|
||||
if (psf->fileoffset > 0 && psf->filelength > FORMsize + 8)
|
||||
{ /* Set file length. */
|
||||
@@ -417,6 +433,8 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
case COMM_MARKER :
|
||||
paiff->comm_offset = psf_ftell (psf) - 4 ;
|
||||
error = aiff_read_comm_chunk (psf, comm_fmt) ;
|
||||
pchk4_store (&paiff->chunk4, marker, paiff->comm_offset, comm_fmt->size) ;
|
||||
|
||||
|
||||
psf->sf.samplerate = tenbytefloat2int (comm_fmt->sampleRate) ;
|
||||
psf->sf.frames = comm_fmt->numSampleFrames ;
|
||||
@@ -435,6 +453,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
return SFE_AIFF_PEAK_B4_COMM ;
|
||||
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf->headindex - 8, dword) ;
|
||||
|
||||
psf_log_printf (psf, "%M : %d\n", marker, dword) ;
|
||||
if (dword != AIFF_PEAK_CHUNK_SIZE (psf->sf.channels))
|
||||
@@ -466,20 +485,22 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
psf->peak_info->peaks [dword].value = value ;
|
||||
psf->peak_info->peaks [dword].position = position ;
|
||||
|
||||
LSF_SNPRINTF (cptr, sizeof (psf->u.scbuf), " %2d %-12ld %g\n",
|
||||
snprintf (cptr, sizeof (psf->u.scbuf), " %2d %-12ld %g\n",
|
||||
dword, (long) psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
|
||||
cptr [sizeof (psf->u.scbuf) - 1] = 0 ;
|
||||
psf_log_printf (psf, cptr) ;
|
||||
} ;
|
||||
|
||||
psf->peak_info->peak_loc = ((found_chunk & HAVE_SSND) == 0) ? SF_PEAK_START : SF_PEAK_END ;
|
||||
break ;
|
||||
|
||||
case SSND_MARKER :
|
||||
if ((found_chunk & HAVE_AIFC) && (found_chunk & HAVE_FVER) == 0)
|
||||
psf_log_printf (psf, "*** Valid AIFC files should have an FVER chunk.\n") ;
|
||||
|
||||
|
||||
paiff->ssnd_offset = psf_ftell (psf) - 4 ;
|
||||
psf_binheader_readf (psf, "E444", &SSNDsize, &(ssnd_fmt.offset), &(ssnd_fmt.blocksize)) ;
|
||||
pchk4_store (&paiff->chunk4, marker, paiff->ssnd_offset, SSNDsize) ;
|
||||
|
||||
psf->datalength = SSNDsize - sizeof (ssnd_fmt) ;
|
||||
psf->dataoffset = psf_ftell (psf) ;
|
||||
@@ -491,27 +512,37 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
else
|
||||
psf_log_printf (psf, " SSND : %u\n", SSNDsize) ;
|
||||
|
||||
if (ssnd_fmt.offset == 0 || psf->dataoffset + ssnd_fmt.offset == ssnd_fmt.blocksize)
|
||||
{ psf_log_printf (psf, " Offset : %u\n", ssnd_fmt.offset) ;
|
||||
psf_log_printf (psf, " Block Size : %u\n", ssnd_fmt.blocksize) ;
|
||||
|
||||
psf->dataoffset += ssnd_fmt.offset ;
|
||||
psf->datalength -= ssnd_fmt.offset ;
|
||||
}
|
||||
else
|
||||
{ psf_log_printf (psf, " Offset : %u (Should be zero)\n", ssnd_fmt.offset) ;
|
||||
psf_log_printf (psf, " Block Size : %u ???\n", ssnd_fmt.blocksize) ;
|
||||
} ;
|
||||
|
||||
/* Only set dataend if there really is data at the end. */
|
||||
if (psf->datalength + psf->dataoffset < psf->filelength)
|
||||
psf->dataend = psf->datalength + psf->dataoffset ;
|
||||
|
||||
psf_log_printf (psf, " Offset : %u\n", ssnd_fmt.offset) ;
|
||||
psf_log_printf (psf, " Block Size : %u\n", ssnd_fmt.blocksize) ;
|
||||
|
||||
found_chunk |= HAVE_SSND ;
|
||||
|
||||
if (! psf->sf.seekable)
|
||||
break ;
|
||||
|
||||
/* Seek to end of SSND chunk. */
|
||||
/* Seek to end of SSND chunk. */
|
||||
psf_fseek (psf, psf->dataoffset + psf->datalength + (SSNDsize & 1), SEEK_SET) ;
|
||||
break ;
|
||||
|
||||
case c_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1)
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf))
|
||||
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
|
||||
return SFE_INTERNAL ;
|
||||
} ;
|
||||
@@ -519,15 +550,19 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
cptr = psf->u.cbuf ;
|
||||
psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
|
||||
cptr [dword] = 0 ;
|
||||
|
||||
psf_sanitize_string (cptr, dword) ;
|
||||
|
||||
psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
|
||||
psf_store_string (psf, SF_STR_COPYRIGHT, cptr) ;
|
||||
break ;
|
||||
|
||||
case AUTH_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1)
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
|
||||
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
|
||||
return SFE_INTERNAL ;
|
||||
} ;
|
||||
@@ -544,6 +579,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
unsigned int timestamp ;
|
||||
|
||||
psf_binheader_readf (psf, "E42", &dword, &count) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " %M : %d\n count : %d\n", marker, dword, count) ;
|
||||
dword += (dword & 1) ;
|
||||
if (dword == 0)
|
||||
@@ -571,7 +607,10 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
break ;
|
||||
|
||||
case APPL_MARKER :
|
||||
{ unsigned appl_marker ;
|
||||
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
|
||||
@@ -580,8 +619,14 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
break ;
|
||||
} ;
|
||||
|
||||
if (dword < 4)
|
||||
{ psf_log_printf (psf, " %M : %d (too small, skipping)\n", marker, dword) ;
|
||||
psf_binheader_readf (psf, "j", dword + (dword & 1)) ;
|
||||
break ;
|
||||
} ;
|
||||
|
||||
cptr = psf->u.cbuf ;
|
||||
psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
|
||||
psf_binheader_readf (psf, "mb", &appl_marker, cptr, dword + (dword & 1) - 4) ;
|
||||
cptr [dword] = 0 ;
|
||||
|
||||
for (k = 0 ; k < (int) dword ; k++)
|
||||
@@ -590,15 +635,17 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
break ;
|
||||
} ;
|
||||
|
||||
psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
|
||||
psf_log_printf (psf, " %M : %d\n AppSig : %M\n Name : %s\n", marker, dword, appl_marker, cptr) ;
|
||||
psf_store_string (psf, SF_STR_SOFTWARE, cptr) ;
|
||||
} ;
|
||||
break ;
|
||||
|
||||
case NAME_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 2)
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 2)
|
||||
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
|
||||
return SFE_INTERNAL ;
|
||||
} ;
|
||||
@@ -612,9 +659,10 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case ANNO_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 2)
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 2)
|
||||
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
|
||||
return SFE_INTERNAL ;
|
||||
} ;
|
||||
@@ -628,6 +676,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case INST_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword != SIZEOF_INST_CHUNK)
|
||||
{ psf_log_printf (psf, " %M : %d (should be %d)\n", marker, dword, SIZEOF_INST_CHUNK) ;
|
||||
psf_binheader_readf (psf, "j", dword) ;
|
||||
@@ -679,7 +728,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
loop_mode = get_loop_mode_str (mode) ;
|
||||
mode = get_loop_mode (mode) ;
|
||||
if (mode == SF_LOOP_NONE)
|
||||
psf->instrument->loops [0].mode = SF_LOOP_NONE ;
|
||||
psf->instrument->loops [1].mode = SF_LOOP_NONE ;
|
||||
else
|
||||
{ psf->instrument->loop_count += 1 ;
|
||||
psf->instrument->loops [1].mode = SF_LOOP_FORWARD ;
|
||||
@@ -695,6 +744,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case basc_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " basc : %u\n", dword) ;
|
||||
|
||||
if ((error = aiff_read_basc_chunk (psf, dword)))
|
||||
@@ -703,6 +753,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case MARK_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
|
||||
{ unsigned short mark_id, n = 0 ;
|
||||
unsigned char pstr_len ;
|
||||
@@ -710,20 +761,27 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
bytesread = psf_binheader_readf (psf, "E2", &n) ;
|
||||
mark_count = n ;
|
||||
markstr = calloc (mark_count, sizeof (MARK_ID_POS)) ;
|
||||
psf_log_printf (psf, " Count : %d\n", mark_count) ;
|
||||
if (paiff->markstr != NULL)
|
||||
{ psf_log_printf (psf, "*** Second MARK chunk found. Throwing away the first.\n") ;
|
||||
free (paiff->markstr) ;
|
||||
} ;
|
||||
paiff->markstr = calloc (mark_count, sizeof (MARK_ID_POS)) ;
|
||||
if (paiff->markstr == NULL)
|
||||
return SFE_MALLOC_FAILED ;
|
||||
|
||||
for (n = 0 ; n < mark_count && bytesread < dword ; n++)
|
||||
{ bytesread += psf_binheader_readf (psf, "E241", &mark_id, &position, &pstr_len) ;
|
||||
psf_log_printf (psf, " Mark ID : %u\n Position : %u\n", mark_id, position) ;
|
||||
|
||||
pstr_len += (pstr_len & 1) + 1 ; /* fudgy, fudgy, hack, hack */
|
||||
pstr_len += (pstr_len & 1) ? 0 : 1 ;
|
||||
|
||||
bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, pstr_len) ;
|
||||
psf->u.scbuf [pstr_len] = 0 ;
|
||||
psf_log_printf (psf, " Name : %s\n", psf->u.scbuf) ;
|
||||
|
||||
markstr [n].markerID = mark_id ;
|
||||
markstr [n].position = position ;
|
||||
paiff->markstr [n].markerID = mark_id ;
|
||||
paiff->markstr [n].position = position ;
|
||||
/*
|
||||
** TODO if psf->u.scbuf is equal to
|
||||
** either Beg_loop, Beg loop or beg loop and spam
|
||||
@@ -742,6 +800,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case SFX_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
|
||||
|
||||
psf_binheader_readf (psf, "j", dword) ;
|
||||
@@ -786,16 +845,13 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
for (j = 0 ; j<psf->instrument->loop_count ; j ++)
|
||||
{ if (j < ARRAY_LEN (psf->instrument->loops))
|
||||
{ psf->instrument->loops [j].start = marker_to_position (markstr, psf->instrument->loops [j].start, mark_count) ;
|
||||
psf->instrument->loops [j].end = marker_to_position (markstr, psf->instrument->loops [j].end, mark_count) ;
|
||||
{ psf->instrument->loops [j].start = marker_to_position (paiff->markstr, psf->instrument->loops [j].start, mark_count) ;
|
||||
psf->instrument->loops [j].end = marker_to_position (paiff->markstr, psf->instrument->loops [j].end, mark_count) ;
|
||||
psf->instrument->loops [j].mode = SF_LOOP_FORWARD ;
|
||||
} ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
if (markstr)
|
||||
free (markstr) ;
|
||||
|
||||
if (! (found_chunk & HAVE_FORM))
|
||||
return SFE_AIFF_NO_FORM ;
|
||||
|
||||
@@ -813,7 +869,13 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
static int
|
||||
aiff_close (SF_PRIVATE *psf)
|
||||
{
|
||||
{ AIFF_PRIVATE *paiff = psf->container_data ;
|
||||
|
||||
if (paiff != NULL && paiff->markstr != NULL)
|
||||
{ free (paiff->markstr) ;
|
||||
paiff->markstr = NULL ;
|
||||
} ;
|
||||
|
||||
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
|
||||
{ aiff_write_tailer (psf) ;
|
||||
aiff_write_header (psf, SF_TRUE) ;
|
||||
@@ -840,23 +902,31 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames),
|
||||
&(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ;
|
||||
|
||||
if (comm_fmt->size > 0x10000 && (comm_fmt->size & 0xffff) == 0)
|
||||
{ psf_log_printf (psf, " COMM : %d (0x%x) *** should be ", comm_fmt->size, comm_fmt->size) ;
|
||||
comm_fmt->size = ENDSWAP_INT (comm_fmt->size) ;
|
||||
psf_log_printf (psf, "%d (0x%x)\n", comm_fmt->size, comm_fmt->size) ;
|
||||
}
|
||||
else
|
||||
psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
|
||||
|
||||
if (comm_fmt->size == SIZEOF_AIFF_COMM)
|
||||
comm_fmt->encoding = NONE_MARKER ;
|
||||
else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN)
|
||||
bytesread += psf_binheader_readf (psf, "Em", &(comm_fmt->encoding)) ;
|
||||
else if (comm_fmt->size >= SIZEOF_AIFC_COMM)
|
||||
{ unsigned char encoding_len ;
|
||||
unsigned read_len ;
|
||||
|
||||
bytesread += psf_binheader_readf (psf, "Em1", &(comm_fmt->encoding), &encoding_len) ;
|
||||
|
||||
comm_fmt->size = SF_MIN (sizeof (psf->u.scbuf), make_size_t (comm_fmt->size)) ;
|
||||
memset (psf->u.scbuf, 0, comm_fmt->size) ;
|
||||
|
||||
bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf,
|
||||
comm_fmt->size - SIZEOF_AIFC_COMM + 1) ;
|
||||
psf->u.scbuf [encoding_len] = 0 ;
|
||||
read_len = comm_fmt->size - SIZEOF_AIFC_COMM + 1 ;
|
||||
bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, read_len) ;
|
||||
psf->u.scbuf [read_len + 1] = 0 ;
|
||||
} ;
|
||||
|
||||
psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
|
||||
psf_log_printf (psf, " Sample Rate : %d\n", tenbytefloat2int (comm_fmt->sampleRate)) ;
|
||||
psf_log_printf (psf, " Frames : %u%s\n", comm_fmt->numSampleFrames, (comm_fmt->numSampleFrames == 0 && psf->filelength > 104) ? " (Should not be 0)" : "") ;
|
||||
psf_log_printf (psf, " Channels : %d\n", comm_fmt->numChannels) ;
|
||||
@@ -883,11 +953,13 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
break ;
|
||||
|
||||
case twos_MARKER :
|
||||
case in24_MARKER :
|
||||
case in32_MARKER :
|
||||
psf->sf.format = (SF_ENDIAN_BIG | SF_FORMAT_AIFF | subformat) ;
|
||||
break ;
|
||||
|
||||
case sowt_MARKER :
|
||||
case ni24_MARKER :
|
||||
case ni32_MARKER :
|
||||
psf->endian = SF_ENDIAN_LITTLE ;
|
||||
psf->sf.format = (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | subformat) ;
|
||||
@@ -961,13 +1033,71 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
} /* aiff_read_comm_chunk */
|
||||
|
||||
|
||||
/*==========================================================================================
|
||||
*/
|
||||
|
||||
static int
|
||||
aiff_rewrite_header (SF_PRIVATE *psf, AIFF_PRIVATE * paiff)
|
||||
{
|
||||
/* Assuming here that the header has already been written and just
|
||||
** needs to be corrected for new data length. That means that we
|
||||
** only change the length fields of the FORM and SSND chunks ;
|
||||
** everything else can be skipped over.
|
||||
*/
|
||||
int k, ch ;
|
||||
int comm_size, comm_frames ;
|
||||
|
||||
psf_fseek (psf, 0, SEEK_SET) ;
|
||||
psf_fread (psf->header, psf->dataoffset, 1, psf) ;
|
||||
|
||||
psf->headindex = 0 ;
|
||||
|
||||
for (k = 0 ; k < paiff->chunk4.count ; k++)
|
||||
{ switch (paiff->chunk4.l [k].chunk)
|
||||
{ case FORM_MARKER :
|
||||
psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
|
||||
break ;
|
||||
|
||||
case COMM_MARKER :
|
||||
psf->headindex = paiff->chunk4.l [k].offset ;
|
||||
comm_frames = psf->sf.frames ;
|
||||
comm_size = paiff->chunk4.l [k].len ;
|
||||
psf_binheader_writef (psf, "Em42t4", COMM_MARKER, comm_size, psf->sf.channels, comm_frames) ;
|
||||
break ;
|
||||
|
||||
case SSND_MARKER :
|
||||
psf->headindex = paiff->chunk4.l [k].offset ;
|
||||
psf_binheader_writef (psf, "Etm8", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK) ;
|
||||
break ;
|
||||
|
||||
case PEAK_MARKER :
|
||||
psf->headindex = paiff->chunk4.l [k].offset ;
|
||||
psf_binheader_writef (psf, "Em4", PEAK_MARKER, AIFF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
|
||||
psf_binheader_writef (psf, "E44", 1, time (NULL)) ;
|
||||
for (ch = 0 ; ch < psf->sf.channels ; ch++)
|
||||
psf_binheader_writef (psf, "Eft8", (float) psf->peak_info->peaks [ch].value, psf->peak_info->peaks [ch].position) ;
|
||||
break ;
|
||||
|
||||
default :
|
||||
/* There are a whole bunch of chunks we should just ignore. */
|
||||
break ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
/* Header mangling complete so write it out. */
|
||||
psf_fseek (psf, 0, SEEK_SET) ;
|
||||
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
|
||||
|
||||
return 0 ;
|
||||
} /* aiff_rewrite_header */
|
||||
|
||||
static int
|
||||
aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
{ sf_count_t current ;
|
||||
AIFF_PRIVATE *paiff ;
|
||||
unsigned char comm_sample_rate [10], comm_zero_bytes [2] = { 0, 0 } ;
|
||||
unsigned int comm_type, comm_size, comm_encoding, comm_frames ;
|
||||
int k, endian ;
|
||||
unsigned int comm_type, comm_size, comm_encoding, comm_frames = 0 ;
|
||||
int k, endian, has_data = SF_FALSE ;
|
||||
short bit_width ;
|
||||
|
||||
if ((paiff = psf->container_data) == NULL)
|
||||
@@ -975,6 +1105,9 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
|
||||
current = psf_ftell (psf) ;
|
||||
|
||||
if (current > psf->dataoffset)
|
||||
has_data = SF_TRUE ;
|
||||
|
||||
if (calc_length)
|
||||
{ psf->filelength = psf_get_filelen (psf) ;
|
||||
|
||||
@@ -986,43 +1119,14 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
|
||||
} ;
|
||||
|
||||
if (psf->mode == SFM_RDWR && psf->dataoffset > 0)
|
||||
{ /* Assuming here that the header has already been written and just
|
||||
** needs to be corrected for new data length. That means that we
|
||||
** only change the length fields of the FORM and SSND chunks ;
|
||||
** everything else can be skipped over.
|
||||
*/
|
||||
|
||||
/* First write new FORM chunk. */
|
||||
psf->headindex = 0 ;
|
||||
psf_fseek (psf, 0, SEEK_SET) ;
|
||||
|
||||
psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
|
||||
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
|
||||
|
||||
/* Now write frame count field of COMM chunk header. */
|
||||
psf->headindex = 0 ;
|
||||
psf_fseek (psf, paiff->comm_offset + 10, SEEK_SET) ;
|
||||
|
||||
psf_binheader_writef (psf, "Et8", psf->sf.frames) ;
|
||||
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
|
||||
|
||||
/* Now write new SSND chunk header. */
|
||||
psf->headindex = 0 ;
|
||||
psf_fseek (psf, paiff->ssnd_offset, SEEK_SET) ;
|
||||
|
||||
psf_binheader_writef (psf, "Etm8", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK) ;
|
||||
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
|
||||
|
||||
if (current < psf->dataoffset)
|
||||
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
|
||||
else if (current > 0)
|
||||
if (psf->mode == SFM_RDWR && psf->dataoffset > 0 && paiff->chunk4.count > 0)
|
||||
{ int err = aiff_rewrite_header (psf, paiff) ;
|
||||
if (current > 0)
|
||||
psf_fseek (psf, current, SEEK_SET) ;
|
||||
|
||||
return 0 ;
|
||||
return err ;
|
||||
} ;
|
||||
|
||||
endian = psf->sf.format & SF_FORMAT_ENDMASK ;
|
||||
endian = SF_ENDIAN (psf->sf.format) ;
|
||||
if (CPU_IS_LITTLE_ENDIAN && endian == SF_ENDIAN_CPU)
|
||||
endian = SF_ENDIAN_LITTLE ;
|
||||
|
||||
@@ -1030,7 +1134,7 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
bit_width = psf->bytewidth * 8 ;
|
||||
comm_frames = (psf->sf.frames > 0xFFFFFFFF) ? 0xFFFFFFFF : psf->sf.frames ;
|
||||
|
||||
switch (psf->sf.format & SF_FORMAT_SUBMASK)
|
||||
switch (SF_CODEC (psf->sf.format))
|
||||
{ case SF_FORMAT_PCM_S8 :
|
||||
case SF_FORMAT_PCM_16 :
|
||||
case SF_FORMAT_PCM_24 :
|
||||
@@ -1158,16 +1262,16 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
/* Write AIFF/AIFC marker and COM chunk. */
|
||||
if (comm_type == AIFC_MARKER)
|
||||
/* AIFC must have an FVER chunk. */
|
||||
psf_binheader_writef (psf, "Emm44m4", comm_type, FVER_MARKER, 4, 0xA2805140, COMM_MARKER, comm_size) ;
|
||||
psf_binheader_writef (psf, "Emm44", comm_type, FVER_MARKER, 4, 0xA2805140) ;
|
||||
else
|
||||
psf_binheader_writef (psf, "Emm4", comm_type, COMM_MARKER, comm_size) ;
|
||||
psf_binheader_writef (psf, "Em", comm_type) ;
|
||||
|
||||
paiff->comm_offset = psf->headindex - 8 ;
|
||||
|
||||
memset (comm_sample_rate, 0, sizeof (comm_sample_rate)) ;
|
||||
uint2tenbytefloat (psf->sf.samplerate, comm_sample_rate) ;
|
||||
|
||||
psf_binheader_writef (psf, "Et242", psf->sf.channels, comm_frames, bit_width) ;
|
||||
psf_binheader_writef (psf, "Em42t42", COMM_MARKER, comm_size, psf->sf.channels, comm_frames, bit_width) ;
|
||||
psf_binheader_writef (psf, "b", comm_sample_rate, sizeof (comm_sample_rate)) ;
|
||||
|
||||
/* AIFC chunks have some extra data. */
|
||||
@@ -1253,9 +1357,12 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
if (psf->error)
|
||||
return psf->error ;
|
||||
|
||||
if (has_data && psf->dataoffset != psf->headindex)
|
||||
return psf->error = SFE_INTERNAL ;
|
||||
|
||||
psf->dataoffset = psf->headindex ;
|
||||
|
||||
if (current < psf->dataoffset)
|
||||
if (! has_data)
|
||||
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
|
||||
else if (current > 0)
|
||||
psf_fseek (psf, current, SEEK_SET) ;
|
||||
@@ -1298,7 +1405,7 @@ aiff_write_tailer (SF_PRIVATE *psf)
|
||||
|
||||
static void
|
||||
aiff_write_strings (SF_PRIVATE *psf, int location)
|
||||
{ int k ;
|
||||
{ int k, slen ;
|
||||
|
||||
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
|
||||
{ if (psf->strings [k].type == 0)
|
||||
@@ -1309,7 +1416,8 @@ aiff_write_strings (SF_PRIVATE *psf, int location)
|
||||
|
||||
switch (psf->strings [k].type)
|
||||
{ case SF_STR_SOFTWARE :
|
||||
psf_binheader_writef (psf, "EmS", APPL_MARKER, psf->strings [k].str) ;
|
||||
slen = strlen (psf->strings [k].str) ;
|
||||
psf_binheader_writef (psf, "Em4mb", APPL_MARKER, slen + 4, m3ga_MARKER, psf->strings [k].str, make_size_t (slen + (slen & 1))) ;
|
||||
break ;
|
||||
|
||||
case SF_STR_TITLE :
|
||||
@@ -1340,17 +1448,8 @@ aiff_write_strings (SF_PRIVATE *psf, int location)
|
||||
} /* aiff_write_strings */
|
||||
|
||||
static int
|
||||
aiff_command (SF_PRIVATE *psf, int command, void *data, int datasize)
|
||||
aiff_command (SF_PRIVATE * UNUSED (psf), int UNUSED (command), void * UNUSED (data), int UNUSED (datasize))
|
||||
{
|
||||
/* Avoid compiler warnings. */
|
||||
psf = psf ;
|
||||
data = data ;
|
||||
datasize = datasize ;
|
||||
|
||||
switch (command)
|
||||
{ default : break ;
|
||||
} ;
|
||||
|
||||
return 0 ;
|
||||
} /* aiff_command */
|
||||
|
||||
@@ -1448,10 +1547,11 @@ static int
|
||||
aiff_read_basc_chunk (SF_PRIVATE * psf, int datasize)
|
||||
{ const char * type_str ;
|
||||
basc_CHUNK bc ;
|
||||
int count ;
|
||||
|
||||
psf_binheader_readf (psf, "E442", &bc.version, &bc.numBeats, &bc.rootNote) ;
|
||||
psf_binheader_readf (psf, "E222", &bc.scaleType, &bc.sigNumerator, &bc.sigDenominator) ;
|
||||
psf_binheader_readf (psf, "E2j", &bc.loopType, datasize - sizeof (bc)) ;
|
||||
count = psf_binheader_readf (psf, "E442", &bc.version, &bc.numBeats, &bc.rootNote) ;
|
||||
count += psf_binheader_readf (psf, "E222", &bc.scaleType, &bc.sigNumerator, &bc.sigDenominator) ;
|
||||
count += psf_binheader_readf (psf, "E2j", &bc.loopType, datasize - sizeof (bc)) ;
|
||||
|
||||
psf_log_printf (psf, " Version ? : %u\n Num Beats : %u\n Root Note : 0x%x\n",
|
||||
bc.version, bc.numBeats, bc.rootNote) ;
|
||||
@@ -1504,13 +1604,9 @@ aiff_read_basc_chunk (SF_PRIVATE * psf, int datasize)
|
||||
* ((bc.numBeats * 4.0) / bc.sigDenominator) * 60.0 ;
|
||||
psf->loop_info->root_key = bc.rootNote ;
|
||||
|
||||
if (count < datasize)
|
||||
psf_binheader_readf (psf, "j", datasize - count) ;
|
||||
|
||||
return 0 ;
|
||||
} /* aiff_read_basc_chunk */
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 7dec56ca-d6f2-48cf-863b-a72e7e17a5d9
|
||||
*/
|
||||
|
Reference in New Issue
Block a user