Fixed up CVS, added missing files.
This commit is contained in:
parent
38706770cc
commit
180dcd01f2
93 changed files with 30293 additions and 0 deletions
366
Libraries/FAAD2/Files/common/faad/aacinfo.c
Normal file
366
Libraries/FAAD2/Files/common/faad/aacinfo.c
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
//#include "filestream.h"
|
||||||
|
#include "aacinfo.h"
|
||||||
|
|
||||||
|
#define ADIF_MAX_SIZE 30 /* Should be enough */
|
||||||
|
#define ADTS_MAX_SIZE 10 /* Should be enough */
|
||||||
|
|
||||||
|
static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
|
||||||
|
|
||||||
|
static int read_ADIF_header(FILE *file, faadAACInfo *info)
|
||||||
|
{
|
||||||
|
int bitstream;
|
||||||
|
unsigned char buffer[ADIF_MAX_SIZE];
|
||||||
|
int skip_size = 0;
|
||||||
|
int sf_idx;
|
||||||
|
|
||||||
|
/* Get ADIF header data */
|
||||||
|
info->headertype = 1;
|
||||||
|
|
||||||
|
if(fread(buffer, 1, ADIF_MAX_SIZE, file) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* copyright string */
|
||||||
|
if(buffer[0] & 0x80)
|
||||||
|
skip_size += 9; /* skip 9 bytes */
|
||||||
|
|
||||||
|
bitstream = buffer[0 + skip_size] & 0x10;
|
||||||
|
info->bitrate = ((unsigned int)(buffer[0 + skip_size] & 0x0F)<<19)|
|
||||||
|
((unsigned int)buffer[1 + skip_size]<<11)|
|
||||||
|
((unsigned int)buffer[2 + skip_size]<<3)|
|
||||||
|
((unsigned int)buffer[3 + skip_size] & 0xE0);
|
||||||
|
|
||||||
|
if (bitstream == 0)
|
||||||
|
{
|
||||||
|
info->object_type = ((buffer[6 + skip_size]&0x01)<<1)|((buffer[7 + skip_size]&0x80)>>7);
|
||||||
|
sf_idx = (buffer[7 + skip_size]&0x78)>>3;
|
||||||
|
} else {
|
||||||
|
info->object_type = (buffer[4 + skip_size] & 0x18)>>3;
|
||||||
|
sf_idx = ((buffer[4 + skip_size] & 0x07)<<1)|((buffer[5 + skip_size] & 0x80)>>7);
|
||||||
|
}
|
||||||
|
info->sampling_rate = sample_rates[sf_idx];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_ADTS_header(FILE *file, faadAACInfo *info,
|
||||||
|
unsigned long **seek_table, int *seek_table_len,
|
||||||
|
int tagsize, int no_seek_table)
|
||||||
|
{
|
||||||
|
/* Get ADTS header data */
|
||||||
|
unsigned char buffer[ADTS_MAX_SIZE];
|
||||||
|
int frames, framesinsec=0, t_framelength = 0, frame_length, sr_idx, ID;
|
||||||
|
int second = 0, pos;
|
||||||
|
int i;
|
||||||
|
float frames_per_sec = 0;
|
||||||
|
unsigned long bytes;
|
||||||
|
unsigned long *tmp_seek_table = NULL;
|
||||||
|
|
||||||
|
info->headertype = 2;
|
||||||
|
|
||||||
|
/* Read all frames to ensure correct time and bitrate */
|
||||||
|
for(frames=0; /* */; frames++, framesinsec++)
|
||||||
|
{
|
||||||
|
/* If streaming, only go until we hit 5 seconds worth */
|
||||||
|
/* if(file->http)
|
||||||
|
{
|
||||||
|
if(frames >= 43 * 5)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
pos = ftell(file);//tell_filestream(file);
|
||||||
|
|
||||||
|
/* 12 bit SYNCWORD */
|
||||||
|
bytes = fread(buffer, 1, ADTS_MAX_SIZE, file);
|
||||||
|
|
||||||
|
if(bytes != ADTS_MAX_SIZE)
|
||||||
|
{
|
||||||
|
/* Bail out if no syncword found */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check syncword */
|
||||||
|
if (!((buffer[0] == 0xFF)&&((buffer[1] & 0xF6) == 0xF0)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(!frames)
|
||||||
|
{
|
||||||
|
/* fixed ADTS header is the same for every frame, so we read it only once */
|
||||||
|
/* Syncword found, proceed to read in the fixed ADTS header */
|
||||||
|
ID = buffer[1] & 0x08;
|
||||||
|
info->object_type = (buffer[2]&0xC0)>>6;
|
||||||
|
sr_idx = (buffer[2]&0x3C)>>2;
|
||||||
|
info->channels = ((buffer[2]&0x01)<<2)|((buffer[3]&0xC0)>>6);
|
||||||
|
|
||||||
|
frames_per_sec = sample_rates[sr_idx] / 1024.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ...and the variable ADTS header */
|
||||||
|
if (ID == 0) {
|
||||||
|
info->version = 4;
|
||||||
|
} else { /* MPEG-2 */
|
||||||
|
info->version = 2;
|
||||||
|
}
|
||||||
|
frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
|
||||||
|
| (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
|
||||||
|
|
||||||
|
t_framelength += frame_length;
|
||||||
|
|
||||||
|
// if(!file->http)
|
||||||
|
{
|
||||||
|
if(framesinsec == 43)
|
||||||
|
framesinsec = 0;
|
||||||
|
|
||||||
|
if(framesinsec == 0 && seek_table_len)
|
||||||
|
{
|
||||||
|
tmp_seek_table = (unsigned long *) realloc(tmp_seek_table, (second + 1) * sizeof(unsigned long));
|
||||||
|
tmp_seek_table[second] = pos;
|
||||||
|
}
|
||||||
|
if(framesinsec == 0)
|
||||||
|
second++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: While simply skipping ahead by reading may seem to be more work than seeking,
|
||||||
|
it is actually much faster, and keeps compatibility with streaming */
|
||||||
|
//F THAT
|
||||||
|
fseek(file, frame_length - ADTS_MAX_SIZE, SEEK_CUR);
|
||||||
|
/* for(i=0; i < frame_length - ADTS_MAX_SIZE; i++)
|
||||||
|
{
|
||||||
|
if(read_byte_filestream(file) < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if(seek_table_len)
|
||||||
|
{
|
||||||
|
*seek_table_len = second;
|
||||||
|
*seek_table = tmp_seek_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->sampling_rate = sample_rates[sr_idx];
|
||||||
|
info->bitrate = (int)(((t_framelength / frames) * (info->sampling_rate/1024.0)) +0.5)*8;
|
||||||
|
|
||||||
|
/* if(file->http)
|
||||||
|
{
|
||||||
|
// Since we only use 5 seconds of aac data to get a rough bitrate, we must use a different
|
||||||
|
// method of calculating the overall length
|
||||||
|
if(filelength_filestream(file))
|
||||||
|
{
|
||||||
|
info->length = (int)((filelength_filestream(file)/(((info->bitrate*8)/1024)*16))*1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Since the server didnt tell us how long the file is,
|
||||||
|
// we have no way of determining length
|
||||||
|
info->length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*/ {
|
||||||
|
info->length = (int)((float)(frames/frames_per_sec))*1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_AAC_format(FILE *file, faadAACInfo *info,
|
||||||
|
unsigned long **seek_table, int *seek_table_len,
|
||||||
|
int no_seek_table)
|
||||||
|
{
|
||||||
|
unsigned long tagsize;
|
||||||
|
char buffer[10];
|
||||||
|
unsigned long file_len;
|
||||||
|
unsigned char adxx_id[5];
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
memset(info, 0, sizeof(faadAACInfo));
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
file_len = ftell(file);
|
||||||
|
|
||||||
|
/* Skip the tag, if it's there */
|
||||||
|
tmp = fread(buffer, 1, 10, file);
|
||||||
|
|
||||||
|
if (StringComp(buffer, "ID3", 3) == 0)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* high bit is not used */
|
||||||
|
tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
|
||||||
|
(buffer[8] << 7) | (buffer[9] << 0);
|
||||||
|
|
||||||
|
fseek(file, tagsize, SEEK_CUR);
|
||||||
|
|
||||||
|
tagsize += 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tagsize = 0;
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_len)
|
||||||
|
file_len -= tagsize;
|
||||||
|
|
||||||
|
tmp = fread(adxx_id, 1, 2, file);
|
||||||
|
//seek_filestream(file, tagsize, FILE_BEGIN);
|
||||||
|
|
||||||
|
adxx_id[5-1] = 0;
|
||||||
|
info->length = 0;
|
||||||
|
|
||||||
|
/* Determine the header type of the file, check the first two bytes */
|
||||||
|
if(strncasecmp((char *)adxx_id, "AD", 2) == 0)
|
||||||
|
{
|
||||||
|
/* We think its an ADIF header, but check the rest just to make sure */
|
||||||
|
tmp = fread(adxx_id+2, 1, 2, file);
|
||||||
|
|
||||||
|
if(strncasecmp((char *)adxx_id, "ADIF", 4) == 0)
|
||||||
|
{
|
||||||
|
read_ADIF_header(file, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No ADIF, check for ADTS header */
|
||||||
|
if ((adxx_id[0] == 0xFF)&&((adxx_id[1] & 0xF6) == 0xF0))
|
||||||
|
{
|
||||||
|
/* ADTS header located */
|
||||||
|
/* Since this routine must work for streams, we can't use the seek function to go backwards, thus
|
||||||
|
we have to use a quick hack as seen below to go back where we need to. */
|
||||||
|
|
||||||
|
fseek(file, -2, SEEK_CUR);
|
||||||
|
/* if(file->buffer_offset >= 2)
|
||||||
|
{
|
||||||
|
// simple seeking hack, though not really safe, the probability of it causing a problem is low.
|
||||||
|
file->buffer_offset -= 2;
|
||||||
|
file->file_offset -= 2;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
read_ADTS_header(file, info, seek_table, seek_table_len, tagsize,
|
||||||
|
no_seek_table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unknown/headerless AAC file, assume format: */
|
||||||
|
info->version = 2;
|
||||||
|
info->bitrate = 128000;
|
||||||
|
info->sampling_rate = 44100;
|
||||||
|
info->channels = 2;
|
||||||
|
info->headertype = 0;
|
||||||
|
info->object_type = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringComp(char const *str1, char const *str2, unsigned long len)
|
||||||
|
{
|
||||||
|
signed int c1 = 0, c2 = 0;
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
c1 = *str1++;
|
||||||
|
c2 = *str2++;
|
||||||
|
|
||||||
|
if (c1 == 0 || c1 != c2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c1 - c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
/* Program to test aacinfo functionality */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
faadAACInfo info;
|
||||||
|
unsigned long *seek_table = NULL;
|
||||||
|
int seek_table_len = 0;
|
||||||
|
char *header, *object;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "USAGE: aacinfo aacfile.aac\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_AAC_format(argv[1], &info, &seek_table, &seek_table_len, 0);
|
||||||
|
|
||||||
|
fprintf(stdout, "MPEG version: %d\n", info.version);
|
||||||
|
fprintf(stdout, "channels: %d\n", info.channels);
|
||||||
|
fprintf(stdout, "sampling_rate: %d\n", info.sampling_rate);
|
||||||
|
fprintf(stdout, "bitrate: %d\n", info.bitrate);
|
||||||
|
fprintf(stdout, "length: %.3f\n", (float)info.length/1000.0);
|
||||||
|
|
||||||
|
switch (info.object_type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
object = "MAIN";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
object = "LC";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
object = "SSR";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
object = "LTP";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "object_type: %s\n", object);
|
||||||
|
|
||||||
|
switch (info.headertype)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
header = "RAW";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
header = "ADIF";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
header = "ADTS";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "headertype: %s\n", header);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
54
Libraries/FAAD2/Files/common/faad/aacinfo.h
Normal file
54
Libraries/FAAD2/Files/common/faad/aacinfo.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef AACINFO_H__
|
||||||
|
#define AACINFO_H__
|
||||||
|
|
||||||
|
//#include "filestream.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int version;
|
||||||
|
int channels;
|
||||||
|
int sampling_rate;
|
||||||
|
int bitrate;
|
||||||
|
int length;
|
||||||
|
int object_type;
|
||||||
|
int headertype;
|
||||||
|
} faadAACInfo;
|
||||||
|
|
||||||
|
int get_AAC_format(FILE *file, faadAACInfo *info,
|
||||||
|
unsigned long **seek_table, int *seek_table_len,
|
||||||
|
int no_seek_table);
|
||||||
|
|
||||||
|
static int read_ADIF_header(FILE *file, faadAACInfo *info);
|
||||||
|
static int read_ADTS_header(FILE *file, faadAACInfo *info,
|
||||||
|
unsigned long **seek_table, int *seek_table_len,
|
||||||
|
int tagsize, int no_seek_table);
|
||||||
|
int StringComp(char const *str1, char const *str2, unsigned long len);
|
||||||
|
|
||||||
|
#endif
|
470
Libraries/FAAD2/Files/common/faad/filestream.c
Normal file
470
Libraries/FAAD2/Files/common/faad/filestream.c
Normal file
|
@ -0,0 +1,470 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* Not very portable yet */
|
||||||
|
|
||||||
|
#include <winsock2.h> // Note: Must be *before* windows.h
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include "filestream.h"
|
||||||
|
#include "aacinfo.h"
|
||||||
|
|
||||||
|
/* TEMPROARY HACK */
|
||||||
|
#define CommonExit(A) MessageBox(NULL, A, "FAAD Plugin", MB_OK)
|
||||||
|
|
||||||
|
int winsock_init=0; // 0=winsock not initialized, 1=success
|
||||||
|
long m_local_buffer_size = 64;
|
||||||
|
long m_stream_buffer_size = 128;
|
||||||
|
|
||||||
|
FILE_STREAM *open_filestream(char *filename)
|
||||||
|
{
|
||||||
|
FILE_STREAM *fs;
|
||||||
|
|
||||||
|
if(StringComp(filename,"http://", 7) == 0)
|
||||||
|
{
|
||||||
|
fs = (FILE_STREAM *)LocalAlloc(LPTR, sizeof(FILE_STREAM) + m_stream_buffer_size * 1024);
|
||||||
|
|
||||||
|
if(fs == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fs->data = (unsigned char *)&fs[1];
|
||||||
|
|
||||||
|
if(http_file_open(filename, fs) < 0)
|
||||||
|
{
|
||||||
|
LocalFree(fs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs->http = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fs = (FILE_STREAM*)LocalAlloc(LPTR, sizeof(FILE_STREAM) + m_local_buffer_size * 1024);
|
||||||
|
|
||||||
|
if(fs == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fs->data = (unsigned char *)&fs[1];
|
||||||
|
|
||||||
|
fs->stream = CreateFile(filename, GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
|
||||||
|
if (fs->stream == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
LocalFree(fs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs->http = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs->buffer_length = 0;
|
||||||
|
fs->buffer_offset = 0;
|
||||||
|
fs->file_offset = 0;
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_byte_filestream(FILE_STREAM *fs)
|
||||||
|
{
|
||||||
|
if(fs->buffer_offset == fs->buffer_length)
|
||||||
|
{
|
||||||
|
fs->buffer_offset = 0;
|
||||||
|
|
||||||
|
if(fs->http)
|
||||||
|
fs->buffer_length = recv(fs->inetStream, fs->data, m_stream_buffer_size * 1024, 0);
|
||||||
|
else
|
||||||
|
ReadFile(fs->stream, fs->data, m_local_buffer_size * 1024, &fs->buffer_length, 0);
|
||||||
|
|
||||||
|
if(fs->buffer_length <= 0)
|
||||||
|
{
|
||||||
|
if(fs->http)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
x = WSAGetLastError();
|
||||||
|
|
||||||
|
if(x == 0)
|
||||||
|
{
|
||||||
|
/* Equivalent of a successful EOF for HTTP */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs->buffer_length = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs->file_offset++;
|
||||||
|
|
||||||
|
return fs->data[fs->buffer_offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_buffer_filestream(FILE_STREAM *fs, void *data, int length)
|
||||||
|
{
|
||||||
|
int i, tmp;
|
||||||
|
unsigned char *data2 = (unsigned char *)data;
|
||||||
|
|
||||||
|
for(i=0; i < length; i++)
|
||||||
|
{
|
||||||
|
if((tmp = read_byte_filestream(fs)) < 0)
|
||||||
|
{
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data2[i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long filelength_filestream(FILE_STREAM *fs)
|
||||||
|
{
|
||||||
|
unsigned long fsize;
|
||||||
|
|
||||||
|
if (fs->http)
|
||||||
|
{
|
||||||
|
fsize = fs->http_file_length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fsize = GetFileSize(fs->stream, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void seek_filestream(FILE_STREAM *fs, unsigned long offset, int mode)
|
||||||
|
{
|
||||||
|
if(fs->http)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFilePointer(fs->stream, offset, NULL, mode);
|
||||||
|
|
||||||
|
if(mode == FILE_CURRENT)
|
||||||
|
fs->file_offset += offset;
|
||||||
|
else if(mode == FILE_END)
|
||||||
|
fs->file_offset = filelength_filestream(fs) + offset;
|
||||||
|
else
|
||||||
|
fs->file_offset = offset;
|
||||||
|
|
||||||
|
fs->buffer_length = 0;
|
||||||
|
fs->buffer_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long tell_filestream(FILE_STREAM *fs)
|
||||||
|
{
|
||||||
|
return fs->file_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_filestream(FILE_STREAM *fs)
|
||||||
|
{
|
||||||
|
if(fs)
|
||||||
|
{
|
||||||
|
if (fs->http)
|
||||||
|
{
|
||||||
|
if (fs->inetStream)
|
||||||
|
{
|
||||||
|
/* The 'proper' way to close a TCP connection */
|
||||||
|
if(fs->inetStream)
|
||||||
|
{
|
||||||
|
CloseTCP(fs->inetStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fs->stream)
|
||||||
|
CloseHandle(fs->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalFree(fs);
|
||||||
|
fs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WinsockInit()
|
||||||
|
{
|
||||||
|
/* Before using winsock, you must load the DLL... */
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
/* Load version 2.0 */
|
||||||
|
if (WSAStartup( MAKEWORD( 2, 0 ), &wsaData ))
|
||||||
|
{
|
||||||
|
/* Disable streaming */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
winsock_init = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinsockDeInit()
|
||||||
|
{
|
||||||
|
/* Unload the DLL */
|
||||||
|
|
||||||
|
if(winsock_init)
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FindCRLF(char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i != lstrlen(str) && str[i] != '\r'; i++);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseTCP(int s)
|
||||||
|
{
|
||||||
|
char tempbuf[1024];
|
||||||
|
|
||||||
|
/* Set the socket to ignore any new incoming data */
|
||||||
|
shutdown(s, 1);
|
||||||
|
|
||||||
|
/* Get any old remaining data */
|
||||||
|
while(recv(s, tempbuf, 1024, 0) > 0);
|
||||||
|
|
||||||
|
/* Deallocate the socket */
|
||||||
|
closesocket(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolve_host(char *host, SOCKADDR_IN *sck_addr, unsigned short remote_port)
|
||||||
|
{
|
||||||
|
HOSTENT *hp;
|
||||||
|
|
||||||
|
if (isalpha(host[0]))
|
||||||
|
{
|
||||||
|
/* server address is a name */
|
||||||
|
hp = gethostbyname(host);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned long addr;
|
||||||
|
/* Convert nnn.nnn address to a usable one */
|
||||||
|
addr = inet_addr(host);
|
||||||
|
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hp == NULL)
|
||||||
|
{
|
||||||
|
char tmp[128];
|
||||||
|
wsprintf(tmp, "Error resolving host address [%s]!\n", host);
|
||||||
|
CommonExit(tmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(sck_addr, sizeof(SOCKADDR_IN));
|
||||||
|
sck_addr->sin_family = AF_INET;
|
||||||
|
sck_addr->sin_port = htons(remote_port);
|
||||||
|
CopyMemory(&sck_addr->sin_addr, hp->h_addr, hp->h_length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int http_file_open(char *url, FILE_STREAM *fs)
|
||||||
|
{
|
||||||
|
SOCKET sck;
|
||||||
|
SOCKADDR_IN host;
|
||||||
|
char server[1024], file[1024], request[1024], *temp = NULL, *tmpfile = NULL;
|
||||||
|
int i, j, port = 80, bytes_recv, http_code;
|
||||||
|
|
||||||
|
/* No winsock, no streaming */
|
||||||
|
if(!winsock_init)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
url += 7; // Skip over http://
|
||||||
|
|
||||||
|
/* Extract data from the URL */
|
||||||
|
for(i=0; url[i] != '/' && url[i] != ':' && url[i] != 0; i++);
|
||||||
|
|
||||||
|
ZeroMemory(server, 1024);
|
||||||
|
CopyMemory(server, url, i);
|
||||||
|
|
||||||
|
if(url[i] == ':')
|
||||||
|
{
|
||||||
|
/* A certain port was specified */
|
||||||
|
port = atol(url + (i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; url[i] != '/' && url[i] != 0; i++);
|
||||||
|
|
||||||
|
ZeroMemory(file, 1024);
|
||||||
|
|
||||||
|
CopyMemory(file, url + i, lstrlen(url));
|
||||||
|
|
||||||
|
/* END OF URL PARSING */
|
||||||
|
|
||||||
|
/* Create a TCP/IP socket */
|
||||||
|
sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
if(sck == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
CommonExit("Error creating TCP/IP new socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resolve the host address (turn www.blah.com into an IP) */
|
||||||
|
if(resolve_host(server, &host, (unsigned short)port))
|
||||||
|
{
|
||||||
|
CommonExit("Error resolving host address");
|
||||||
|
CloseTCP(sck);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to the server */
|
||||||
|
if(connect(sck, (SOCKADDR *)&host, sizeof(SOCKADDR)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
CommonExit("Error connecting to remote server");
|
||||||
|
CloseTCP(sck);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpfile = calloc(1, (strlen(file) * 3) + 1);
|
||||||
|
|
||||||
|
/* Encode URL */
|
||||||
|
for(i=0, j=0; i < (int)strlen(file); i++)
|
||||||
|
{
|
||||||
|
if((unsigned char)file[i] <= 31 || (unsigned char)file[i] >= 127)
|
||||||
|
{
|
||||||
|
/* encode ASCII-control characters */
|
||||||
|
wsprintf(tmpfile + j, "%%%X", (unsigned char)file[i]);
|
||||||
|
j += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(file[i])
|
||||||
|
{
|
||||||
|
/* encode characters that could confuse some servers */
|
||||||
|
case ' ':
|
||||||
|
case '"':
|
||||||
|
case '>':
|
||||||
|
case '<':
|
||||||
|
case '#':
|
||||||
|
case '%':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case '|':
|
||||||
|
case '\\':
|
||||||
|
case '^':
|
||||||
|
case '~':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '`':
|
||||||
|
|
||||||
|
wsprintf(tmpfile + j, "%%%X", (unsigned char)file[i]);
|
||||||
|
j += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpfile[j] = file[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wsprintf(request, "GET %s\r\n\r\n", tmpfile);
|
||||||
|
|
||||||
|
free(tmpfile);
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
if(send(sck, request, lstrlen(request), 0) <= 0)
|
||||||
|
{
|
||||||
|
/* Error sending data */
|
||||||
|
CloseTCP(sck);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(request, 1024);
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
if((bytes_recv = recv(sck, request, 1024, 0)) <= 0)
|
||||||
|
{
|
||||||
|
/* Error sending data */
|
||||||
|
CloseTCP(sck);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringComp(request,"HTTP/1.", 7) != 0)
|
||||||
|
{
|
||||||
|
/* Invalid header */
|
||||||
|
CloseTCP(sck);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
http_code = atol(request + 9);
|
||||||
|
|
||||||
|
if(http_code < 200 || http_code > 299)
|
||||||
|
{
|
||||||
|
/* HTTP error */
|
||||||
|
CloseTCP(sck);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for a length field
|
||||||
|
fs->http_file_length = 0;
|
||||||
|
|
||||||
|
/* Limit search to only 20 loops */
|
||||||
|
if((temp = strstr(request, "Content-Length: ")) != NULL)
|
||||||
|
{
|
||||||
|
/* Has a content-length field, copy into structure */
|
||||||
|
fs->http_file_length = atol(temp + 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the handle data into the structure */
|
||||||
|
fs->inetStream = sck;
|
||||||
|
|
||||||
|
/* Copy any excess data beyond the header into the filestream buffers */
|
||||||
|
temp = strstr(request, "\r\n\r\n");
|
||||||
|
|
||||||
|
if(temp)
|
||||||
|
{
|
||||||
|
temp += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp - request < bytes_recv)
|
||||||
|
{
|
||||||
|
memcpy(fs->data, temp, (temp - request) - bytes_recv);
|
||||||
|
fs->buffer_length = (temp - request) - bytes_recv;
|
||||||
|
fs->buffer_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
57
Libraries/FAAD2/Files/common/faad/filestream.h
Normal file
57
Libraries/FAAD2/Files/common/faad/filestream.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef FILESTREAM_H
|
||||||
|
#define FILESTREAM_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE stream;
|
||||||
|
unsigned short inetStream;
|
||||||
|
unsigned char *data;
|
||||||
|
int http;
|
||||||
|
int buffer_offset;
|
||||||
|
int buffer_length;
|
||||||
|
int file_offset;
|
||||||
|
int http_file_length;
|
||||||
|
} FILE_STREAM;
|
||||||
|
|
||||||
|
extern long m_local_buffer_size;
|
||||||
|
extern long m_stream_buffer_size;
|
||||||
|
|
||||||
|
FILE_STREAM *open_filestream(char *filename);
|
||||||
|
int read_byte_filestream(FILE_STREAM *fs);
|
||||||
|
int read_buffer_filestream(FILE_STREAM *fs, void *data, int length);
|
||||||
|
unsigned long filelength_filestream(FILE_STREAM *fs);
|
||||||
|
void close_filestream(FILE_STREAM *fs);
|
||||||
|
void seek_filestream(FILE_STREAM *fs, unsigned long offset, int mode);
|
||||||
|
unsigned long tell_filestream(FILE_STREAM *fs);
|
||||||
|
int http_file_open(char *url, FILE_STREAM *fs);
|
||||||
|
|
||||||
|
int WinsockInit();
|
||||||
|
void WinsockDeInit();
|
||||||
|
void CloseTCP(int s);
|
||||||
|
#endif
|
755
Libraries/FAAD2/Files/common/faad/getopt.c
Normal file
755
Libraries/FAAD2/Files/common/faad/getopt.c
Normal file
|
@ -0,0 +1,755 @@
|
||||||
|
/* Getopt for GNU.
|
||||||
|
NOTE: getopt is now part of the C library, so if you don't know what
|
||||||
|
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||||
|
before changing it!
|
||||||
|
|
||||||
|
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STDC__
|
||||||
|
# ifndef const
|
||||||
|
# define const
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||||
|
#ifndef _NO_PROTO
|
||||||
|
#define _NO_PROTO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||||
|
actually compiling the library itself. This code is part of the GNU C
|
||||||
|
Library, but also included in many other GNU distributions. Compiling
|
||||||
|
and linking in this code is a waste when using the GNU C library
|
||||||
|
(especially if it is a shared library). Rather than having every GNU
|
||||||
|
program understand `configure --with-gnu-libc' and omit the object files,
|
||||||
|
it is simpler to just do this in the source for each such file. */
|
||||||
|
|
||||||
|
#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || !__MacOSX__
|
||||||
|
|
||||||
|
|
||||||
|
/* This needs to come after some library #include
|
||||||
|
to get __GNU_LIBRARY__ defined. */
|
||||||
|
#ifdef __GNU_LIBRARY__
|
||||||
|
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||||
|
contain conflicting prototypes for getopt. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif /* GNU C library. */
|
||||||
|
|
||||||
|
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||||
|
long-named option. Because this is not POSIX.2 compliant, it is
|
||||||
|
being phased out. */
|
||||||
|
/* #define GETOPT_COMPAT */
|
||||||
|
|
||||||
|
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||||
|
but it behaves differently for the user, since it allows the user
|
||||||
|
to intersperse the options with the other arguments.
|
||||||
|
|
||||||
|
As `getopt' works, it permutes the elements of ARGV so that,
|
||||||
|
when it is done, all the options precede everything else. Thus
|
||||||
|
all application programs are extended to handle flexible argument order.
|
||||||
|
|
||||||
|
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||||
|
Then the behavior is completely standard.
|
||||||
|
|
||||||
|
GNU application programs can use a third alternative mode in which
|
||||||
|
they can distinguish the relative order of options and other arguments. */
|
||||||
|
|
||||||
|
#include "getopt.h"
|
||||||
|
|
||||||
|
/* For communication from `getopt' to the caller.
|
||||||
|
When `getopt' finds an option that takes an argument,
|
||||||
|
the argument value is returned here.
|
||||||
|
Also, when `ordering' is RETURN_IN_ORDER,
|
||||||
|
each non-option ARGV-element is returned here. */
|
||||||
|
|
||||||
|
char *optarg = 0;
|
||||||
|
|
||||||
|
/* Index in ARGV of the next element to be scanned.
|
||||||
|
This is used for communication to and from the caller
|
||||||
|
and for communication between successive calls to `getopt'.
|
||||||
|
|
||||||
|
On entry to `getopt', zero means this is the first call; initialize.
|
||||||
|
|
||||||
|
When `getopt' returns EOF, this is the index of the first of the
|
||||||
|
non-option elements that the caller should itself scan.
|
||||||
|
|
||||||
|
Otherwise, `optind' communicates from one call to the next
|
||||||
|
how much of ARGV has been scanned so far. */
|
||||||
|
|
||||||
|
/* XXX 1003.2 says this must be 1 before any call. */
|
||||||
|
int optind = 0;
|
||||||
|
|
||||||
|
/* The next char to be scanned in the option-element
|
||||||
|
in which the last option character we returned was found.
|
||||||
|
This allows us to pick up the scan where we left off.
|
||||||
|
|
||||||
|
If this is zero, or a null string, it means resume the scan
|
||||||
|
by advancing to the next ARGV-element. */
|
||||||
|
|
||||||
|
static char *nextchar;
|
||||||
|
|
||||||
|
/* Callers store zero here to inhibit the error message
|
||||||
|
for unrecognized options. */
|
||||||
|
|
||||||
|
int opterr = 1;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized.
|
||||||
|
This must be initialized on some systems to avoid linking in the
|
||||||
|
system's own getopt implementation. */
|
||||||
|
|
||||||
|
#define BAD_OPTION '\0'
|
||||||
|
int optopt = BAD_OPTION;
|
||||||
|
|
||||||
|
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||||
|
|
||||||
|
If the caller did not specify anything,
|
||||||
|
the default is REQUIRE_ORDER if the environment variable
|
||||||
|
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||||
|
|
||||||
|
REQUIRE_ORDER means don't recognize them as options;
|
||||||
|
stop option processing when the first non-option is seen.
|
||||||
|
This is what Unix does.
|
||||||
|
This mode of operation is selected by either setting the environment
|
||||||
|
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||||
|
of the list of option characters.
|
||||||
|
|
||||||
|
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||||
|
so that eventually all the non-options are at the end. This allows options
|
||||||
|
to be given in any order, even with programs that were not written to
|
||||||
|
expect this.
|
||||||
|
|
||||||
|
RETURN_IN_ORDER is an option available to programs that were written
|
||||||
|
to expect options and other ARGV-elements in any order and that care about
|
||||||
|
the ordering of the two. We describe each non-option ARGV-element
|
||||||
|
as if it were the argument of an option with character code 1.
|
||||||
|
Using `-' as the first character of the list of option characters
|
||||||
|
selects this mode of operation.
|
||||||
|
|
||||||
|
The special argument `--' forces an end of option-scanning regardless
|
||||||
|
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||||
|
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||||
|
|
||||||
|
static enum
|
||||||
|
{
|
||||||
|
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||||
|
} ordering;
|
||||||
|
|
||||||
|
#ifdef __GNU_LIBRARY__
|
||||||
|
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||||
|
because there are many ways it can cause trouble.
|
||||||
|
On some systems, it contains special magic macros that don't work
|
||||||
|
in GCC. */
|
||||||
|
#include <string.h>
|
||||||
|
#define my_index strchr
|
||||||
|
#define my_strlen strlen
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Avoid depending on library functions or files
|
||||||
|
whose names are inconsistent. */
|
||||||
|
|
||||||
|
#if __STDC__ || defined(PROTO)
|
||||||
|
extern char *getenv(const char *name);
|
||||||
|
extern int strcmp (const char *s1, const char *s2);
|
||||||
|
extern int strncmp(const char *s1, const char *s2, unsigned int n);
|
||||||
|
|
||||||
|
static int my_strlen(const char *s);
|
||||||
|
static char *my_index (const char *str, int chr);
|
||||||
|
#else
|
||||||
|
extern char *getenv ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
my_strlen (str)
|
||||||
|
const char *str;
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
while (*str++)
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
my_index (str, chr)
|
||||||
|
const char *str;
|
||||||
|
int chr;
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
if (*str == chr)
|
||||||
|
return (char *) str;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GNU C library. */
|
||||||
|
|
||||||
|
/* Handle permutation of arguments. */
|
||||||
|
|
||||||
|
/* Describe the part of ARGV that contains non-options that have
|
||||||
|
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||||
|
`last_nonopt' is the index after the last of them. */
|
||||||
|
|
||||||
|
static int first_nonopt;
|
||||||
|
static int last_nonopt;
|
||||||
|
|
||||||
|
/* Exchange two adjacent subsequences of ARGV.
|
||||||
|
One subsequence is elements [first_nonopt,last_nonopt)
|
||||||
|
which contains all the non-options that have been skipped so far.
|
||||||
|
The other is elements [last_nonopt,optind), which contains all
|
||||||
|
the options processed since those non-options were skipped.
|
||||||
|
|
||||||
|
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||||
|
the new indices of the non-options in ARGV after they are moved.
|
||||||
|
|
||||||
|
To perform the swap, we first reverse the order of all elements. So
|
||||||
|
all options now come before all non options, but they are in the
|
||||||
|
wrong order. So we put back the options and non options in original
|
||||||
|
order by reversing them again. For example:
|
||||||
|
original input: a b c -x -y
|
||||||
|
reverse all: -y -x c b a
|
||||||
|
reverse options: -x -y c b a
|
||||||
|
reverse non options: -x -y a b c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if __STDC__ || defined(PROTO)
|
||||||
|
static void exchange (char **argv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
exchange (argv)
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
char *temp, **first, **last;
|
||||||
|
|
||||||
|
/* Reverse all the elements [first_nonopt, optind) */
|
||||||
|
first = &argv[first_nonopt];
|
||||||
|
last = &argv[optind-1];
|
||||||
|
while (first < last) {
|
||||||
|
temp = *first; *first = *last; *last = temp; first++; last--;
|
||||||
|
}
|
||||||
|
/* Put back the options in order */
|
||||||
|
first = &argv[first_nonopt];
|
||||||
|
first_nonopt += (optind - last_nonopt);
|
||||||
|
last = &argv[first_nonopt - 1];
|
||||||
|
while (first < last) {
|
||||||
|
temp = *first; *first = *last; *last = temp; first++; last--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put back the non options in order */
|
||||||
|
first = &argv[first_nonopt];
|
||||||
|
last_nonopt = optind;
|
||||||
|
last = &argv[last_nonopt-1];
|
||||||
|
while (first < last) {
|
||||||
|
temp = *first; *first = *last; *last = temp; first++; last--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||||
|
given in OPTSTRING.
|
||||||
|
|
||||||
|
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||||
|
then it is an option element. The characters of this element
|
||||||
|
(aside from the initial '-') are option characters. If `getopt'
|
||||||
|
is called repeatedly, it returns successively each of the option characters
|
||||||
|
from each of the option elements.
|
||||||
|
|
||||||
|
If `getopt' finds another option character, it returns that character,
|
||||||
|
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||||
|
resume the scan with the following option character or ARGV-element.
|
||||||
|
|
||||||
|
If there are no more option characters, `getopt' returns `EOF'.
|
||||||
|
Then `optind' is the index in ARGV of the first ARGV-element
|
||||||
|
that is not an option. (The ARGV-elements have been permuted
|
||||||
|
so that those that are not options now come last.)
|
||||||
|
|
||||||
|
OPTSTRING is a string containing the legitimate option characters.
|
||||||
|
If an option character is seen that is not listed in OPTSTRING,
|
||||||
|
return BAD_OPTION after printing an error message. If you set `opterr' to
|
||||||
|
zero, the error message is suppressed but we still return BAD_OPTION.
|
||||||
|
|
||||||
|
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||||
|
so the following text in the same ARGV-element, or the text of the following
|
||||||
|
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||||
|
wants an optional arg; if there is text in the current ARGV-element,
|
||||||
|
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||||
|
|
||||||
|
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||||
|
handling the non-option ARGV-elements.
|
||||||
|
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||||
|
|
||||||
|
Long-named options begin with `--' instead of `-'.
|
||||||
|
Their names may be abbreviated as long as the abbreviation is unique
|
||||||
|
or is an exact match for some defined option. If they have an
|
||||||
|
argument, it follows the option name in the same ARGV-element, separated
|
||||||
|
from the option name by a `=', or else the in next ARGV-element.
|
||||||
|
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||||
|
`flag' field is nonzero, the value of the option's `val' field
|
||||||
|
if the `flag' field is zero.
|
||||||
|
|
||||||
|
The elements of ARGV aren't really const, because we permute them.
|
||||||
|
But we pretend they're const in the prototype to be compatible
|
||||||
|
with other systems.
|
||||||
|
|
||||||
|
LONGOPTS is a vector of `struct option' terminated by an
|
||||||
|
element containing a name which is zero.
|
||||||
|
|
||||||
|
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||||
|
It is only valid when a long-named option has been found by the most
|
||||||
|
recent call.
|
||||||
|
|
||||||
|
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||||
|
long-named options. */
|
||||||
|
|
||||||
|
int
|
||||||
|
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
|
int argc;
|
||||||
|
char *const *argv;
|
||||||
|
const char *optstring;
|
||||||
|
const struct option *longopts;
|
||||||
|
int *longind;
|
||||||
|
int long_only;
|
||||||
|
{
|
||||||
|
int option_index;
|
||||||
|
|
||||||
|
optarg = 0;
|
||||||
|
|
||||||
|
/* Initialize the internal data when the first call is made.
|
||||||
|
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||||
|
is the program name); the sequence of previously skipped
|
||||||
|
non-option ARGV-elements is empty. */
|
||||||
|
|
||||||
|
if (optind == 0)
|
||||||
|
{
|
||||||
|
first_nonopt = last_nonopt = optind = 1;
|
||||||
|
|
||||||
|
nextchar = NULL;
|
||||||
|
|
||||||
|
/* Determine how to handle the ordering of options and nonoptions. */
|
||||||
|
|
||||||
|
if (optstring[0] == '-')
|
||||||
|
{
|
||||||
|
ordering = RETURN_IN_ORDER;
|
||||||
|
++optstring;
|
||||||
|
}
|
||||||
|
else if (optstring[0] == '+')
|
||||||
|
{
|
||||||
|
ordering = REQUIRE_ORDER;
|
||||||
|
++optstring;
|
||||||
|
}
|
||||||
|
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||||
|
ordering = REQUIRE_ORDER;
|
||||||
|
else
|
||||||
|
ordering = PERMUTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextchar == NULL || *nextchar == '\0')
|
||||||
|
{
|
||||||
|
if (ordering == PERMUTE)
|
||||||
|
{
|
||||||
|
/* If we have just processed some options following some non-options,
|
||||||
|
exchange them so that the options come first. */
|
||||||
|
|
||||||
|
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||||
|
exchange ((char **) argv);
|
||||||
|
else if (last_nonopt != optind)
|
||||||
|
first_nonopt = optind;
|
||||||
|
|
||||||
|
/* Now skip any additional non-options
|
||||||
|
and extend the range of non-options previously skipped. */
|
||||||
|
|
||||||
|
while (optind < argc
|
||||||
|
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
&& (longopts == NULL
|
||||||
|
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
)
|
||||||
|
optind++;
|
||||||
|
last_nonopt = optind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special ARGV-element `--' means premature end of options.
|
||||||
|
Skip it like a null option,
|
||||||
|
then exchange with previous non-options as if it were an option,
|
||||||
|
then skip everything else like a non-option. */
|
||||||
|
|
||||||
|
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||||
|
{
|
||||||
|
optind++;
|
||||||
|
|
||||||
|
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||||
|
exchange ((char **) argv);
|
||||||
|
else if (first_nonopt == last_nonopt)
|
||||||
|
first_nonopt = optind;
|
||||||
|
last_nonopt = argc;
|
||||||
|
|
||||||
|
optind = argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have done all the ARGV-elements, stop the scan
|
||||||
|
and back over any non-options that we skipped and permuted. */
|
||||||
|
|
||||||
|
if (optind == argc)
|
||||||
|
{
|
||||||
|
/* Set the next-arg-index to point at the non-options
|
||||||
|
that we previously skipped, so the caller will digest them. */
|
||||||
|
if (first_nonopt != last_nonopt)
|
||||||
|
optind = first_nonopt;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have come to a non-option and did not permute it,
|
||||||
|
either stop the scan or describe it to the caller and pass it by. */
|
||||||
|
|
||||||
|
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
&& (longopts == NULL
|
||||||
|
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (ordering == REQUIRE_ORDER)
|
||||||
|
return EOF;
|
||||||
|
optarg = argv[optind++];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have found another option-ARGV-element.
|
||||||
|
Start decoding its characters. */
|
||||||
|
|
||||||
|
nextchar = (argv[optind] + 1
|
||||||
|
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longopts != NULL
|
||||||
|
&& ((argv[optind][0] == '-'
|
||||||
|
&& (argv[optind][1] == '-' || long_only))
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
|| argv[optind][0] == '+'
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
))
|
||||||
|
{
|
||||||
|
const struct option *p;
|
||||||
|
char *s = nextchar;
|
||||||
|
int exact = 0;
|
||||||
|
int ambig = 0;
|
||||||
|
const struct option *pfound = NULL;
|
||||||
|
int indfound = 0;
|
||||||
|
|
||||||
|
while (*s && *s != '=')
|
||||||
|
s++;
|
||||||
|
|
||||||
|
/* Test all options for either exact match or abbreviated matches. */
|
||||||
|
for (p = longopts, option_index = 0; p->name;
|
||||||
|
p++, option_index++)
|
||||||
|
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||||
|
{
|
||||||
|
if (s - nextchar == my_strlen (p->name))
|
||||||
|
{
|
||||||
|
/* Exact match found. */
|
||||||
|
pfound = p;
|
||||||
|
indfound = option_index;
|
||||||
|
exact = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (pfound == NULL)
|
||||||
|
{
|
||||||
|
/* First nonexact match found. */
|
||||||
|
pfound = p;
|
||||||
|
indfound = option_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Second nonexact match found. */
|
||||||
|
ambig = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ambig && !exact)
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||||
|
argv[0], argv[optind]);
|
||||||
|
nextchar += my_strlen (nextchar);
|
||||||
|
optind++;
|
||||||
|
return BAD_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfound != NULL)
|
||||||
|
{
|
||||||
|
option_index = indfound;
|
||||||
|
optind++;
|
||||||
|
if (*s)
|
||||||
|
{
|
||||||
|
/* Don't test has_arg with >, because some C compilers don't
|
||||||
|
allow it to be used on enums. */
|
||||||
|
if (pfound->has_arg)
|
||||||
|
optarg = s + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
if (argv[optind - 1][1] == '-')
|
||||||
|
/* --option */
|
||||||
|
fprintf (stderr,
|
||||||
|
"%s: option `--%s' doesn't allow an argument\n",
|
||||||
|
argv[0], pfound->name);
|
||||||
|
else
|
||||||
|
/* +option or -option */
|
||||||
|
fprintf (stderr,
|
||||||
|
"%s: option `%c%s' doesn't allow an argument\n",
|
||||||
|
argv[0], argv[optind - 1][0], pfound->name);
|
||||||
|
}
|
||||||
|
nextchar += my_strlen (nextchar);
|
||||||
|
return BAD_OPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pfound->has_arg == 1)
|
||||||
|
{
|
||||||
|
if (optind < argc)
|
||||||
|
optarg = argv[optind++];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||||
|
argv[0], argv[optind - 1]);
|
||||||
|
nextchar += my_strlen (nextchar);
|
||||||
|
return optstring[0] == ':' ? ':' : BAD_OPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextchar += my_strlen (nextchar);
|
||||||
|
if (longind != NULL)
|
||||||
|
*longind = option_index;
|
||||||
|
if (pfound->flag)
|
||||||
|
{
|
||||||
|
*(pfound->flag) = pfound->val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pfound->val;
|
||||||
|
}
|
||||||
|
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||||
|
or the option starts with '--' or is not a valid short
|
||||||
|
option, then it's an error.
|
||||||
|
Otherwise interpret it as a short option. */
|
||||||
|
if (!long_only || argv[optind][1] == '-'
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
|| argv[optind][0] == '+'
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
|| my_index (optstring, *nextchar) == NULL)
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
if (argv[optind][1] == '-')
|
||||||
|
/* --option */
|
||||||
|
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||||
|
argv[0], nextchar);
|
||||||
|
else
|
||||||
|
/* +option or -option */
|
||||||
|
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||||
|
argv[0], argv[optind][0], nextchar);
|
||||||
|
}
|
||||||
|
nextchar = (char *) "";
|
||||||
|
optind++;
|
||||||
|
return BAD_OPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look at and handle the next option-character. */
|
||||||
|
|
||||||
|
{
|
||||||
|
char c = *nextchar++;
|
||||||
|
char *temp = my_index (optstring, c);
|
||||||
|
|
||||||
|
/* Increment `optind' when we start to process its last character. */
|
||||||
|
if (*nextchar == '\0')
|
||||||
|
++optind;
|
||||||
|
|
||||||
|
if (temp == NULL || c == ':')
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (c < 040 || c >= 0177)
|
||||||
|
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||||
|
argv[0], c);
|
||||||
|
else
|
||||||
|
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||||
|
#else
|
||||||
|
/* 1003.2 specifies the format of this message. */
|
||||||
|
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
optopt = c;
|
||||||
|
return BAD_OPTION;
|
||||||
|
}
|
||||||
|
if (temp[1] == ':')
|
||||||
|
{
|
||||||
|
if (temp[2] == ':')
|
||||||
|
{
|
||||||
|
/* This is an option that accepts an argument optionally. */
|
||||||
|
if (*nextchar != '\0')
|
||||||
|
{
|
||||||
|
optarg = nextchar;
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
optarg = 0;
|
||||||
|
nextchar = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is an option that requires an argument. */
|
||||||
|
if (*nextchar != '\0')
|
||||||
|
{
|
||||||
|
optarg = nextchar;
|
||||||
|
/* If we end this ARGV-element by taking the rest as an arg,
|
||||||
|
we must advance to the next element now. */
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
else if (optind == argc)
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||||
|
argv[0], c);
|
||||||
|
#else
|
||||||
|
/* 1003.2 specifies the format of this message. */
|
||||||
|
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||||
|
argv[0], c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
optopt = c;
|
||||||
|
if (optstring[0] == ':')
|
||||||
|
c = ':';
|
||||||
|
else
|
||||||
|
c = BAD_OPTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* We already incremented `optind' once;
|
||||||
|
increment it again when taking next ARGV-elt as argument. */
|
||||||
|
optarg = argv[optind++];
|
||||||
|
nextchar = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getopt (argc, argv, optstring)
|
||||||
|
int argc;
|
||||||
|
char *const *argv;
|
||||||
|
const char *optstring;
|
||||||
|
{
|
||||||
|
return _getopt_internal (argc, argv, optstring,
|
||||||
|
(const struct option *) 0,
|
||||||
|
(int *) 0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getopt_long (argc, argv, options, long_options, opt_index)
|
||||||
|
int argc;
|
||||||
|
char *const *argv;
|
||||||
|
const char *options;
|
||||||
|
const struct option *long_options;
|
||||||
|
int *opt_index;
|
||||||
|
{
|
||||||
|
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
/* Compile with -DTEST to make an executable for use in testing
|
||||||
|
the above definition of `getopt'. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int digit_optind = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int this_option_optind = optind ? optind : 1;
|
||||||
|
|
||||||
|
c = getopt (argc, argv, "abc:d:0123456789");
|
||||||
|
if (c == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||||
|
printf ("digits occur in two different argv-elements.\n");
|
||||||
|
digit_optind = this_option_optind;
|
||||||
|
printf ("option %c\n", c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
printf ("option a\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
printf ("option b\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
printf ("option c with value `%s'\n", optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BAD_OPTION:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind < argc)
|
||||||
|
{
|
||||||
|
printf ("non-option ARGV-elements: ");
|
||||||
|
while (optind < argc)
|
||||||
|
printf ("%s ", argv[optind++]);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TEST */
|
130
Libraries/FAAD2/Files/common/faad/getopt.h
Normal file
130
Libraries/FAAD2/Files/common/faad/getopt.h
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/* Declarations for getopt.
|
||||||
|
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef _GETOPT_H
|
||||||
|
#define _GETOPT_H 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __MacOSX__
|
||||||
|
|
||||||
|
/* For communication from `getopt' to the caller.
|
||||||
|
When `getopt' finds an option that takes an argument,
|
||||||
|
the argument value is returned here.
|
||||||
|
Also, when `ordering' is RETURN_IN_ORDER,
|
||||||
|
each non-option ARGV-element is returned here. */
|
||||||
|
|
||||||
|
extern char *optarg;
|
||||||
|
|
||||||
|
/* Index in ARGV of the next element to be scanned.
|
||||||
|
This is used for communication to and from the caller
|
||||||
|
and for communication between successive calls to `getopt'.
|
||||||
|
|
||||||
|
On entry to `getopt', zero means this is the first call; initialize.
|
||||||
|
|
||||||
|
When `getopt' returns EOF, this is the index of the first of the
|
||||||
|
non-option elements that the caller should itself scan.
|
||||||
|
|
||||||
|
Otherwise, `optind' communicates from one call to the next
|
||||||
|
how much of ARGV has been scanned so far. */
|
||||||
|
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||||
|
for unrecognized options. */
|
||||||
|
|
||||||
|
extern int opterr;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized. */
|
||||||
|
|
||||||
|
extern int optopt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Describe the long-named options requested by the application.
|
||||||
|
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||||
|
of `struct option' terminated by an element containing a name which is
|
||||||
|
zero.
|
||||||
|
|
||||||
|
The field `has_arg' is:
|
||||||
|
no_argument (or 0) if the option does not take an argument,
|
||||||
|
required_argument (or 1) if the option requires an argument,
|
||||||
|
optional_argument (or 2) if the option takes an optional argument.
|
||||||
|
|
||||||
|
If the field `flag' is not NULL, it points to a variable that is set
|
||||||
|
to the value given in the field `val' when the option is found, but
|
||||||
|
left unchanged if the option is not found.
|
||||||
|
|
||||||
|
To have a long-named option do something other than set an `int' to
|
||||||
|
a compiled-in constant, such as set a value from `optarg', set the
|
||||||
|
option's `flag' field to zero and its `val' field to a nonzero
|
||||||
|
value (the equivalent single-letter option character, if there is
|
||||||
|
one). For long options that have a zero `flag' field, `getopt'
|
||||||
|
returns the contents of the `val' field. */
|
||||||
|
|
||||||
|
struct option
|
||||||
|
{
|
||||||
|
#if __STDC__
|
||||||
|
const char *name;
|
||||||
|
#else
|
||||||
|
char *name;
|
||||||
|
#endif
|
||||||
|
/* has_arg can't be an enum because some compilers complain about
|
||||||
|
type mismatches in all the code that assumes it is an int. */
|
||||||
|
int has_arg;
|
||||||
|
int *flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||||
|
|
||||||
|
#define no_argument 0
|
||||||
|
#define required_argument 1
|
||||||
|
#define optional_argument 2
|
||||||
|
|
||||||
|
//#if __STDC__ || defined(PROTO)
|
||||||
|
#if defined(__GNU_LIBRARY__)
|
||||||
|
/* Many other libraries have conflicting prototypes for getopt, with
|
||||||
|
differences in the consts, in stdlib.h. To avoid compilation
|
||||||
|
errors, only prototype getopt for the GNU C library. */
|
||||||
|
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||||
|
#endif /* not __GNU_LIBRARY__ */
|
||||||
|
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
extern int getopt_long_only (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
|
||||||
|
/* Internal only. Users should not call this directly. */
|
||||||
|
extern int _getopt_internal (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind,
|
||||||
|
int long_only);
|
||||||
|
//#else /* not __STDC__ */
|
||||||
|
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||||
|
//extern int getopt_long ();
|
||||||
|
//extern int getopt_long_only ();
|
||||||
|
|
||||||
|
//extern int _getopt_internal ();
|
||||||
|
//#endif /* not __STDC__ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _GETOPT_H */
|
1124
Libraries/FAAD2/Files/common/faad/id3v2tag.c
Normal file
1124
Libraries/FAAD2/Files/common/faad/id3v2tag.c
Normal file
File diff suppressed because it is too large
Load diff
54
Libraries/FAAD2/Files/common/faad/id3v2tag.h
Normal file
54
Libraries/FAAD2/Files/common/faad/id3v2tag.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __ID3V2TAG_H__
|
||||||
|
#define __ID3V2TAG_H__
|
||||||
|
|
||||||
|
void GetID3FileTitle(char *filename, char *title, char *format);
|
||||||
|
void FillID3List(HWND hwndDlg, HWND hwndList, char *filename);
|
||||||
|
void List_OnGetDispInfo(LV_DISPINFO *pnmv);
|
||||||
|
BOOL List_EditData(HWND hwndApp, HWND hwndList);
|
||||||
|
void List_SaveID3(HWND hwndApp, HWND hwndList, char *filename);
|
||||||
|
BOOL List_DeleteSelected(HWND hwndApp, HWND hwndList);
|
||||||
|
BOOL List_AddFrame(HWND hwndApp, HWND hwndList);
|
||||||
|
BOOL List_AddStandardFrames(HWND hwndApp, HWND hwndList);
|
||||||
|
void AddFrameFromRAWData(HWND hwndList, int frameId, LPSTR data1, LPSTR data2);
|
||||||
|
|
||||||
|
HINSTANCE hInstance_for_id3editor;
|
||||||
|
|
||||||
|
typedef struct ID3GENRES_TAG
|
||||||
|
{
|
||||||
|
BYTE id;
|
||||||
|
char name[30];
|
||||||
|
} ID3GENRES;
|
||||||
|
|
||||||
|
typedef struct id3item_tag {
|
||||||
|
int frameId;
|
||||||
|
LPSTR aCols[2];
|
||||||
|
} ID3ITEM;
|
||||||
|
|
||||||
|
#endif
|
1321
Libraries/FAAD2/Files/common/mp4ff/drms.c
Normal file
1321
Libraries/FAAD2/Files/common/mp4ff/drms.c
Normal file
File diff suppressed because it is too large
Load diff
30
Libraries/FAAD2/Files/common/mp4ff/drms.h
Normal file
30
Libraries/FAAD2/Files/common/mp4ff/drms.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* drms.h : DRMS
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2004 VideoLAN
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Author: Jon Lech Johansen <jon-vl@nanocrew.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern void *drms_alloc( char *psz_homedir );
|
||||||
|
extern void drms_free( void *p_drms );
|
||||||
|
extern int drms_init( void *p_drms, uint32_t i_type,
|
||||||
|
uint8_t *p_info, uint32_t i_len );
|
||||||
|
extern void drms_decrypt( void *p_drms, uint32_t *p_buffer,
|
||||||
|
uint32_t i_len );
|
||||||
|
|
288
Libraries/FAAD2/Files/common/mp4ff/drmstables.h
Normal file
288
Libraries/FAAD2/Files/common/mp4ff/drmstables.h
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* drmstables.h : AES/Rijndael block cipher and miscellaneous tables
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 2004 VideoLAN
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Author: Jon Lech Johansen <jon-vl@nanocrew.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define AES_ROR( x, n ) (((x) << (32-(n))) | ((x) >> (n)))
|
||||||
|
|
||||||
|
#define AES_XOR_ROR( p_table, p_tmp ) \
|
||||||
|
( p_table[ (p_tmp[ t > 2 ? t - 3 : t + 1 ] >> 24) & 0xFF ] \
|
||||||
|
^ AES_ROR( p_table[ (p_tmp[ t > 1 ? t - 2 : t + 2 ] >> 16) & 0xFF ], 8 ) \
|
||||||
|
^ AES_ROR( p_table[ (p_tmp[ t > 0 ? t - 1 : t + 3 ] >> 8) & 0xFF ], 16 ) \
|
||||||
|
^ AES_ROR( p_table[ p_tmp[ t ] & 0xFF ], 24 ) )
|
||||||
|
|
||||||
|
#define AES_KEY_COUNT 10
|
||||||
|
|
||||||
|
static uint32_t const p_aes_table[ AES_KEY_COUNT ] =
|
||||||
|
{
|
||||||
|
0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020,
|
||||||
|
0x00000040, 0x00000080, 0x0000001b, 0x00000036
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t const p_aes_encrypt[ 256 ] =
|
||||||
|
{
|
||||||
|
0x63000000, 0x7c000000, 0x77000000, 0x7b000000, 0xf2000000, 0x6b000000,
|
||||||
|
0x6f000000, 0xc5000000, 0x30000000, 0x01000000, 0x67000000, 0x2b000000,
|
||||||
|
0xfe000000, 0xd7000000, 0xab000000, 0x76000000, 0xca000000, 0x82000000,
|
||||||
|
0xc9000000, 0x7d000000, 0xfa000000, 0x59000000, 0x47000000, 0xf0000000,
|
||||||
|
0xad000000, 0xd4000000, 0xa2000000, 0xaf000000, 0x9c000000, 0xa4000000,
|
||||||
|
0x72000000, 0xc0000000, 0xb7000000, 0xfd000000, 0x93000000, 0x26000000,
|
||||||
|
0x36000000, 0x3f000000, 0xf7000000, 0xcc000000, 0x34000000, 0xa5000000,
|
||||||
|
0xe5000000, 0xf1000000, 0x71000000, 0xd8000000, 0x31000000, 0x15000000,
|
||||||
|
0x04000000, 0xc7000000, 0x23000000, 0xc3000000, 0x18000000, 0x96000000,
|
||||||
|
0x05000000, 0x9a000000, 0x07000000, 0x12000000, 0x80000000, 0xe2000000,
|
||||||
|
0xeb000000, 0x27000000, 0xb2000000, 0x75000000, 0x09000000, 0x83000000,
|
||||||
|
0x2c000000, 0x1a000000, 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000,
|
||||||
|
0x52000000, 0x3b000000, 0xd6000000, 0xb3000000, 0x29000000, 0xe3000000,
|
||||||
|
0x2f000000, 0x84000000, 0x53000000, 0xd1000000, 0x00000000, 0xed000000,
|
||||||
|
0x20000000, 0xfc000000, 0xb1000000, 0x5b000000, 0x6a000000, 0xcb000000,
|
||||||
|
0xbe000000, 0x39000000, 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000,
|
||||||
|
0xd0000000, 0xef000000, 0xaa000000, 0xfb000000, 0x43000000, 0x4d000000,
|
||||||
|
0x33000000, 0x85000000, 0x45000000, 0xf9000000, 0x02000000, 0x7f000000,
|
||||||
|
0x50000000, 0x3c000000, 0x9f000000, 0xa8000000, 0x51000000, 0xa3000000,
|
||||||
|
0x40000000, 0x8f000000, 0x92000000, 0x9d000000, 0x38000000, 0xf5000000,
|
||||||
|
0xbc000000, 0xb6000000, 0xda000000, 0x21000000, 0x10000000, 0xff000000,
|
||||||
|
0xf3000000, 0xd2000000, 0xcd000000, 0x0c000000, 0x13000000, 0xec000000,
|
||||||
|
0x5f000000, 0x97000000, 0x44000000, 0x17000000, 0xc4000000, 0xa7000000,
|
||||||
|
0x7e000000, 0x3d000000, 0x64000000, 0x5d000000, 0x19000000, 0x73000000,
|
||||||
|
0x60000000, 0x81000000, 0x4f000000, 0xdc000000, 0x22000000, 0x2a000000,
|
||||||
|
0x90000000, 0x88000000, 0x46000000, 0xee000000, 0xb8000000, 0x14000000,
|
||||||
|
0xde000000, 0x5e000000, 0x0b000000, 0xdb000000, 0xe0000000, 0x32000000,
|
||||||
|
0x3a000000, 0x0a000000, 0x49000000, 0x06000000, 0x24000000, 0x5c000000,
|
||||||
|
0xc2000000, 0xd3000000, 0xac000000, 0x62000000, 0x91000000, 0x95000000,
|
||||||
|
0xe4000000, 0x79000000, 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000,
|
||||||
|
0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000, 0x6c000000, 0x56000000,
|
||||||
|
0xf4000000, 0xea000000, 0x65000000, 0x7a000000, 0xae000000, 0x08000000,
|
||||||
|
0xba000000, 0x78000000, 0x25000000, 0x2e000000, 0x1c000000, 0xa6000000,
|
||||||
|
0xb4000000, 0xc6000000, 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000,
|
||||||
|
0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000, 0x70000000, 0x3e000000,
|
||||||
|
0xb5000000, 0x66000000, 0x48000000, 0x03000000, 0xf6000000, 0x0e000000,
|
||||||
|
0x61000000, 0x35000000, 0x57000000, 0xb9000000, 0x86000000, 0xc1000000,
|
||||||
|
0x1d000000, 0x9e000000, 0xe1000000, 0xf8000000, 0x98000000, 0x11000000,
|
||||||
|
0x69000000, 0xd9000000, 0x8e000000, 0x94000000, 0x9b000000, 0x1e000000,
|
||||||
|
0x87000000, 0xe9000000, 0xce000000, 0x55000000, 0x28000000, 0xdf000000,
|
||||||
|
0x8c000000, 0xa1000000, 0x89000000, 0x0d000000, 0xbf000000, 0xe6000000,
|
||||||
|
0x42000000, 0x68000000, 0x41000000, 0x99000000, 0x2d000000, 0x0f000000,
|
||||||
|
0xb0000000, 0x54000000, 0xbb000000, 0x16000000
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t const p_aes_itable[ 256 ] =
|
||||||
|
{
|
||||||
|
0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d,
|
||||||
|
0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
|
||||||
|
0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba,
|
||||||
|
0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
|
||||||
|
0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174,
|
||||||
|
0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
|
||||||
|
0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a,
|
||||||
|
0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
|
||||||
|
0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b,
|
||||||
|
0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
|
||||||
|
0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479,
|
||||||
|
0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
|
||||||
|
0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60,
|
||||||
|
0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
|
||||||
|
0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd,
|
||||||
|
0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
|
||||||
|
0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b,
|
||||||
|
0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
|
||||||
|
0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757,
|
||||||
|
0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
|
||||||
|
0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, 0xf2adc78b,
|
||||||
|
0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
|
||||||
|
0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623,
|
||||||
|
0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
|
||||||
|
0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2,
|
||||||
|
0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
|
||||||
|
0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138,
|
||||||
|
0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
|
||||||
|
0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8,
|
||||||
|
0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
|
||||||
|
0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859,
|
||||||
|
0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
|
||||||
|
0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f,
|
||||||
|
0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
|
||||||
|
0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef,
|
||||||
|
0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
|
||||||
|
0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db,
|
||||||
|
0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
|
||||||
|
0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2,
|
||||||
|
0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
|
||||||
|
0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2,
|
||||||
|
0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
|
||||||
|
0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t const p_aes_decrypt[ 256 ] =
|
||||||
|
{
|
||||||
|
0x52000000, 0x09000000, 0x6a000000, 0xd5000000, 0x30000000, 0x36000000,
|
||||||
|
0xa5000000, 0x38000000, 0xbf000000, 0x40000000, 0xa3000000, 0x9e000000,
|
||||||
|
0x81000000, 0xf3000000, 0xd7000000, 0xfb000000, 0x7c000000, 0xe3000000,
|
||||||
|
0x39000000, 0x82000000, 0x9b000000, 0x2f000000, 0xff000000, 0x87000000,
|
||||||
|
0x34000000, 0x8e000000, 0x43000000, 0x44000000, 0xc4000000, 0xde000000,
|
||||||
|
0xe9000000, 0xcb000000, 0x54000000, 0x7b000000, 0x94000000, 0x32000000,
|
||||||
|
0xa6000000, 0xc2000000, 0x23000000, 0x3d000000, 0xee000000, 0x4c000000,
|
||||||
|
0x95000000, 0x0b000000, 0x42000000, 0xfa000000, 0xc3000000, 0x4e000000,
|
||||||
|
0x08000000, 0x2e000000, 0xa1000000, 0x66000000, 0x28000000, 0xd9000000,
|
||||||
|
0x24000000, 0xb2000000, 0x76000000, 0x5b000000, 0xa2000000, 0x49000000,
|
||||||
|
0x6d000000, 0x8b000000, 0xd1000000, 0x25000000, 0x72000000, 0xf8000000,
|
||||||
|
0xf6000000, 0x64000000, 0x86000000, 0x68000000, 0x98000000, 0x16000000,
|
||||||
|
0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000, 0x5d000000, 0x65000000,
|
||||||
|
0xb6000000, 0x92000000, 0x6c000000, 0x70000000, 0x48000000, 0x50000000,
|
||||||
|
0xfd000000, 0xed000000, 0xb9000000, 0xda000000, 0x5e000000, 0x15000000,
|
||||||
|
0x46000000, 0x57000000, 0xa7000000, 0x8d000000, 0x9d000000, 0x84000000,
|
||||||
|
0x90000000, 0xd8000000, 0xab000000, 0x00000000, 0x8c000000, 0xbc000000,
|
||||||
|
0xd3000000, 0x0a000000, 0xf7000000, 0xe4000000, 0x58000000, 0x05000000,
|
||||||
|
0xb8000000, 0xb3000000, 0x45000000, 0x06000000, 0xd0000000, 0x2c000000,
|
||||||
|
0x1e000000, 0x8f000000, 0xca000000, 0x3f000000, 0x0f000000, 0x02000000,
|
||||||
|
0xc1000000, 0xaf000000, 0xbd000000, 0x03000000, 0x01000000, 0x13000000,
|
||||||
|
0x8a000000, 0x6b000000, 0x3a000000, 0x91000000, 0x11000000, 0x41000000,
|
||||||
|
0x4f000000, 0x67000000, 0xdc000000, 0xea000000, 0x97000000, 0xf2000000,
|
||||||
|
0xcf000000, 0xce000000, 0xf0000000, 0xb4000000, 0xe6000000, 0x73000000,
|
||||||
|
0x96000000, 0xac000000, 0x74000000, 0x22000000, 0xe7000000, 0xad000000,
|
||||||
|
0x35000000, 0x85000000, 0xe2000000, 0xf9000000, 0x37000000, 0xe8000000,
|
||||||
|
0x1c000000, 0x75000000, 0xdf000000, 0x6e000000, 0x47000000, 0xf1000000,
|
||||||
|
0x1a000000, 0x71000000, 0x1d000000, 0x29000000, 0xc5000000, 0x89000000,
|
||||||
|
0x6f000000, 0xb7000000, 0x62000000, 0x0e000000, 0xaa000000, 0x18000000,
|
||||||
|
0xbe000000, 0x1b000000, 0xfc000000, 0x56000000, 0x3e000000, 0x4b000000,
|
||||||
|
0xc6000000, 0xd2000000, 0x79000000, 0x20000000, 0x9a000000, 0xdb000000,
|
||||||
|
0xc0000000, 0xfe000000, 0x78000000, 0xcd000000, 0x5a000000, 0xf4000000,
|
||||||
|
0x1f000000, 0xdd000000, 0xa8000000, 0x33000000, 0x88000000, 0x07000000,
|
||||||
|
0xc7000000, 0x31000000, 0xb1000000, 0x12000000, 0x10000000, 0x59000000,
|
||||||
|
0x27000000, 0x80000000, 0xec000000, 0x5f000000, 0x60000000, 0x51000000,
|
||||||
|
0x7f000000, 0xa9000000, 0x19000000, 0xb5000000, 0x4a000000, 0x0d000000,
|
||||||
|
0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000, 0x93000000, 0xc9000000,
|
||||||
|
0x9c000000, 0xef000000, 0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000,
|
||||||
|
0xae000000, 0x2a000000, 0xf5000000, 0xb0000000, 0xc8000000, 0xeb000000,
|
||||||
|
0xbb000000, 0x3c000000, 0x83000000, 0x53000000, 0x99000000, 0x61000000,
|
||||||
|
0x17000000, 0x2b000000, 0x04000000, 0x7e000000, 0xba000000, 0x77000000,
|
||||||
|
0xd6000000, 0x26000000, 0xe1000000, 0x69000000, 0x14000000, 0x63000000,
|
||||||
|
0x55000000, 0x21000000, 0x0c000000, 0x7d000000
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t const p_shuffle_xor[ 256 ] =
|
||||||
|
{
|
||||||
|
0x00d1, 0x0315, 0x1a32, 0x19ec, 0x1bbb, 0x1d6f, 0x14fe, 0x0e9e,
|
||||||
|
0x029e, 0x1b8f, 0x0b70, 0x033a, 0x188e, 0x1d18, 0x0bd8, 0x0edb,
|
||||||
|
0x0c64, 0x1c2b, 0x149c, 0x047b, 0x1064, 0x1c7c, 0x118d, 0x1355,
|
||||||
|
0x0ae5, 0x0f18, 0x016f, 0x17d6, 0x1595, 0x0084, 0x0616, 0x1ccd,
|
||||||
|
0x1d94, 0x0618, 0x182c, 0x195b, 0x196d, 0x0394, 0x07db, 0x0287,
|
||||||
|
0x1636, 0x0b81, 0x1519, 0x0df9, 0x1ba3, 0x1cc3, 0x0ee2, 0x1434,
|
||||||
|
0x1457, 0x0ced, 0x0f7d, 0x0d7b, 0x0b9e, 0x0d13, 0x13d7, 0x18d0,
|
||||||
|
0x1259, 0x1977, 0x0606, 0x1e80, 0x05f2, 0x06b8, 0x1f07, 0x1365,
|
||||||
|
0x0334, 0x0e30, 0x195f, 0x15f1, 0x058e, 0x0aa8, 0x045a, 0x0465,
|
||||||
|
0x0b3e, 0x071e, 0x0a36, 0x105c, 0x01ac, 0x1a1e, 0x04e4, 0x056b,
|
||||||
|
0x12bf, 0x0da2, 0x0b41, 0x0eaf, 0x034f, 0x0181, 0x04e2, 0x002b,
|
||||||
|
0x12e6, 0x01be, 0x10e8, 0x128f, 0x0eb2, 0x1369, 0x05be, 0x1a59,
|
||||||
|
0x117e, 0x047c, 0x1e86, 0x056a, 0x0da7, 0x0d61, 0x03fc, 0x1e6e,
|
||||||
|
0x1d0c, 0x1e6d, 0x14bf, 0x0c50, 0x063a, 0x1b47, 0x17ae, 0x1321,
|
||||||
|
0x041b, 0x0a24, 0x0d4d, 0x1f2b, 0x1cb6, 0x1bed, 0x1549, 0x03a7,
|
||||||
|
0x0254, 0x006c, 0x0c9e, 0x0f73, 0x006c, 0x0008, 0x11f9, 0x0dd5,
|
||||||
|
0x0bcf, 0x0af9, 0x1dfe, 0x0341, 0x0e49, 0x0d38, 0x17cb, 0x1513,
|
||||||
|
0x0e96, 0x00ed, 0x0556, 0x1b28, 0x100c, 0x19d8, 0x14fa, 0x028c,
|
||||||
|
0x1c60, 0x1232, 0x13d3, 0x0d00, 0x1534, 0x192c, 0x14b5, 0x1cf2,
|
||||||
|
0x0504, 0x0b5b, 0x1ecf, 0x0423, 0x183b, 0x06b0, 0x169e, 0x1066,
|
||||||
|
0x04cb, 0x08a2, 0x1b4a, 0x1254, 0x198d, 0x1044, 0x0236, 0x1bd8,
|
||||||
|
0x18a1, 0x03ff, 0x1a0d, 0x0277, 0x0c2d, 0x17c9, 0x007c, 0x116e,
|
||||||
|
0x048a, 0x1eaf, 0x0922, 0x0c45, 0x0766, 0x1e5f, 0x1a28, 0x0120,
|
||||||
|
0x1c15, 0x034c, 0x0508, 0x0e73, 0x0879, 0x0441, 0x09ae, 0x132f,
|
||||||
|
0x14fe, 0x0413, 0x0a9d, 0x1727, 0x01d7, 0x1a2b, 0x0474, 0x18f0,
|
||||||
|
0x1f3b, 0x14f5, 0x1071, 0x0895, 0x1071, 0x18ff, 0x18e3, 0x0eb9,
|
||||||
|
0x0ba9, 0x0961, 0x1599, 0x019e, 0x1d12, 0x1baa, 0x1e94, 0x1921,
|
||||||
|
0x14dc, 0x124e, 0x0a25, 0x03ab, 0x1cc0, 0x1ebb, 0x0b4b, 0x16e5,
|
||||||
|
0x11ea, 0x0d78, 0x1bb3, 0x1ba7, 0x1510, 0x1b7b, 0x0c64, 0x1995,
|
||||||
|
0x1a58, 0x1651, 0x1964, 0x147a, 0x15f2, 0x11bb, 0x1654, 0x166e,
|
||||||
|
0x0ea9, 0x1de1, 0x1443, 0x13c5, 0x00e1, 0x0b2f, 0x0b6f, 0x0a37,
|
||||||
|
0x18ac, 0x08e6, 0x06f0, 0x136e, 0x0853, 0x0b2e, 0x0813, 0x10d6
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t const p_shuffle_sub[ 256 ] =
|
||||||
|
{
|
||||||
|
0x067a, 0x0c7d, 0x0b4f, 0x127d, 0x0bd6, 0x04ac, 0x16e0, 0x1730,
|
||||||
|
0x0587, 0x0afb, 0x1ac3, 0x0120, 0x14b5, 0x0f67, 0x11de, 0x0961,
|
||||||
|
0x1127, 0x1a68, 0x07f0, 0x17d0, 0x1a6f, 0x1f3b, 0x01ef, 0x0919,
|
||||||
|
0x131e, 0x0f90, 0x19e9, 0x18a8, 0x0cb2, 0x1ad0, 0x0c66, 0x0378,
|
||||||
|
0x03b0, 0x01be, 0x1866, 0x1159, 0x197c, 0x1105, 0x010b, 0x0353,
|
||||||
|
0x1abb, 0x09a6, 0x028a, 0x1bad, 0x1b20, 0x0455, 0x0f57, 0x0588,
|
||||||
|
0x1491, 0x0a1d, 0x0f04, 0x0650, 0x191e, 0x1e0e, 0x174b, 0x016b,
|
||||||
|
0x051f, 0x0532, 0x00df, 0x1aea, 0x0005, 0x0e1b, 0x0ff6, 0x08d8,
|
||||||
|
0x14b4, 0x086a, 0x0c20, 0x0149, 0x1971, 0x0f26, 0x1852, 0x017d,
|
||||||
|
0x1228, 0x0352, 0x0a44, 0x1330, 0x18df, 0x1e38, 0x01bc, 0x0bac,
|
||||||
|
0x1a48, 0x021f, 0x02f7, 0x0c31, 0x0bc4, 0x1e75, 0x105c, 0x13e3,
|
||||||
|
0x0b20, 0x03a1, 0x1af3, 0x1a36, 0x0e34, 0x181f, 0x09bd, 0x122b,
|
||||||
|
0x0ee0, 0x163b, 0x0be7, 0x103d, 0x1075, 0x1e9d, 0x02af, 0x0ba2,
|
||||||
|
0x1daa, 0x0cf1, 0x04b6, 0x0598, 0x06a1, 0x0d33, 0x1cfe, 0x04ee,
|
||||||
|
0x1bad, 0x07c8, 0x1a48, 0x05e6, 0x031f, 0x0e0a, 0x0326, 0x1650,
|
||||||
|
0x0526, 0x0b4e, 0x08fc, 0x0e4d, 0x0832, 0x06ea, 0x09bf, 0x0993,
|
||||||
|
0x09eb, 0x0f31, 0x071b, 0x14d5, 0x11ca, 0x0722, 0x120d, 0x014c,
|
||||||
|
0x1993, 0x0ae4, 0x1ccb, 0x04e9, 0x0aee, 0x1708, 0x0c3d, 0x12f2,
|
||||||
|
0x1a19, 0x07c1, 0x05a7, 0x0744, 0x1606, 0x1a9b, 0x042d, 0x1bfc,
|
||||||
|
0x1841, 0x0c3c, 0x0ffe, 0x1ab1, 0x1416, 0x18a9, 0x0320, 0x1ec2,
|
||||||
|
0x0ae7, 0x11c6, 0x124a, 0x11df, 0x0f81, 0x06cf, 0x0ed9, 0x0253,
|
||||||
|
0x1d2b, 0x0349, 0x0805, 0x08b3, 0x1052, 0x12cf, 0x0a44, 0x0ea6,
|
||||||
|
0x03bf, 0x1d90, 0x0ef8, 0x0657, 0x156d, 0x0405, 0x10be, 0x091f,
|
||||||
|
0x1c82, 0x1725, 0x19ef, 0x0b8c, 0x04d9, 0x02c7, 0x025a, 0x1b89,
|
||||||
|
0x0f5c, 0x013d, 0x02f7, 0x12e3, 0x0bc5, 0x1b56, 0x0848, 0x0239,
|
||||||
|
0x0fcf, 0x03a4, 0x092d, 0x1354, 0x1d83, 0x01bd, 0x071a, 0x0af1,
|
||||||
|
0x0875, 0x0793, 0x1b41, 0x1782, 0x0def, 0x1d20, 0x13be, 0x0095,
|
||||||
|
0x1650, 0x19d4, 0x0de3, 0x0980, 0x18f2, 0x0ca3, 0x0098, 0x149a,
|
||||||
|
0x0b81, 0x0ad2, 0x1bba, 0x1a02, 0x027b, 0x1906, 0x07f5, 0x1cae,
|
||||||
|
0x0c3f, 0x02f6, 0x1298, 0x175e, 0x15b2, 0x13d8, 0x14cc, 0x161a,
|
||||||
|
0x0a42, 0x15f3, 0x0870, 0x1c1d, 0x1203, 0x18b1, 0x1738, 0x1954,
|
||||||
|
0x1143, 0x1ae8, 0x1d9d, 0x155b, 0x11e8, 0x0ed9, 0x06f7, 0x04ca
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t const p_shuffle_add[ 256 ] =
|
||||||
|
{
|
||||||
|
0x0706, 0x175a, 0x0def, 0x1e72, 0x0297, 0x1b0e, 0x1d5a, 0x15b8,
|
||||||
|
0x13e2, 0x1347, 0x10c6, 0x0b4f, 0x0629, 0x0a75, 0x0a9b, 0x0f55,
|
||||||
|
0x1a69, 0x09bf, 0x0ba6, 0x1582, 0x1086, 0x1921, 0x01cb, 0x1c6a,
|
||||||
|
0x0ff5, 0x00f7, 0x0a67, 0x0a1e, 0x1838, 0x0196, 0x10d6, 0x0c7a,
|
||||||
|
0x180e, 0x038d, 0x1add, 0x0684, 0x154a, 0x0ab0, 0x18a4, 0x0d73,
|
||||||
|
0x1641, 0x0ec6, 0x09f1, 0x1a62, 0x0414, 0x162a, 0x194e, 0x1ec9,
|
||||||
|
0x022f, 0x0296, 0x1104, 0x14fc, 0x096c, 0x1d02, 0x09bd, 0x027c,
|
||||||
|
0x080e, 0x1324, 0x128c, 0x0dc1, 0x00b9, 0x17f2, 0x0cbc, 0x0f97,
|
||||||
|
0x1b93, 0x1c3c, 0x0415, 0x0395, 0x0c7a, 0x06cc, 0x0d4b, 0x16e2,
|
||||||
|
0x04a2, 0x0dab, 0x1228, 0x012b, 0x0896, 0x0012, 0x1cd6, 0x1dac,
|
||||||
|
0x080d, 0x0446, 0x047a, 0x00ad, 0x029e, 0x0686, 0x17c3, 0x1466,
|
||||||
|
0x0d16, 0x1896, 0x076e, 0x00cd, 0x17dc, 0x1e9f, 0x1a7c, 0x02bb,
|
||||||
|
0x0d06, 0x112b, 0x14cb, 0x0a03, 0x1541, 0x1290, 0x0f6d, 0x1503,
|
||||||
|
0x084b, 0x0382, 0x1a3f, 0x0371, 0x1977, 0x0b67, 0x0cad, 0x1df8,
|
||||||
|
0x1ce3, 0x1306, 0x13f8, 0x1163, 0x1b0b, 0x00bd, 0x0bf0, 0x1a4f,
|
||||||
|
0x16f7, 0x0b4f, 0x0cf8, 0x1254, 0x0541, 0x100d, 0x0296, 0x0410,
|
||||||
|
0x1a2b, 0x1169, 0x17d9, 0x0819, 0x03d6, 0x0d03, 0x194d, 0x184a,
|
||||||
|
0x07ca, 0x1989, 0x0fad, 0x011c, 0x1c71, 0x0ef6, 0x0dc8, 0x0f2f,
|
||||||
|
0x0fa5, 0x11be, 0x0f3b, 0x1d52, 0x0de2, 0x016e, 0x1ad1, 0x0c4a,
|
||||||
|
0x1bc2, 0x0ac9, 0x1485, 0x1bee, 0x0949, 0x1a79, 0x1894, 0x12bb,
|
||||||
|
0x17b6, 0x14f5, 0x16b1, 0x142c, 0x1301, 0x03ef, 0x16ff, 0x0d37,
|
||||||
|
0x0d78, 0x01ff, 0x00d6, 0x1053, 0x1a2a, 0x0f61, 0x1352, 0x0c7f,
|
||||||
|
0x137f, 0x09c4, 0x1d96, 0x021d, 0x1037, 0x1b19, 0x10ef, 0x14e4,
|
||||||
|
0x02a0, 0x0236, 0x0a5d, 0x1519, 0x141c, 0x1399, 0x007e, 0x1e74,
|
||||||
|
0x0941, 0x1b3c, 0x0062, 0x0371, 0x09ad, 0x08e8, 0x0a24, 0x0b97,
|
||||||
|
0x1ed2, 0x0889, 0x136b, 0x0006, 0x1c4c, 0x0444, 0x06f8, 0x0dfb,
|
||||||
|
0x1d0f, 0x198d, 0x0700, 0x0afc, 0x1781, 0x12f3, 0x10da, 0x1f19,
|
||||||
|
0x1055, 0x0dc9, 0x1860, 0x012b, 0x05bf, 0x082d, 0x0c17, 0x1941,
|
||||||
|
0x0359, 0x1232, 0x104c, 0x0762, 0x0897, 0x1d6c, 0x030f, 0x1a36,
|
||||||
|
0x16b0, 0x094d, 0x1782, 0x036f, 0x0eea, 0x06e6, 0x0d00, 0x0187,
|
||||||
|
0x17e2, 0x05e5, 0x19fa, 0x1950, 0x146a, 0x0b2a, 0x0512, 0x0ee0,
|
||||||
|
0x1e27, 0x112d, 0x1df0, 0x0b13, 0x0378, 0x1dd0, 0x00c1, 0x01e6
|
||||||
|
};
|
||||||
|
|
901
Libraries/FAAD2/Files/common/mp4ff/mp4atom.c
Normal file
901
Libraries/FAAD2/Files/common/mp4ff/mp4atom.c
Normal file
|
@ -0,0 +1,901 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include "config.h"
|
||||||
|
#else
|
||||||
|
#include <tchar.h>
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
#include <shlobj.h>
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GETPWUID
|
||||||
|
# include <pwd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#endif
|
||||||
|
#include "mp4ffint.h"
|
||||||
|
|
||||||
|
#include "drms.h"
|
||||||
|
|
||||||
|
/* parse atom header size */
|
||||||
|
static int32_t mp4ff_atom_get_size(const int8_t *data)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t a, b, c, d;
|
||||||
|
|
||||||
|
a = (uint8_t)data[0];
|
||||||
|
b = (uint8_t)data[1];
|
||||||
|
c = (uint8_t)data[2];
|
||||||
|
d = (uint8_t)data[3];
|
||||||
|
|
||||||
|
result = (a<<24) | (b<<16) | (c<<8) | d;
|
||||||
|
//if (result > 0 && result < 8) result = 8;
|
||||||
|
|
||||||
|
return (int32_t)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
|
||||||
|
static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
|
||||||
|
const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2)
|
||||||
|
{
|
||||||
|
if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
|
||||||
|
const int8_t c, const int8_t d)
|
||||||
|
{
|
||||||
|
if (a == 'm')
|
||||||
|
{
|
||||||
|
if (mp4ff_atom_compare(a,b,c,d, 'm','o','o','v'))
|
||||||
|
return ATOM_MOOV;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','i','n','f'))
|
||||||
|
return ATOM_MINF;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','d','i','a'))
|
||||||
|
return ATOM_MDIA;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','d','a','t'))
|
||||||
|
return ATOM_MDAT;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','d','h','d'))
|
||||||
|
return ATOM_MDHD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','v','h','d'))
|
||||||
|
return ATOM_MVHD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','a'))
|
||||||
|
return ATOM_MP4A;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','v'))
|
||||||
|
return ATOM_MP4V;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','s'))
|
||||||
|
return ATOM_MP4S;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'm','e','t','a'))
|
||||||
|
return ATOM_META;
|
||||||
|
} else if (a == 't') {
|
||||||
|
if (mp4ff_atom_compare(a,b,c,d, 't','r','a','k'))
|
||||||
|
return ATOM_TRAK;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 't','k','h','d'))
|
||||||
|
return ATOM_TKHD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 't','r','e','f'))
|
||||||
|
return ATOM_TREF;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 't','r','k','n'))
|
||||||
|
return ATOM_TRACK;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o'))
|
||||||
|
return ATOM_TEMPO;
|
||||||
|
} else if (a == 's') {
|
||||||
|
if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l'))
|
||||||
|
return ATOM_STBL;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','m','h','d'))
|
||||||
|
return ATOM_SMHD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','d'))
|
||||||
|
return ATOM_STSD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','t','t','s'))
|
||||||
|
return ATOM_STTS;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','t','c','o'))
|
||||||
|
return ATOM_STCO;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','c'))
|
||||||
|
return ATOM_STSC;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','z'))
|
||||||
|
return ATOM_STSZ;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','t','z','2'))
|
||||||
|
return ATOM_STZ2;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','k','i','p'))
|
||||||
|
return ATOM_SKIP;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','i','n','f'))
|
||||||
|
return ATOM_SINF;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i'))
|
||||||
|
return ATOM_SCHI;
|
||||||
|
} else if (a == '©') {
|
||||||
|
if (mp4ff_atom_compare(a,b,c,d, '©','n','a','m'))
|
||||||
|
return ATOM_TITLE;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','A','R','T'))
|
||||||
|
return ATOM_ARTIST;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','w','r','t'))
|
||||||
|
return ATOM_WRITER;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','a','l','b'))
|
||||||
|
return ATOM_ALBUM;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','d','a','y'))
|
||||||
|
return ATOM_DATE;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','t','o','o'))
|
||||||
|
return ATOM_TOOL;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','c','m','t'))
|
||||||
|
return ATOM_COMMENT;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, '©','g','e','n'))
|
||||||
|
return ATOM_GENRE1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s'))
|
||||||
|
return ATOM_EDTS;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'e','s','d','s'))
|
||||||
|
return ATOM_ESDS;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'f','t','y','p'))
|
||||||
|
return ATOM_FTYP;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'f','r','e','e'))
|
||||||
|
return ATOM_FREE;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'h','m','h','d'))
|
||||||
|
return ATOM_HMHD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'v','m','h','d'))
|
||||||
|
return ATOM_VMHD;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'u','d','t','a'))
|
||||||
|
return ATOM_UDTA;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'i','l','s','t'))
|
||||||
|
return ATOM_ILST;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'n','a','m','e'))
|
||||||
|
return ATOM_NAME;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'd','a','t','a'))
|
||||||
|
return ATOM_DATA;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'd','i','s','k'))
|
||||||
|
return ATOM_DISC;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e'))
|
||||||
|
return ATOM_GENRE2;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r'))
|
||||||
|
return ATOM_COVER;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l'))
|
||||||
|
return ATOM_COMPILATION;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s'))
|
||||||
|
return ATOM_CTTS;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s'))
|
||||||
|
return ATOM_DRMS;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a'))
|
||||||
|
return ATOM_FRMA;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v'))
|
||||||
|
return ATOM_PRIV;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v'))
|
||||||
|
return ATOM_IVIV;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'u','s','e','r'))
|
||||||
|
return ATOM_USER;
|
||||||
|
else if (mp4ff_atom_compare(a,b,c,d, 'k','e','y',' '))
|
||||||
|
return ATOM_KEY;
|
||||||
|
else
|
||||||
|
return ATOM_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read atom header, return atom size, atom size is with header included */
|
||||||
|
uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
int32_t ret;
|
||||||
|
int8_t atom_header[8];
|
||||||
|
|
||||||
|
ret = mp4ff_read_data(f, atom_header, 8);
|
||||||
|
if (ret != 8)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
size = mp4ff_atom_get_size(atom_header);
|
||||||
|
*header_size = 8;
|
||||||
|
|
||||||
|
/* check for 64 bit atom size */
|
||||||
|
if (size == 1)
|
||||||
|
{
|
||||||
|
*header_size = 16;
|
||||||
|
size = mp4ff_read_int64(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
|
||||||
|
|
||||||
|
*atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_stsz(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
|
||||||
|
f->track[f->total_tracks - 1]->stsz_sample_count = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->stsz_sample_size == 0)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
f->track[f->total_tracks - 1]->stsz_table =
|
||||||
|
(int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t));
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
|
||||||
|
{
|
||||||
|
f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_esds(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint8_t tag;
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
|
||||||
|
/* get and verify ES_DescrTag */
|
||||||
|
tag = mp4ff_read_char(f);
|
||||||
|
if (tag == 0x03)
|
||||||
|
{
|
||||||
|
/* read length */
|
||||||
|
if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* skip 3 bytes */
|
||||||
|
mp4ff_read_int24(f);
|
||||||
|
} else {
|
||||||
|
/* skip 2 bytes */
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get and verify DecoderConfigDescrTab */
|
||||||
|
if (mp4ff_read_char(f) != 0x04)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read length */
|
||||||
|
temp = mp4ff_read_mp4_descr_length(f);
|
||||||
|
if (temp < 13) return 1;
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
|
||||||
|
mp4ff_read_int32(f);//0x15000414 ????
|
||||||
|
f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
|
||||||
|
f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
/* get and verify DecSpecificInfoTag */
|
||||||
|
if (mp4ff_read_char(f) != 0x05)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read length */
|
||||||
|
f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->decoderConfig)
|
||||||
|
free(f->track[f->total_tracks - 1]->decoderConfig);
|
||||||
|
f->track[f->total_tracks - 1]->decoderConfig = malloc(f->track[f->total_tracks - 1]->decoderConfigLen);
|
||||||
|
if (f->track[f->total_tracks - 1]->decoderConfig)
|
||||||
|
{
|
||||||
|
mp4ff_read_data(f, f->track[f->total_tracks - 1]->decoderConfig, f->track[f->total_tracks - 1]->decoderConfigLen);
|
||||||
|
} else {
|
||||||
|
f->track[f->total_tracks - 1]->decoderConfigLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* will skip the remainder of the atom */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_mp4a(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
int32_t i;
|
||||||
|
uint8_t atom_type = 0;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
mp4ff_read_char(f); /* reserved */
|
||||||
|
}
|
||||||
|
/* data_reference_index */ mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
mp4ff_read_int32(f); /* reserved */
|
||||||
|
mp4ff_read_int32(f); /* reserved */
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
|
||||||
|
f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
size = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
if (atom_type == ATOM_ESDS)
|
||||||
|
{
|
||||||
|
mp4ff_read_esds(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
char *GetHomeDir( void )
|
||||||
|
{
|
||||||
|
char *p_tmp, *p_homedir = NULL;
|
||||||
|
|
||||||
|
#if defined(HAVE_GETPWUID)
|
||||||
|
struct passwd *p_pw = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(UNDER_CE)
|
||||||
|
typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
|
||||||
|
LPSTR );
|
||||||
|
# define CSIDL_FLAG_CREATE 0x8000
|
||||||
|
# define CSIDL_APPDATA 0x1A
|
||||||
|
# define SHGFP_TYPE_CURRENT 0
|
||||||
|
|
||||||
|
HINSTANCE shfolder_dll;
|
||||||
|
SHGETFOLDERPATH SHGetFolderPath ;
|
||||||
|
/* load the shfolder dll to retrieve SHGetFolderPath */
|
||||||
|
if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
|
||||||
|
{
|
||||||
|
SHGetFolderPath = (void *)GetProcAddress( shfolder_dll,
|
||||||
|
_T("SHGetFolderPathA") );
|
||||||
|
if ( SHGetFolderPath != NULL )
|
||||||
|
{
|
||||||
|
p_homedir = (char *)malloc( MAX_PATH );
|
||||||
|
if( !p_homedir )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the "Application Data" folder for the current user */
|
||||||
|
if( S_OK == SHGetFolderPath( NULL,
|
||||||
|
CSIDL_APPDATA | CSIDL_FLAG_CREATE,
|
||||||
|
NULL, SHGFP_TYPE_CURRENT,
|
||||||
|
p_homedir ) )
|
||||||
|
{
|
||||||
|
FreeLibrary( shfolder_dll );
|
||||||
|
return p_homedir;
|
||||||
|
}
|
||||||
|
free( p_homedir );
|
||||||
|
}
|
||||||
|
FreeLibrary( shfolder_dll );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_GETPWUID)
|
||||||
|
if( ( p_pw = getpwuid( getuid() ) ) == NULL )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( ( p_tmp = getenv( "HOME" ) ) == NULL )
|
||||||
|
{
|
||||||
|
if( ( p_tmp = getenv( "TMP" ) ) == NULL )
|
||||||
|
{
|
||||||
|
p_tmp = "/tmp";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_homedir = strdup( p_tmp );
|
||||||
|
}
|
||||||
|
#if defined(HAVE_GETPWUID)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p_homedir = strdup( p_pw->pw_dir );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return p_homedir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_drms(mp4ff_t *f, uint64_t skip)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
int32_t i;
|
||||||
|
uint8_t atom_type = 0;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->p_drms = drms_alloc( GetHomeDir() );
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
mp4ff_read_char(f); /* reserved */
|
||||||
|
}
|
||||||
|
/* data_reference_index */ mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
mp4ff_read_int32(f); /* reserved */
|
||||||
|
mp4ff_read_int32(f); /* reserved */
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
|
||||||
|
f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
size = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
if (atom_type == ATOM_ESDS)
|
||||||
|
{
|
||||||
|
mp4ff_read_esds(f);
|
||||||
|
}
|
||||||
|
mp4ff_set_position(f, skip+size+28);
|
||||||
|
|
||||||
|
size = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
if (atom_type == ATOM_SINF)
|
||||||
|
{
|
||||||
|
parse_sub_atoms(f, size-header_size,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_frma(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint8_t atom_type;
|
||||||
|
int8_t type[4];
|
||||||
|
|
||||||
|
mp4ff_read_data(f, type, 4);
|
||||||
|
|
||||||
|
atom_type = mp4ff_atom_name_to_type(type[0], type[1], type[2], type[3]);
|
||||||
|
|
||||||
|
if (atom_type == ATOM_MP4A)
|
||||||
|
{
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
|
||||||
|
} else if (atom_type == ATOM_MP4V) {
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
|
||||||
|
} else if (atom_type == ATOM_MP4S) {
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
|
||||||
|
} else {
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_name(mp4ff_t *f, uint64_t size)
|
||||||
|
{
|
||||||
|
uint8_t *data = malloc(size);
|
||||||
|
mp4ff_read_data(f, data, size);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->p_drms != NULL)
|
||||||
|
{
|
||||||
|
drms_init(f->track[f->total_tracks - 1]->p_drms,
|
||||||
|
FOURCC_name, data, strlen(data) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_priv(mp4ff_t *f, uint64_t size)
|
||||||
|
{
|
||||||
|
uint8_t *data = malloc(size);
|
||||||
|
mp4ff_read_data(f, data, size);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->p_drms != 0)
|
||||||
|
{
|
||||||
|
drms_init(f->track[f->total_tracks - 1]->p_drms,
|
||||||
|
FOURCC_priv, data, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_iviv(mp4ff_t *f, uint64_t size)
|
||||||
|
{
|
||||||
|
uint8_t *data = malloc(size);
|
||||||
|
mp4ff_read_data(f, data, size);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->p_drms != 0)
|
||||||
|
{
|
||||||
|
drms_init(f->track[f->total_tracks - 1]->p_drms,
|
||||||
|
FOURCC_iviv, data, sizeof(uint32_t) * 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_user(mp4ff_t *f, uint64_t size)
|
||||||
|
{
|
||||||
|
uint8_t *data = malloc(size);
|
||||||
|
mp4ff_read_data(f, data, size);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->p_drms != 0)
|
||||||
|
{
|
||||||
|
drms_init(f->track[f->total_tracks - 1]->p_drms,
|
||||||
|
FOURCC_user, data, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_key(mp4ff_t *f, uint64_t size)
|
||||||
|
{
|
||||||
|
uint8_t *data = malloc(size);
|
||||||
|
mp4ff_read_data(f, data, size);
|
||||||
|
|
||||||
|
if (f->track[f->total_tracks - 1]->p_drms != 0)
|
||||||
|
{
|
||||||
|
drms_init(f->track[f->total_tracks - 1]->p_drms,
|
||||||
|
FOURCC_key, data, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_stsd(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
|
||||||
|
{
|
||||||
|
uint64_t skip = mp4ff_position(f);
|
||||||
|
uint64_t size;
|
||||||
|
uint8_t atom_type = 0;
|
||||||
|
size = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
skip += size;
|
||||||
|
|
||||||
|
if (atom_type == ATOM_MP4A)
|
||||||
|
{
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
|
||||||
|
mp4ff_read_mp4a(f);
|
||||||
|
} else if (atom_type == ATOM_MP4V) {
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
|
||||||
|
} else if (atom_type == ATOM_MP4S) {
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
} else if (atom_type == ATOM_DRMS) {
|
||||||
|
// track type is read from the "frma" atom
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
|
||||||
|
mp4ff_read_drms(f, skip-size+header_size);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp4ff_set_position(f, skip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_stsc(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->stsc_first_chunk =
|
||||||
|
(int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
|
||||||
|
f->track[f->total_tracks - 1]->stsc_samples_per_chunk =
|
||||||
|
(int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
|
||||||
|
f->track[f->total_tracks - 1]->stsc_sample_desc_index =
|
||||||
|
(int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
|
||||||
|
{
|
||||||
|
f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f);
|
||||||
|
f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f);
|
||||||
|
f->track[f->total_tracks - 1]->stsc_sample_desc_index[i] = mp4ff_read_int32(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_stco(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1]->stco_chunk_offset =
|
||||||
|
(int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t));
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
|
||||||
|
{
|
||||||
|
f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_ctts(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
|
||||||
|
|
||||||
|
if (p_track->ctts_entry_count) return 0;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
p_track->ctts_entry_count = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
|
||||||
|
p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
|
||||||
|
|
||||||
|
if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
|
||||||
|
{
|
||||||
|
if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
|
||||||
|
if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
|
||||||
|
p_track->ctts_entry_count = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
|
||||||
|
{
|
||||||
|
p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
|
||||||
|
p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_stts(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
|
||||||
|
|
||||||
|
if (p_track->stts_entry_count) return 0;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
p_track->stts_entry_count = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
|
||||||
|
p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
|
||||||
|
|
||||||
|
if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
|
||||||
|
{
|
||||||
|
if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
|
||||||
|
if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
|
||||||
|
p_track->stts_entry_count = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
|
||||||
|
{
|
||||||
|
p_track->stts_sample_count[i] = mp4ff_read_int32(f);
|
||||||
|
p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_mvhd(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
/* creation_time */ mp4ff_read_int32(f);
|
||||||
|
/* modification_time */ mp4ff_read_int32(f);
|
||||||
|
f->time_scale = mp4ff_read_int32(f);
|
||||||
|
f->duration = mp4ff_read_int32(f);
|
||||||
|
/* preferred_rate */ mp4ff_read_int32(f); /*mp4ff_read_fixed32(f);*/
|
||||||
|
/* preferred_volume */ mp4ff_read_int16(f); /*mp4ff_read_fixed16(f);*/
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
/* reserved */ mp4ff_read_char(f);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
mp4ff_read_int32(f); /* matrix */
|
||||||
|
}
|
||||||
|
/* preview_time */ mp4ff_read_int32(f);
|
||||||
|
/* preview_duration */ mp4ff_read_int32(f);
|
||||||
|
/* poster_time */ mp4ff_read_int32(f);
|
||||||
|
/* selection_time */ mp4ff_read_int32(f);
|
||||||
|
/* selection_duration */ mp4ff_read_int32(f);
|
||||||
|
/* current_time */ mp4ff_read_int32(f);
|
||||||
|
/* next_track_id */ mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int32_t mp4ff_read_tkhd(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint8_t version;
|
||||||
|
uint32_t flags;
|
||||||
|
version = mp4ff_read_char(f); /* version */
|
||||||
|
flags = mp4ff_read_int24(f); /* flags */
|
||||||
|
if (version==1)
|
||||||
|
{
|
||||||
|
mp4ff_read_int64(f);//creation-time
|
||||||
|
mp4ff_read_int64(f);//modification-time
|
||||||
|
mp4ff_read_int32(f);//track-id
|
||||||
|
mp4ff_read_int32(f);//reserved
|
||||||
|
f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
|
||||||
|
}
|
||||||
|
else //version == 0
|
||||||
|
{
|
||||||
|
mp4ff_read_int32(f);//creation-time
|
||||||
|
mp4ff_read_int32(f);//modification-time
|
||||||
|
mp4ff_read_int32(f);//track-id
|
||||||
|
mp4ff_read_int32(f);//reserved
|
||||||
|
f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f);//duration
|
||||||
|
if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF)
|
||||||
|
f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF;
|
||||||
|
|
||||||
|
}
|
||||||
|
mp4ff_read_int32(f);//reserved
|
||||||
|
mp4ff_read_int32(f);//reserved
|
||||||
|
mp4ff_read_int16(f);//layer
|
||||||
|
mp4ff_read_int16(f);//pre-defined
|
||||||
|
mp4ff_read_int16(f);//volume
|
||||||
|
mp4ff_read_int16(f);//reserved
|
||||||
|
|
||||||
|
//matrix
|
||||||
|
mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
|
||||||
|
mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
|
||||||
|
mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
|
||||||
|
mp4ff_read_int32(f);//width
|
||||||
|
mp4ff_read_int32(f);//height
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int32_t mp4ff_read_mdhd(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
version = mp4ff_read_int32(f);
|
||||||
|
if (version==1)
|
||||||
|
{
|
||||||
|
mp4ff_read_int64(f);//creation-time
|
||||||
|
mp4ff_read_int64(f);//modification-time
|
||||||
|
f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
|
||||||
|
f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
|
||||||
|
}
|
||||||
|
else //version == 0
|
||||||
|
{
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
mp4ff_read_int32(f);//creation-time
|
||||||
|
mp4ff_read_int32(f);//modification-time
|
||||||
|
f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
|
||||||
|
temp = mp4ff_read_int32(f);
|
||||||
|
f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp);
|
||||||
|
}
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
|
||||||
|
{
|
||||||
|
uint64_t subsize, sumsize = 0;
|
||||||
|
uint8_t atom_type;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
|
||||||
|
while (sumsize < (size-(header_size+4)))
|
||||||
|
{
|
||||||
|
subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
if (subsize <= header_size+4)
|
||||||
|
return 1;
|
||||||
|
if (atom_type == ATOM_ILST)
|
||||||
|
{
|
||||||
|
mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
|
||||||
|
} else {
|
||||||
|
mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
|
||||||
|
}
|
||||||
|
sumsize += subsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
|
||||||
|
{
|
||||||
|
uint64_t dest_position = mp4ff_position(f)+size-8;
|
||||||
|
if (atom_type == ATOM_STSZ)
|
||||||
|
{
|
||||||
|
/* sample size box */
|
||||||
|
mp4ff_read_stsz(f);
|
||||||
|
} else if (atom_type == ATOM_STTS) {
|
||||||
|
/* time to sample box */
|
||||||
|
mp4ff_read_stts(f);
|
||||||
|
} else if (atom_type == ATOM_CTTS) {
|
||||||
|
/* composition offset box */
|
||||||
|
mp4ff_read_ctts(f);
|
||||||
|
} else if (atom_type == ATOM_STSC) {
|
||||||
|
/* sample to chunk box */
|
||||||
|
mp4ff_read_stsc(f);
|
||||||
|
} else if (atom_type == ATOM_STCO) {
|
||||||
|
/* chunk offset box */
|
||||||
|
mp4ff_read_stco(f);
|
||||||
|
} else if (atom_type == ATOM_STSD) {
|
||||||
|
/* sample description box */
|
||||||
|
mp4ff_read_stsd(f);
|
||||||
|
} else if (atom_type == ATOM_MVHD) {
|
||||||
|
/* movie header box */
|
||||||
|
mp4ff_read_mvhd(f);
|
||||||
|
} else if (atom_type == ATOM_MDHD) {
|
||||||
|
/* track header */
|
||||||
|
mp4ff_read_mdhd(f);
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
} else if (atom_type == ATOM_FRMA) {
|
||||||
|
/* DRM track format */
|
||||||
|
mp4ff_read_frma(f);
|
||||||
|
} else if (atom_type == ATOM_IVIV) {
|
||||||
|
mp4ff_read_iviv(f, size-8);
|
||||||
|
} else if (atom_type == ATOM_NAME) {
|
||||||
|
mp4ff_read_name(f, size-8);
|
||||||
|
} else if (atom_type == ATOM_PRIV) {
|
||||||
|
mp4ff_read_priv(f, size-8);
|
||||||
|
} else if (atom_type == ATOM_USER) {
|
||||||
|
mp4ff_read_user(f, size-8);
|
||||||
|
} else if (atom_type == ATOM_KEY) {
|
||||||
|
mp4ff_read_key(f, size-8);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
} else if (atom_type == ATOM_META) {
|
||||||
|
/* iTunes Metadata box */
|
||||||
|
mp4ff_read_meta(f, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
mp4ff_set_position(f, dest_position);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
474
Libraries/FAAD2/Files/common/mp4ff/mp4ff.c
Normal file
474
Libraries/FAAD2/Files/common/mp4ff/mp4ff.c
Normal file
|
@ -0,0 +1,474 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "mp4ffint.h"
|
||||||
|
|
||||||
|
#include "drms.h"
|
||||||
|
|
||||||
|
mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
|
||||||
|
{
|
||||||
|
mp4ff_t *ff = malloc(sizeof(mp4ff_t));
|
||||||
|
|
||||||
|
memset(ff, 0, sizeof(mp4ff_t));
|
||||||
|
|
||||||
|
ff->stream = f;
|
||||||
|
|
||||||
|
parse_atoms(ff,0);
|
||||||
|
|
||||||
|
return ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f)
|
||||||
|
{
|
||||||
|
mp4ff_t *ff = malloc(sizeof(mp4ff_t));
|
||||||
|
|
||||||
|
memset(ff, 0, sizeof(mp4ff_t));
|
||||||
|
|
||||||
|
ff->stream = f;
|
||||||
|
|
||||||
|
parse_atoms(ff,1);
|
||||||
|
|
||||||
|
return ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp4ff_close(mp4ff_t *ff)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < ff->total_tracks; i++)
|
||||||
|
{
|
||||||
|
if (ff->track[i])
|
||||||
|
{
|
||||||
|
if (ff->track[i]->stsz_table)
|
||||||
|
free(ff->track[i]->stsz_table);
|
||||||
|
if (ff->track[i]->stts_sample_count)
|
||||||
|
free(ff->track[i]->stts_sample_count);
|
||||||
|
if (ff->track[i]->stts_sample_delta)
|
||||||
|
free(ff->track[i]->stts_sample_delta);
|
||||||
|
if (ff->track[i]->stsc_first_chunk)
|
||||||
|
free(ff->track[i]->stsc_first_chunk);
|
||||||
|
if (ff->track[i]->stsc_samples_per_chunk)
|
||||||
|
free(ff->track[i]->stsc_samples_per_chunk);
|
||||||
|
if (ff->track[i]->stsc_sample_desc_index)
|
||||||
|
free(ff->track[i]->stsc_sample_desc_index);
|
||||||
|
if (ff->track[i]->stco_chunk_offset)
|
||||||
|
free(ff->track[i]->stco_chunk_offset);
|
||||||
|
if (ff->track[i]->decoderConfig)
|
||||||
|
free(ff->track[i]->decoderConfig);
|
||||||
|
if (ff->track[i]->ctts_sample_count)
|
||||||
|
free(ff->track[i]->ctts_sample_count);
|
||||||
|
if (ff->track[i]->ctts_sample_offset)
|
||||||
|
free(ff->track[i]->ctts_sample_offset);
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
if (ff->track[i]->p_drms)
|
||||||
|
drms_free(ff->track[i]->p_drms);
|
||||||
|
#endif
|
||||||
|
free(ff->track[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
mp4ff_tag_delete(&(ff->tags));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ff) free(ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mp4ff_track_add(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
f->total_tracks++;
|
||||||
|
|
||||||
|
f->track[f->total_tracks - 1] = malloc(sizeof(mp4ff_track_t));
|
||||||
|
|
||||||
|
memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int need_parse_when_meta_only(uint8_t atom_type)
|
||||||
|
{
|
||||||
|
switch(atom_type)
|
||||||
|
{
|
||||||
|
case ATOM_EDTS:
|
||||||
|
// case ATOM_MDIA:
|
||||||
|
// case ATOM_MINF:
|
||||||
|
case ATOM_DRMS:
|
||||||
|
case ATOM_SINF:
|
||||||
|
case ATOM_SCHI:
|
||||||
|
// case ATOM_STBL:
|
||||||
|
// case ATOM_STSD:
|
||||||
|
case ATOM_STTS:
|
||||||
|
case ATOM_STSZ:
|
||||||
|
case ATOM_STZ2:
|
||||||
|
case ATOM_STCO:
|
||||||
|
case ATOM_STSC:
|
||||||
|
// case ATOM_CTTS:
|
||||||
|
case ATOM_FRMA:
|
||||||
|
case ATOM_IVIV:
|
||||||
|
case ATOM_PRIV:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse atoms that are sub atoms of other atoms */
|
||||||
|
int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
uint8_t atom_type = 0;
|
||||||
|
uint64_t counted_size = 0;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
while (counted_size < total_size)
|
||||||
|
{
|
||||||
|
size = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
counted_size += size;
|
||||||
|
|
||||||
|
/* check for end of file */
|
||||||
|
if (size == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* we're starting to read a new track, update index,
|
||||||
|
* so that all data and tables get written in the right place
|
||||||
|
*/
|
||||||
|
if (atom_type == ATOM_TRAK)
|
||||||
|
{
|
||||||
|
mp4ff_track_add(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse subatoms */
|
||||||
|
if (meta_only && !need_parse_when_meta_only(atom_type))
|
||||||
|
{
|
||||||
|
mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
|
||||||
|
} else if (atom_type < SUBATOMIC)
|
||||||
|
{
|
||||||
|
parse_sub_atoms(f, size-header_size,meta_only);
|
||||||
|
} else {
|
||||||
|
mp4ff_atom_read(f, (uint32_t)size, atom_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse root atoms */
|
||||||
|
int32_t parse_atoms(mp4ff_t *f,int meta_only)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
uint8_t atom_type = 0;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
f->file_size = 0;
|
||||||
|
|
||||||
|
while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
|
||||||
|
{
|
||||||
|
f->file_size += size;
|
||||||
|
f->last_atom = atom_type;
|
||||||
|
|
||||||
|
if (atom_type == ATOM_MDAT && f->moov_read)
|
||||||
|
{
|
||||||
|
/* moov atom is before mdat, we can stop reading when mdat is encountered */
|
||||||
|
/* file position will stay at beginning of mdat data */
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atom_type == ATOM_MOOV && size > header_size)
|
||||||
|
{
|
||||||
|
f->moov_read = 1;
|
||||||
|
f->moov_offset = mp4ff_position(f)-header_size;
|
||||||
|
f->moov_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse subatoms */
|
||||||
|
if (meta_only && !need_parse_when_meta_only(atom_type))
|
||||||
|
{
|
||||||
|
mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
|
||||||
|
} else if (atom_type < SUBATOMIC)
|
||||||
|
{
|
||||||
|
parse_sub_atoms(f, size-header_size,meta_only);
|
||||||
|
} else {
|
||||||
|
/* skip this atom */
|
||||||
|
mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
|
||||||
|
uint8_t** ppBuf, uint32_t* pBufSize)
|
||||||
|
{
|
||||||
|
if (track >= f->total_tracks)
|
||||||
|
{
|
||||||
|
*ppBuf = NULL;
|
||||||
|
*pBufSize = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
|
||||||
|
{
|
||||||
|
*ppBuf = NULL;
|
||||||
|
*pBufSize = 0;
|
||||||
|
} else {
|
||||||
|
*ppBuf = malloc(f->track[track]->decoderConfigLen);
|
||||||
|
if (*ppBuf == NULL)
|
||||||
|
{
|
||||||
|
*pBufSize = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
|
||||||
|
*pBufSize = f->track[track]->decoderConfigLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track)
|
||||||
|
{
|
||||||
|
return f->track[track]->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_total_tracks(const mp4ff_t *f)
|
||||||
|
{
|
||||||
|
return f->total_tracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->timeScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->avgBitrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->maxBitrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
int64_t duration = mp4ff_get_track_duration(f,track);
|
||||||
|
if (duration!=-1)
|
||||||
|
{
|
||||||
|
int64_t offset = mp4ff_get_sample_offset(f,track,0);
|
||||||
|
if (offset > duration) duration = 0;
|
||||||
|
else duration -= offset;
|
||||||
|
}
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
int32_t total = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[track]->stts_entry_count; i++)
|
||||||
|
{
|
||||||
|
total += f->track[track]->stts_sample_count[i];
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->channelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track)
|
||||||
|
{
|
||||||
|
return f->track[track]->audioType;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t d,o;
|
||||||
|
d = mp4ff_get_sample_duration(f,track,sample);
|
||||||
|
if (d!=-1)
|
||||||
|
{
|
||||||
|
o = mp4ff_get_sample_offset(f,track,sample);
|
||||||
|
if (o>d) d = 0;
|
||||||
|
else d -= o;
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t i, co = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[track]->stts_entry_count; i++)
|
||||||
|
{
|
||||||
|
int32_t delta = f->track[track]->stts_sample_count[i];
|
||||||
|
if (sample < co + delta)
|
||||||
|
return f->track[track]->stts_sample_delta[i];
|
||||||
|
co += delta;
|
||||||
|
}
|
||||||
|
return (int32_t)(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t i, co = 0;
|
||||||
|
int64_t acc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[track]->stts_entry_count; i++)
|
||||||
|
{
|
||||||
|
int32_t delta = f->track[track]->stts_sample_count[i];
|
||||||
|
if (sample < co + delta)
|
||||||
|
{
|
||||||
|
acc += f->track[track]->stts_sample_delta[i] * (sample - co);
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
acc += f->track[track]->stts_sample_delta[i] * delta;
|
||||||
|
}
|
||||||
|
co += delta;
|
||||||
|
}
|
||||||
|
return (int64_t)(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t i, co = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < f->track[track]->ctts_entry_count; i++)
|
||||||
|
{
|
||||||
|
int32_t delta = f->track[track]->ctts_sample_count[i];
|
||||||
|
if (sample < co + delta)
|
||||||
|
return f->track[track]->ctts_sample_offset[i];
|
||||||
|
co += delta;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
|
||||||
|
{
|
||||||
|
int32_t i, co = 0;
|
||||||
|
int64_t offset_total = 0;
|
||||||
|
mp4ff_track_t * p_track = f->track[track];
|
||||||
|
|
||||||
|
for (i = 0; i < p_track->stts_entry_count; i++)
|
||||||
|
{
|
||||||
|
int32_t sample_count = p_track->stts_sample_count[i];
|
||||||
|
int32_t sample_delta = p_track->stts_sample_delta[i];
|
||||||
|
int64_t offset_delta = (int64_t)sample_delta * (int64_t)sample_count;
|
||||||
|
if (offset < offset_total + offset_delta)
|
||||||
|
{
|
||||||
|
int64_t offset_fromstts = offset - offset_total;
|
||||||
|
if (toskip) *toskip = (int32_t)(offset_fromstts % sample_delta);
|
||||||
|
return co + (int32_t)(offset_fromstts / sample_delta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset_total += offset_delta;
|
||||||
|
}
|
||||||
|
co += sample_count;
|
||||||
|
}
|
||||||
|
return (int32_t)(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
|
||||||
|
{
|
||||||
|
return mp4ff_find_sample(f,track,offset + mp4ff_get_sample_offset(f,track,0),toskip);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
|
||||||
|
uint8_t **audio_buffer, uint32_t *bytes)
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
*bytes = mp4ff_audio_frame_size(f, track, sample);
|
||||||
|
|
||||||
|
if (*bytes==0) return 0;
|
||||||
|
|
||||||
|
*audio_buffer = (uint8_t*)malloc(*bytes);
|
||||||
|
|
||||||
|
mp4ff_set_sample_position(f, track, sample);
|
||||||
|
|
||||||
|
result = mp4ff_read_data(f, *audio_buffer, *bytes);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
free(*audio_buffer);
|
||||||
|
*audio_buffer = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
if (f->track[track]->p_drms != NULL)
|
||||||
|
{
|
||||||
|
drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer)
|
||||||
|
{
|
||||||
|
int32_t result = 0;
|
||||||
|
int32_t size = mp4ff_audio_frame_size(f,track,sample);
|
||||||
|
if (size<=0) return 0;
|
||||||
|
mp4ff_set_sample_position(f, track, sample);
|
||||||
|
result = mp4ff_read_data(f,buffer,size);
|
||||||
|
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
if (f->track[track]->p_drms != NULL)
|
||||||
|
{
|
||||||
|
drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample)
|
||||||
|
{
|
||||||
|
int32_t temp = mp4ff_audio_frame_size(f, track, sample);
|
||||||
|
if (temp<0) temp = 0;
|
||||||
|
return temp;
|
||||||
|
}
|
131
Libraries/FAAD2/Files/common/mp4ff/mp4ff.h
Normal file
131
Libraries/FAAD2/Files/common/mp4ff/mp4ff.h
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef MP4FF_H
|
||||||
|
#define MP4FF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#include "mp4ff_int_types.h"
|
||||||
|
|
||||||
|
/* file callback structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
|
||||||
|
uint32_t (*write)(void *udata, void *buffer, uint32_t length);
|
||||||
|
uint32_t (*seek)(void *user_data, uint64_t position);
|
||||||
|
uint32_t (*truncate)(void *user_data);
|
||||||
|
void *user_data;
|
||||||
|
} mp4ff_callback_t;
|
||||||
|
|
||||||
|
/* mp4 main file structure */
|
||||||
|
typedef void* mp4ff_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
|
||||||
|
mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
|
||||||
|
mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f);
|
||||||
|
void mp4ff_close(mp4ff_t *f);
|
||||||
|
int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
|
||||||
|
int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
|
||||||
|
|
||||||
|
int32_t mp4ff_read_sample(mp4ff_t *f, const int track, const int sample,
|
||||||
|
unsigned char **audio_buffer, unsigned int *bytes);
|
||||||
|
|
||||||
|
int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer);//returns 0 on error, number of bytes read on success, use mp4ff_read_sample_getsize() to check buffer size needed
|
||||||
|
int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample);//returns 0 on error, buffer size needed for mp4ff_read_sample_v2() on success
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int track,
|
||||||
|
unsigned char** ppBuf, unsigned int* pBufSize);
|
||||||
|
int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track);
|
||||||
|
int32_t mp4ff_total_tracks(const mp4ff_t *f);
|
||||||
|
int32_t mp4ff_num_samples(const mp4ff_t *f, const int track);
|
||||||
|
int32_t mp4ff_time_scale(const mp4ff_t *f, const int track);
|
||||||
|
|
||||||
|
uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track);
|
||||||
|
uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track);
|
||||||
|
int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
|
||||||
|
int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
|
||||||
|
uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track);
|
||||||
|
uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track);
|
||||||
|
uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track);
|
||||||
|
|
||||||
|
|
||||||
|
/* metadata */
|
||||||
|
int mp4ff_meta_get_num_items(const mp4ff_t *f);
|
||||||
|
int mp4ff_meta_get_by_index(const mp4ff_t *f, unsigned int index,
|
||||||
|
char **item, char **value);
|
||||||
|
int mp4ff_meta_get_title(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_album(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_date(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_track(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
|
||||||
|
int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
|
||||||
|
/* metadata tag structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *item;
|
||||||
|
char *value;
|
||||||
|
} mp4ff_tag_t;
|
||||||
|
|
||||||
|
/* metadata list structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mp4ff_tag_t *tags;
|
||||||
|
uint32_t count;
|
||||||
|
} mp4ff_metadata_t;
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif
|
23
Libraries/FAAD2/Files/common/mp4ff/mp4ff_int_types.h
Normal file
23
Libraries/FAAD2/Files/common/mp4ff/mp4ff_int_types.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef _MP4FF_INT_TYPES_H_
|
||||||
|
#define _MP4FF_INT_TYPES_H_
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
typedef char int8_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef long int32_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
|
||||||
|
typedef __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
373
Libraries/FAAD2/Files/common/mp4ff/mp4ffint.h
Normal file
373
Libraries/FAAD2/Files/common/mp4ff/mp4ffint.h
Normal file
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef MP4FF_INTERNAL_H
|
||||||
|
#define MP4FF_INTERNAL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#include "mp4ff_int_types.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE)
|
||||||
|
#define ITUNES_DRM
|
||||||
|
|
||||||
|
static __inline uint32_t GetDWLE( void const * _p )
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)_p;
|
||||||
|
return ( ((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16)
|
||||||
|
| ((uint32_t)p[1] << 8) | p[0] );
|
||||||
|
}
|
||||||
|
static __inline uint32_t U32_AT( void const * _p )
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)_p;
|
||||||
|
return ( ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16)
|
||||||
|
| ((uint32_t)p[2] << 8) | p[3] );
|
||||||
|
}
|
||||||
|
static __inline uint64_t U64_AT( void const * _p )
|
||||||
|
{
|
||||||
|
uint8_t * p = (uint8_t *)_p;
|
||||||
|
return ( ((uint64_t)p[0] << 56) | ((uint64_t)p[1] << 48)
|
||||||
|
| ((uint64_t)p[2] << 40) | ((uint64_t)p[3] << 32)
|
||||||
|
| ((uint64_t)p[4] << 24) | ((uint64_t)p[5] << 16)
|
||||||
|
| ((uint64_t)p[6] << 8) | p[7] );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
# define VLC_FOURCC( a, b, c, d ) \
|
||||||
|
( ((uint32_t)d) | ( ((uint32_t)c) << 8 ) \
|
||||||
|
| ( ((uint32_t)b) << 16 ) | ( ((uint32_t)a) << 24 ) )
|
||||||
|
# define VLC_TWOCC( a, b ) \
|
||||||
|
( (uint16_t)(b) | ( (uint16_t)(a) << 8 ) )
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define VLC_FOURCC( a, b, c, d ) \
|
||||||
|
( ((uint32_t)a) | ( ((uint32_t)b) << 8 ) \
|
||||||
|
| ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) )
|
||||||
|
# define VLC_TWOCC( a, b ) \
|
||||||
|
( (uint16_t)(a) | ( (uint16_t)(b) << 8 ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FOURCC_user VLC_FOURCC( 'u', 's', 'e', 'r' )
|
||||||
|
#define FOURCC_key VLC_FOURCC( 'k', 'e', 'y', ' ' )
|
||||||
|
#define FOURCC_iviv VLC_FOURCC( 'i', 'v', 'i', 'v' )
|
||||||
|
#define FOURCC_name VLC_FOURCC( 'n', 'a', 'm', 'e' )
|
||||||
|
#define FOURCC_priv VLC_FOURCC( 'p', 'r', 'i', 'v' )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_TRACKS 1024
|
||||||
|
#define TRACK_UNKNOWN 0
|
||||||
|
#define TRACK_AUDIO 1
|
||||||
|
#define TRACK_VIDEO 2
|
||||||
|
#define TRACK_SYSTEM 3
|
||||||
|
|
||||||
|
|
||||||
|
#define SUBATOMIC 128
|
||||||
|
|
||||||
|
/* atoms without subatoms */
|
||||||
|
#define ATOM_FTYP 129
|
||||||
|
#define ATOM_MDAT 130
|
||||||
|
#define ATOM_MVHD 131
|
||||||
|
#define ATOM_TKHD 132
|
||||||
|
#define ATOM_TREF 133
|
||||||
|
#define ATOM_MDHD 134
|
||||||
|
#define ATOM_VMHD 135
|
||||||
|
#define ATOM_SMHD 136
|
||||||
|
#define ATOM_HMHD 137
|
||||||
|
#define ATOM_STSD 138
|
||||||
|
#define ATOM_STTS 139
|
||||||
|
#define ATOM_STSZ 140
|
||||||
|
#define ATOM_STZ2 141
|
||||||
|
#define ATOM_STCO 142
|
||||||
|
#define ATOM_STSC 143
|
||||||
|
#define ATOM_MP4A 144
|
||||||
|
#define ATOM_MP4V 145
|
||||||
|
#define ATOM_MP4S 146
|
||||||
|
#define ATOM_ESDS 147
|
||||||
|
#define ATOM_META 148 /* iTunes Metadata box */
|
||||||
|
#define ATOM_NAME 149 /* iTunes Metadata name box */
|
||||||
|
#define ATOM_DATA 150 /* iTunes Metadata data box */
|
||||||
|
#define ATOM_CTTS 151
|
||||||
|
#define ATOM_FRMA 152
|
||||||
|
#define ATOM_IVIV 153
|
||||||
|
#define ATOM_PRIV 154
|
||||||
|
#define ATOM_USER 155
|
||||||
|
#define ATOM_KEY 156
|
||||||
|
|
||||||
|
#define ATOM_UNKNOWN 255
|
||||||
|
#define ATOM_FREE ATOM_UNKNOWN
|
||||||
|
#define ATOM_SKIP ATOM_UNKNOWN
|
||||||
|
|
||||||
|
/* atoms with subatoms */
|
||||||
|
#define ATOM_MOOV 1
|
||||||
|
#define ATOM_TRAK 2
|
||||||
|
#define ATOM_EDTS 3
|
||||||
|
#define ATOM_MDIA 4
|
||||||
|
#define ATOM_MINF 5
|
||||||
|
#define ATOM_STBL 6
|
||||||
|
#define ATOM_UDTA 7
|
||||||
|
#define ATOM_ILST 8 /* iTunes Metadata list */
|
||||||
|
#define ATOM_TITLE 9
|
||||||
|
#define ATOM_ARTIST 10
|
||||||
|
#define ATOM_WRITER 11
|
||||||
|
#define ATOM_ALBUM 12
|
||||||
|
#define ATOM_DATE 13
|
||||||
|
#define ATOM_TOOL 14
|
||||||
|
#define ATOM_COMMENT 15
|
||||||
|
#define ATOM_GENRE1 16
|
||||||
|
#define ATOM_TRACK 17
|
||||||
|
#define ATOM_DISC 18
|
||||||
|
#define ATOM_COMPILATION 19
|
||||||
|
#define ATOM_GENRE2 20
|
||||||
|
#define ATOM_TEMPO 21
|
||||||
|
#define ATOM_COVER 22
|
||||||
|
#define ATOM_DRMS 23
|
||||||
|
#define ATOM_SINF 24
|
||||||
|
#define ATOM_SCHI 25
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(defined(_WIN32) || defined(_WIN32_WCE))
|
||||||
|
#define stricmp strcasecmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* file callback structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
|
||||||
|
uint32_t (*write)(void *udata, void *buffer, uint32_t length);
|
||||||
|
uint32_t (*seek)(void *user_data, uint64_t position);
|
||||||
|
uint32_t (*truncate)(void *user_data);
|
||||||
|
void *user_data;
|
||||||
|
} mp4ff_callback_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* metadata tag structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *item;
|
||||||
|
char *value;
|
||||||
|
} mp4ff_tag_t;
|
||||||
|
|
||||||
|
/* metadata list structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mp4ff_tag_t *tags;
|
||||||
|
uint32_t count;
|
||||||
|
} mp4ff_metadata_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t type;
|
||||||
|
int32_t channelCount;
|
||||||
|
int32_t sampleSize;
|
||||||
|
uint16_t sampleRate;
|
||||||
|
int32_t audioType;
|
||||||
|
|
||||||
|
/* stsd */
|
||||||
|
int32_t stsd_entry_count;
|
||||||
|
|
||||||
|
/* stsz */
|
||||||
|
int32_t stsz_sample_size;
|
||||||
|
int32_t stsz_sample_count;
|
||||||
|
int32_t *stsz_table;
|
||||||
|
|
||||||
|
/* stts */
|
||||||
|
int32_t stts_entry_count;
|
||||||
|
int32_t *stts_sample_count;
|
||||||
|
int32_t *stts_sample_delta;
|
||||||
|
|
||||||
|
/* stsc */
|
||||||
|
int32_t stsc_entry_count;
|
||||||
|
int32_t *stsc_first_chunk;
|
||||||
|
int32_t *stsc_samples_per_chunk;
|
||||||
|
int32_t *stsc_sample_desc_index;
|
||||||
|
|
||||||
|
/* stsc */
|
||||||
|
int32_t stco_entry_count;
|
||||||
|
int32_t *stco_chunk_offset;
|
||||||
|
|
||||||
|
/* ctts */
|
||||||
|
int32_t ctts_entry_count;
|
||||||
|
int32_t *ctts_sample_count;
|
||||||
|
int32_t *ctts_sample_offset;
|
||||||
|
|
||||||
|
/* esde */
|
||||||
|
uint8_t *decoderConfig;
|
||||||
|
int32_t decoderConfigLen;
|
||||||
|
|
||||||
|
uint32_t maxBitrate;
|
||||||
|
uint32_t avgBitrate;
|
||||||
|
|
||||||
|
uint32_t timeScale;
|
||||||
|
uint64_t duration;
|
||||||
|
|
||||||
|
#ifdef ITUNES_DRM
|
||||||
|
/* drms */
|
||||||
|
void *p_drms;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} mp4ff_track_t;
|
||||||
|
|
||||||
|
/* mp4 main file structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* stream to read from */
|
||||||
|
mp4ff_callback_t *stream;
|
||||||
|
int64_t current_position;
|
||||||
|
|
||||||
|
int32_t moov_read;
|
||||||
|
uint64_t moov_offset;
|
||||||
|
uint64_t moov_size;
|
||||||
|
uint8_t last_atom;
|
||||||
|
uint64_t file_size;
|
||||||
|
|
||||||
|
/* mvhd */
|
||||||
|
int32_t time_scale;
|
||||||
|
int32_t duration;
|
||||||
|
|
||||||
|
/* incremental track index while reading the file */
|
||||||
|
int32_t total_tracks;
|
||||||
|
|
||||||
|
/* track data */
|
||||||
|
mp4ff_track_t *track[MAX_TRACKS];
|
||||||
|
|
||||||
|
/* metadata */
|
||||||
|
mp4ff_metadata_t tags;
|
||||||
|
} mp4ff_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mp4util.c */
|
||||||
|
int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size);
|
||||||
|
int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size);
|
||||||
|
uint64_t mp4ff_read_int64(mp4ff_t *f);
|
||||||
|
uint32_t mp4ff_read_int32(mp4ff_t *f);
|
||||||
|
uint32_t mp4ff_read_int24(mp4ff_t *f);
|
||||||
|
uint16_t mp4ff_read_int16(mp4ff_t *f);
|
||||||
|
uint8_t mp4ff_read_char(mp4ff_t *f);
|
||||||
|
int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data);
|
||||||
|
uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f);
|
||||||
|
int64_t mp4ff_position(const mp4ff_t *f);
|
||||||
|
int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position);
|
||||||
|
int32_t mp4ff_truncate(mp4ff_t * f);
|
||||||
|
char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
|
||||||
|
|
||||||
|
/* mp4atom.c */
|
||||||
|
static int32_t mp4ff_atom_get_size(const int8_t *data);
|
||||||
|
static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
|
||||||
|
const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2);
|
||||||
|
static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, const int8_t c, const int8_t d);
|
||||||
|
uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size);
|
||||||
|
static int32_t mp4ff_read_stsz(mp4ff_t *f);
|
||||||
|
static int32_t mp4ff_read_esds(mp4ff_t *f);
|
||||||
|
static int32_t mp4ff_read_mp4a(mp4ff_t *f);
|
||||||
|
static int32_t mp4ff_read_stsd(mp4ff_t *f);
|
||||||
|
static int32_t mp4ff_read_stsc(mp4ff_t *f);
|
||||||
|
static int32_t mp4ff_read_stco(mp4ff_t *f);
|
||||||
|
static int32_t mp4ff_read_stts(mp4ff_t *f);
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size);
|
||||||
|
#endif
|
||||||
|
int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type);
|
||||||
|
|
||||||
|
/* mp4sample.c */
|
||||||
|
static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
|
||||||
|
int32_t *chunk_sample, int32_t *chunk);
|
||||||
|
static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk);
|
||||||
|
static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
|
||||||
|
const int32_t chunk_sample, const int32_t sample);
|
||||||
|
static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
/* mp4meta.c */
|
||||||
|
static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value);
|
||||||
|
static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value);
|
||||||
|
static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name);
|
||||||
|
static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size);
|
||||||
|
static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value);
|
||||||
|
int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size);
|
||||||
|
int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags);
|
||||||
|
int32_t mp4ff_meta_get_num_items(const mp4ff_t *f);
|
||||||
|
int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
|
||||||
|
char **item, char **value);
|
||||||
|
int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
|
||||||
|
int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* mp4ff.c */
|
||||||
|
mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
mp4ff_t *mp4ff_open_edit(mp4ff_callback_t *f);
|
||||||
|
#endif
|
||||||
|
void mp4ff_close(mp4ff_t *ff);
|
||||||
|
void mp4ff_track_add(mp4ff_t *f);
|
||||||
|
int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only);
|
||||||
|
int32_t parse_atoms(mp4ff_t *f,int meta_only);
|
||||||
|
|
||||||
|
int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
|
||||||
|
int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
|
||||||
|
|
||||||
|
int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
|
||||||
|
uint8_t **audio_buffer, uint32_t *bytes);
|
||||||
|
int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
|
||||||
|
uint8_t** ppBuf, uint32_t* pBufSize);
|
||||||
|
int32_t mp4ff_total_tracks(const mp4ff_t *f);
|
||||||
|
int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track);
|
||||||
|
int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track);
|
||||||
|
|
||||||
|
uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
|
||||||
|
const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif
|
426
Libraries/FAAD2/Files/common/mp4ff/mp4meta.c
Normal file
426
Libraries/FAAD2/Files/common/mp4ff/mp4meta.c
Normal file
|
@ -0,0 +1,426 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "mp4ffint.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value)
|
||||||
|
{
|
||||||
|
void *backup = (void *)tags->tags;
|
||||||
|
|
||||||
|
if (!item || (item && !*item) || !value) return 0;
|
||||||
|
|
||||||
|
tags->tags = (mp4ff_tag_t*)realloc(tags->tags, (tags->count+1) * sizeof(mp4ff_tag_t));
|
||||||
|
if (!tags->tags)
|
||||||
|
{
|
||||||
|
if (backup) free(backup);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
tags->tags[tags->count].item = strdup(item);
|
||||||
|
tags->tags[tags->count].value = strdup(value);
|
||||||
|
|
||||||
|
if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
|
||||||
|
{
|
||||||
|
if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
|
||||||
|
if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
|
||||||
|
tags->tags[tags->count].item = NULL;
|
||||||
|
tags->tags[tags->count].value = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tags->count++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!item || (item && !*item) || !value) return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < tags->count; i++)
|
||||||
|
{
|
||||||
|
if (!stricmp(tags->tags[i].item, item))
|
||||||
|
{
|
||||||
|
free(tags->tags[i].value);
|
||||||
|
tags->tags[i].value = strdup(value);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mp4ff_tag_add_field(tags, item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < tags->count; i++)
|
||||||
|
{
|
||||||
|
if (tags->tags[i].item) free(tags->tags[i].item);
|
||||||
|
if (tags->tags[i].value) free(tags->tags[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags->tags) free(tags->tags);
|
||||||
|
|
||||||
|
tags->tags = NULL;
|
||||||
|
tags->count = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* ID3v1GenreList[] = {
|
||||||
|
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
|
||||||
|
"Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
|
||||||
|
"Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
|
||||||
|
"Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
|
||||||
|
"Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
|
||||||
|
"Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
|
||||||
|
"Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
|
||||||
|
"Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
|
||||||
|
"Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
|
||||||
|
"Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
|
||||||
|
"Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
|
||||||
|
"New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
|
||||||
|
"Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
|
||||||
|
"Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",
|
||||||
|
"Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
|
||||||
|
"Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
|
||||||
|
"Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
|
||||||
|
"Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
|
||||||
|
"Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
|
||||||
|
"Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
|
||||||
|
"Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
|
||||||
|
"Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
|
||||||
|
"Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat",
|
||||||
|
"Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
|
||||||
|
"Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
|
||||||
|
"SynthPop",
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t mp4ff_meta_genre_to_index(const char * genrestr)
|
||||||
|
{
|
||||||
|
unsigned n;
|
||||||
|
for(n=0;n<sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]);n++)
|
||||||
|
{
|
||||||
|
if (!stricmp(genrestr,ID3v1GenreList[n])) return n+1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * mp4ff_meta_index_to_genre(uint32_t idx)
|
||||||
|
{
|
||||||
|
if (idx>0 && idx<=sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]))
|
||||||
|
{
|
||||||
|
return ID3v1GenreList[idx-1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t TrackToString(char** str, const uint16_t track, const uint16_t totalTracks)
|
||||||
|
{
|
||||||
|
char temp[32];
|
||||||
|
sprintf(temp, "%.5u of %.5u", track, totalTracks);
|
||||||
|
*str = strdup(temp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name)
|
||||||
|
{
|
||||||
|
static char *tag_names[] = {
|
||||||
|
"unknown", "title", "artist", "writer", "album",
|
||||||
|
"date", "tool", "comment", "genre", "track",
|
||||||
|
"disc", "compilation", "genre", "tempo", "cover"
|
||||||
|
};
|
||||||
|
uint8_t tag_idx = 0;
|
||||||
|
|
||||||
|
switch (atom_type)
|
||||||
|
{
|
||||||
|
case ATOM_TITLE: tag_idx = 1; break;
|
||||||
|
case ATOM_ARTIST: tag_idx = 2; break;
|
||||||
|
case ATOM_WRITER: tag_idx = 3; break;
|
||||||
|
case ATOM_ALBUM: tag_idx = 4; break;
|
||||||
|
case ATOM_DATE: tag_idx = 5; break;
|
||||||
|
case ATOM_TOOL: tag_idx = 6; break;
|
||||||
|
case ATOM_COMMENT: tag_idx = 7; break;
|
||||||
|
case ATOM_GENRE1: tag_idx = 8; break;
|
||||||
|
case ATOM_TRACK: tag_idx = 9; break;
|
||||||
|
case ATOM_DISC: tag_idx = 10; break;
|
||||||
|
case ATOM_COMPILATION: tag_idx = 11; break;
|
||||||
|
case ATOM_GENRE2: tag_idx = 12; break;
|
||||||
|
case ATOM_TEMPO: tag_idx = 13; break;
|
||||||
|
case ATOM_COVER: tag_idx = 14; break;
|
||||||
|
default: tag_idx = 0; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*name = strdup(tag_names[tag_idx]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
|
||||||
|
{
|
||||||
|
uint8_t atom_type;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
uint64_t subsize, sumsize = 0;
|
||||||
|
char * name = NULL;
|
||||||
|
char * data = NULL;
|
||||||
|
uint32_t done = 0;
|
||||||
|
|
||||||
|
|
||||||
|
while (sumsize < size)
|
||||||
|
{
|
||||||
|
uint64_t destpos;
|
||||||
|
subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
destpos = mp4ff_position(f)+subsize-header_size;
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
if (atom_type == ATOM_DATA)
|
||||||
|
{
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
mp4ff_read_int32(f); /* reserved */
|
||||||
|
|
||||||
|
/* some need special attention */
|
||||||
|
if (parent_atom_type == ATOM_GENRE2 || parent_atom_type == ATOM_TEMPO)
|
||||||
|
{
|
||||||
|
if (subsize - header_size >= 8 + 2)
|
||||||
|
{
|
||||||
|
uint16_t val = mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
if (parent_atom_type == ATOM_TEMPO)
|
||||||
|
{
|
||||||
|
char temp[16];
|
||||||
|
sprintf(temp, "%.5u BPM", val);
|
||||||
|
mp4ff_tag_add_field(&(f->tags), "tempo", temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char * temp = mp4ff_meta_index_to_genre(val);
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
mp4ff_tag_add_field(&(f->tags), "genre", temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
|
||||||
|
if (!done && subsize - header_size >= 8 + 8)
|
||||||
|
{
|
||||||
|
uint16_t index,total;
|
||||||
|
char temp[32];
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
index = mp4ff_read_int16(f);
|
||||||
|
total = mp4ff_read_int16(f);
|
||||||
|
mp4ff_read_int16(f);
|
||||||
|
|
||||||
|
sprintf(temp,"%d",index);
|
||||||
|
mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "track" : "disc", temp);
|
||||||
|
if (total>0)
|
||||||
|
{
|
||||||
|
sprintf(temp,"%d",total);
|
||||||
|
mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "totaltracks" : "totaldiscs", temp);
|
||||||
|
}
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (data) {free(data);data = NULL;}
|
||||||
|
data = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+8)));
|
||||||
|
}
|
||||||
|
} else if (atom_type == ATOM_NAME) {
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
mp4ff_read_char(f); /* version */
|
||||||
|
mp4ff_read_int24(f); /* flags */
|
||||||
|
if (name) free(name);
|
||||||
|
name = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+4)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mp4ff_set_position(f, destpos);
|
||||||
|
sumsize += subsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
if (name == NULL) mp4ff_set_metadata_name(f, parent_atom_type, &name);
|
||||||
|
if (name) mp4ff_tag_add_field(&(f->tags), name, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
if (name) free(name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size)
|
||||||
|
{
|
||||||
|
uint64_t subsize, sumsize = 0;
|
||||||
|
uint8_t atom_type;
|
||||||
|
uint8_t header_size = 0;
|
||||||
|
|
||||||
|
while (sumsize < size)
|
||||||
|
{
|
||||||
|
subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
|
||||||
|
mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
|
||||||
|
sumsize += subsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find a metadata item by name */
|
||||||
|
/* returns 0 if item found, 1 if no such item */
|
||||||
|
static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < f->tags.count; i++)
|
||||||
|
{
|
||||||
|
if (!stricmp(f->tags.tags[i].item, item))
|
||||||
|
{
|
||||||
|
*value = strdup(f->tags.tags[i].value);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = NULL;
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_num_items(const mp4ff_t *f)
|
||||||
|
{
|
||||||
|
return f->tags.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
|
||||||
|
char **item, char **value)
|
||||||
|
{
|
||||||
|
if (index >= f->tags.count)
|
||||||
|
{
|
||||||
|
*item = NULL;
|
||||||
|
*value = NULL;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
*item = strdup(f->tags.tags[index].item);
|
||||||
|
*value = strdup(f->tags.tags[index].value);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "title", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "artist", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "writer", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "album", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "date", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "tool", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "comment", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "genre", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "track", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "totaltracks", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "disc", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "totaldiscs", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "compilation", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "tempo", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value)
|
||||||
|
{
|
||||||
|
return mp4ff_meta_find_by_name(f, "cover", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
152
Libraries/FAAD2/Files/common/mp4ff/mp4sample.c
Normal file
152
Libraries/FAAD2/Files/common/mp4ff/mp4sample.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mp4ffint.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
|
||||||
|
int32_t *chunk_sample, int32_t *chunk)
|
||||||
|
{
|
||||||
|
int32_t total_entries = 0;
|
||||||
|
int32_t chunk2entry;
|
||||||
|
int32_t chunk1, chunk2, chunk1samples, range_samples, total = 0;
|
||||||
|
|
||||||
|
if (f->track[track] == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_entries = f->track[track]->stsc_entry_count;
|
||||||
|
|
||||||
|
chunk1 = 1;
|
||||||
|
chunk1samples = 0;
|
||||||
|
chunk2entry = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
chunk2 = f->track[track]->stsc_first_chunk[chunk2entry];
|
||||||
|
*chunk = chunk2 - chunk1;
|
||||||
|
range_samples = *chunk * chunk1samples;
|
||||||
|
|
||||||
|
if (sample < total + range_samples) break;
|
||||||
|
|
||||||
|
chunk1samples = f->track[track]->stsc_samples_per_chunk[chunk2entry];
|
||||||
|
chunk1 = chunk2;
|
||||||
|
|
||||||
|
if(chunk2entry < total_entries)
|
||||||
|
{
|
||||||
|
chunk2entry++;
|
||||||
|
total += range_samples;
|
||||||
|
}
|
||||||
|
} while (chunk2entry < total_entries);
|
||||||
|
|
||||||
|
if (chunk1samples)
|
||||||
|
*chunk = (sample - total) / chunk1samples + chunk1;
|
||||||
|
else
|
||||||
|
*chunk = 1;
|
||||||
|
|
||||||
|
*chunk_sample = total + (*chunk - chunk1) * chunk1samples;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk)
|
||||||
|
{
|
||||||
|
const mp4ff_track_t * p_track = f->track[track];
|
||||||
|
|
||||||
|
if (p_track->stco_entry_count && (chunk > p_track->stco_entry_count))
|
||||||
|
{
|
||||||
|
return p_track->stco_chunk_offset[p_track->stco_entry_count - 1];
|
||||||
|
} else if (p_track->stco_entry_count) {
|
||||||
|
return p_track->stco_chunk_offset[chunk - 1];
|
||||||
|
} else {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
|
||||||
|
const int32_t chunk_sample, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t i, total;
|
||||||
|
const mp4ff_track_t * p_track = f->track[track];
|
||||||
|
|
||||||
|
if (p_track->stsz_sample_size)
|
||||||
|
{
|
||||||
|
return (sample - chunk_sample) * p_track->stsz_sample_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sample>=p_track->stsz_sample_count) return 0;//error
|
||||||
|
|
||||||
|
for(i = chunk_sample, total = 0; i < sample; i++)
|
||||||
|
{
|
||||||
|
total += p_track->stsz_table[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t chunk, chunk_sample, chunk_offset1, chunk_offset2;
|
||||||
|
|
||||||
|
mp4ff_chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
|
||||||
|
|
||||||
|
chunk_offset1 = mp4ff_chunk_to_offset(f, track, chunk);
|
||||||
|
chunk_offset2 = chunk_offset1 + mp4ff_sample_range_size(f, track, chunk_sample, sample);
|
||||||
|
|
||||||
|
return chunk_offset2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t bytes;
|
||||||
|
const mp4ff_track_t * p_track = f->track[track];
|
||||||
|
|
||||||
|
if (p_track->stsz_sample_size)
|
||||||
|
{
|
||||||
|
bytes = p_track->stsz_sample_size;
|
||||||
|
} else {
|
||||||
|
bytes = p_track->stsz_table[sample];
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample)
|
||||||
|
{
|
||||||
|
int32_t offset;
|
||||||
|
|
||||||
|
offset = mp4ff_sample_to_offset(f, track, sample);
|
||||||
|
mp4ff_set_position(f, offset);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
645
Libraries/FAAD2/Files/common/mp4ff/mp4tagupdate.c
Normal file
645
Libraries/FAAD2/Files/common/mp4ff/mp4tagupdate.c
Normal file
|
@ -0,0 +1,645 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "mp4ffint.h"
|
||||||
|
|
||||||
|
#ifdef USE_TAGGING
|
||||||
|
|
||||||
|
static uint32_t fix_byte_order_32(uint32_t src)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t a, b, c, d;
|
||||||
|
int8_t data[4];
|
||||||
|
|
||||||
|
memcpy(data,&src,sizeof(src));
|
||||||
|
a = (uint8_t)data[0];
|
||||||
|
b = (uint8_t)data[1];
|
||||||
|
c = (uint8_t)data[2];
|
||||||
|
d = (uint8_t)data[3];
|
||||||
|
|
||||||
|
result = (a<<24) | (b<<16) | (c<<8) | d;
|
||||||
|
return (uint32_t)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t fix_byte_order_16(uint16_t src)
|
||||||
|
{
|
||||||
|
uint16_t result;
|
||||||
|
uint16_t a, b;
|
||||||
|
int8_t data[2];
|
||||||
|
|
||||||
|
memcpy(data,&src,sizeof(src));
|
||||||
|
a = (uint8_t)data[0];
|
||||||
|
b = (uint8_t)data[1];
|
||||||
|
|
||||||
|
result = (a<<8) | b;
|
||||||
|
return (uint16_t)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void * data;
|
||||||
|
unsigned written;
|
||||||
|
unsigned allocated;
|
||||||
|
unsigned error;
|
||||||
|
} membuffer;
|
||||||
|
|
||||||
|
unsigned membuffer_write(membuffer * buf,const void * ptr,unsigned bytes)
|
||||||
|
{
|
||||||
|
unsigned dest_size = buf->written + bytes;
|
||||||
|
|
||||||
|
if (buf->error) return 0;
|
||||||
|
if (dest_size > buf->allocated)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
buf->allocated <<= 1;
|
||||||
|
} while(dest_size > buf->allocated);
|
||||||
|
|
||||||
|
{
|
||||||
|
void * newptr = realloc(buf->data,buf->allocated);
|
||||||
|
if (newptr==0)
|
||||||
|
{
|
||||||
|
free(buf->data);
|
||||||
|
buf->data = 0;
|
||||||
|
buf->error = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
buf->data = newptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr) memcpy((char*)buf->data + buf->written,ptr,bytes);
|
||||||
|
buf->written += bytes;
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define membuffer_write_data membuffer_write
|
||||||
|
|
||||||
|
unsigned membuffer_write_int32(membuffer * buf,uint32_t data)
|
||||||
|
{
|
||||||
|
uint8_t temp[4] = {(uint8_t)(data>>24),(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
|
||||||
|
return membuffer_write_data(buf,temp,4);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_write_int24(membuffer * buf,uint32_t data)
|
||||||
|
{
|
||||||
|
uint8_t temp[3] = {(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
|
||||||
|
return membuffer_write_data(buf,temp,3);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_write_int16(membuffer * buf,uint16_t data)
|
||||||
|
{
|
||||||
|
uint8_t temp[2] = {(uint8_t)(data>>8),(uint8_t)data};
|
||||||
|
return membuffer_write_data(buf,temp,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_write_atom_name(membuffer * buf,const char * data)
|
||||||
|
{
|
||||||
|
return membuffer_write_data(buf,data,4)==4 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void membuffer_write_atom(membuffer * buf,const char * name,unsigned size,const void * data)
|
||||||
|
{
|
||||||
|
membuffer_write_int32(buf,size + 8);
|
||||||
|
membuffer_write_atom_name(buf,name);
|
||||||
|
membuffer_write_data(buf,data,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_write_string(membuffer * buf,const char * data)
|
||||||
|
{
|
||||||
|
return membuffer_write_data(buf,data,strlen(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_write_int8(membuffer * buf,uint8_t data)
|
||||||
|
{
|
||||||
|
return membuffer_write_data(buf,&data,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void * membuffer_get_ptr(const membuffer * buf)
|
||||||
|
{
|
||||||
|
return buf->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_get_size(const membuffer * buf)
|
||||||
|
{
|
||||||
|
return buf->written;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned membuffer_error(const membuffer * buf)
|
||||||
|
{
|
||||||
|
return buf->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void membuffer_set_error(membuffer * buf) {buf->error = 1;}
|
||||||
|
|
||||||
|
unsigned membuffer_transfer_from_file(membuffer * buf,mp4ff_t * src,unsigned bytes)
|
||||||
|
{
|
||||||
|
unsigned oldsize;
|
||||||
|
void * bufptr;
|
||||||
|
|
||||||
|
oldsize = membuffer_get_size(buf);
|
||||||
|
if (membuffer_write_data(buf,0,bytes) != bytes) return 0;
|
||||||
|
|
||||||
|
bufptr = membuffer_get_ptr(buf);
|
||||||
|
if (bufptr==0) return 0;
|
||||||
|
|
||||||
|
if ((unsigned)mp4ff_read_data(src,(char*)bufptr + oldsize,bytes)!=bytes)
|
||||||
|
{
|
||||||
|
membuffer_set_error(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
membuffer * membuffer_create()
|
||||||
|
{
|
||||||
|
const unsigned initial_size = 256;
|
||||||
|
|
||||||
|
membuffer * buf = (membuffer *) malloc(sizeof(membuffer));
|
||||||
|
buf->data = malloc(initial_size);
|
||||||
|
buf->written = 0;
|
||||||
|
buf->allocated = initial_size;
|
||||||
|
buf->error = buf->data == 0 ? 1 : 0;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void membuffer_free(membuffer * buf)
|
||||||
|
{
|
||||||
|
if (buf->data) free(buf->data);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void * membuffer_detach(membuffer * buf)
|
||||||
|
{
|
||||||
|
void * ret;
|
||||||
|
|
||||||
|
if (buf->error) return 0;
|
||||||
|
|
||||||
|
ret = realloc(buf->data,buf->written);
|
||||||
|
|
||||||
|
if (ret == 0) free(buf->data);
|
||||||
|
|
||||||
|
buf->data = 0;
|
||||||
|
buf->error = 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* metadata tag structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *item;
|
||||||
|
char *value;
|
||||||
|
} mp4ff_tag_t;
|
||||||
|
|
||||||
|
/* metadata list structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mp4ff_tag_t *tags;
|
||||||
|
uint32_t count;
|
||||||
|
} mp4ff_metadata_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char * atom;
|
||||||
|
const char * name;
|
||||||
|
} stdmeta_entry;
|
||||||
|
|
||||||
|
static stdmeta_entry stdmetas[] =
|
||||||
|
{
|
||||||
|
{"©nam","title"},
|
||||||
|
{"©ART","artist"},
|
||||||
|
{"©wrt","writer"},
|
||||||
|
{"©alb","album"},
|
||||||
|
{"©day","date"},
|
||||||
|
{"©too","tool"},
|
||||||
|
{"©cmt","comment"},
|
||||||
|
// {"©gen","genre"},
|
||||||
|
{"cpil","compilation"},
|
||||||
|
// {"trkn","track"},
|
||||||
|
// {"disk","disc"},
|
||||||
|
// {"gnre","genre"},
|
||||||
|
{"covr","cover"},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const char* find_standard_meta(const char * name) //returns atom name if found, 0 if not
|
||||||
|
{
|
||||||
|
unsigned n;
|
||||||
|
for(n=0;n<sizeof(stdmetas)/sizeof(stdmetas[0]);n++)
|
||||||
|
{
|
||||||
|
if (!stricmp(name,stdmetas[n].name)) return stdmetas[n].atom;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void membuffer_write_track_tag(membuffer * buf,const char * name,uint32_t index,uint32_t total)
|
||||||
|
{
|
||||||
|
membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
|
||||||
|
membuffer_write_atom_name(buf,name);
|
||||||
|
membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
|
||||||
|
membuffer_write_atom_name(buf,"data");
|
||||||
|
membuffer_write_int32(buf,0);//flags
|
||||||
|
membuffer_write_int32(buf,0);//reserved
|
||||||
|
membuffer_write_int16(buf,0);
|
||||||
|
membuffer_write_int16(buf,(uint16_t)index);//track number
|
||||||
|
membuffer_write_int16(buf,(uint16_t)total);//total tracks
|
||||||
|
membuffer_write_int16(buf,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void membuffer_write_int16_tag(membuffer * buf,const char * name,uint16_t value)
|
||||||
|
{
|
||||||
|
membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
|
||||||
|
membuffer_write_atom_name(buf,name);
|
||||||
|
membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
|
||||||
|
membuffer_write_atom_name(buf,"data");
|
||||||
|
membuffer_write_int32(buf,0);//flags
|
||||||
|
membuffer_write_int32(buf,0);//reserved
|
||||||
|
membuffer_write_int16(buf,value);//value
|
||||||
|
}
|
||||||
|
|
||||||
|
static void membuffer_write_std_tag(membuffer * buf,const char * name,const char * value)
|
||||||
|
{
|
||||||
|
membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value) );
|
||||||
|
membuffer_write_atom_name(buf,name);
|
||||||
|
membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
|
||||||
|
membuffer_write_atom_name(buf,"data");
|
||||||
|
membuffer_write_int32(buf,1);//flags
|
||||||
|
membuffer_write_int32(buf,0);//reserved
|
||||||
|
membuffer_write_data(buf,value,strlen(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void membuffer_write_custom_tag(membuffer * buf,const char * name,const char * value)
|
||||||
|
{
|
||||||
|
membuffer_write_int32(buf,8 /*atom header*/ + 0x1C /*weirdo itunes atom*/ + 12 /*name atom header*/ + strlen(name) + 16 /*data atom header + flags*/ + strlen(value) );
|
||||||
|
membuffer_write_atom_name(buf,"----");
|
||||||
|
membuffer_write_int32(buf,0x1C);//weirdo itunes atom
|
||||||
|
membuffer_write_atom_name(buf,"mean");
|
||||||
|
membuffer_write_int32(buf,0);
|
||||||
|
membuffer_write_data(buf,"com.apple.iTunes",16);
|
||||||
|
membuffer_write_int32(buf,12 + strlen(name));
|
||||||
|
membuffer_write_atom_name(buf,"name");
|
||||||
|
membuffer_write_int32(buf,0);
|
||||||
|
membuffer_write_data(buf,name,strlen(name));
|
||||||
|
membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
|
||||||
|
membuffer_write_atom_name(buf,"data");
|
||||||
|
membuffer_write_int32(buf,1);//flags
|
||||||
|
membuffer_write_int32(buf,0);//reserved
|
||||||
|
membuffer_write_data(buf,value,strlen(value));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t myatoi(const char * param)
|
||||||
|
{
|
||||||
|
return param ? atoi(param) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t create_ilst(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
|
||||||
|
{
|
||||||
|
membuffer * buf = membuffer_create();
|
||||||
|
unsigned metaptr;
|
||||||
|
char * mask = (char*)malloc(data->count);
|
||||||
|
memset(mask,0,data->count);
|
||||||
|
|
||||||
|
{
|
||||||
|
const char * tracknumber_ptr = 0, * totaltracks_ptr = 0;
|
||||||
|
const char * discnumber_ptr = 0, * totaldiscs_ptr = 0;
|
||||||
|
const char * genre_ptr = 0, * tempo_ptr = 0;
|
||||||
|
for(metaptr = 0; metaptr < data->count; metaptr++)
|
||||||
|
{
|
||||||
|
mp4ff_tag_t * tag = &data->tags[metaptr];
|
||||||
|
if (!stricmp(tag->item,"tracknumber") || !stricmp(tag->item,"track"))
|
||||||
|
{
|
||||||
|
if (tracknumber_ptr==0) tracknumber_ptr = tag->value;
|
||||||
|
mask[metaptr] = 1;
|
||||||
|
}
|
||||||
|
else if (!stricmp(tag->item,"totaltracks"))
|
||||||
|
{
|
||||||
|
if (totaltracks_ptr==0) totaltracks_ptr = tag->value;
|
||||||
|
mask[metaptr] = 1;
|
||||||
|
}
|
||||||
|
else if (!stricmp(tag->item,"discnumber") || !stricmp(tag->item,"disc"))
|
||||||
|
{
|
||||||
|
if (discnumber_ptr==0) discnumber_ptr = tag->value;
|
||||||
|
mask[metaptr] = 1;
|
||||||
|
}
|
||||||
|
else if (!stricmp(tag->item,"totaldiscs"))
|
||||||
|
{
|
||||||
|
if (totaldiscs_ptr==0) totaldiscs_ptr = tag->value;
|
||||||
|
mask[metaptr] = 1;
|
||||||
|
}
|
||||||
|
else if (!stricmp(tag->item,"genre"))
|
||||||
|
{
|
||||||
|
if (genre_ptr==0) genre_ptr = tag->value;
|
||||||
|
mask[metaptr] = 1;
|
||||||
|
}
|
||||||
|
else if (!stricmp(tag->item,"tempo"))
|
||||||
|
{
|
||||||
|
if (tempo_ptr==0) tempo_ptr = tag->value;
|
||||||
|
mask[metaptr] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tracknumber_ptr) membuffer_write_track_tag(buf,"trkn",myatoi(tracknumber_ptr),myatoi(totaltracks_ptr));
|
||||||
|
if (discnumber_ptr) membuffer_write_track_tag(buf,"disk",myatoi(discnumber_ptr),myatoi(totaldiscs_ptr));
|
||||||
|
if (tempo_ptr) membuffer_write_int16_tag(buf,"tmpo",(uint16_t)myatoi(tempo_ptr));
|
||||||
|
|
||||||
|
if (genre_ptr)
|
||||||
|
{
|
||||||
|
uint32_t index = mp4ff_meta_genre_to_index(genre_ptr);
|
||||||
|
if (index==0)
|
||||||
|
membuffer_write_std_tag(buf,"©gen",genre_ptr);
|
||||||
|
else
|
||||||
|
membuffer_write_int16_tag(buf,"gnre",(uint16_t)index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(metaptr = 0; metaptr < data->count; metaptr++)
|
||||||
|
{
|
||||||
|
if (!mask[metaptr])
|
||||||
|
{
|
||||||
|
mp4ff_tag_t * tag = &data->tags[metaptr];
|
||||||
|
const char * std_meta_atom = find_standard_meta(tag->item);
|
||||||
|
if (std_meta_atom)
|
||||||
|
{
|
||||||
|
membuffer_write_std_tag(buf,std_meta_atom,tag->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
membuffer_write_custom_tag(buf,tag->item,tag->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(mask);
|
||||||
|
|
||||||
|
if (membuffer_error(buf))
|
||||||
|
{
|
||||||
|
membuffer_free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_size = membuffer_get_size(buf);
|
||||||
|
*out_buffer = membuffer_detach(buf);
|
||||||
|
membuffer_free(buf);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t find_atom(mp4ff_t * f,uint64_t base,uint32_t size,const char * name)
|
||||||
|
{
|
||||||
|
uint32_t remaining = size;
|
||||||
|
uint64_t atom_offset = base;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
char atom_name[4];
|
||||||
|
uint32_t atom_size;
|
||||||
|
|
||||||
|
mp4ff_set_position(f,atom_offset);
|
||||||
|
|
||||||
|
if (remaining < 8) break;
|
||||||
|
atom_size = mp4ff_read_int32(f);
|
||||||
|
if (atom_size > remaining || atom_size < 8) break;
|
||||||
|
mp4ff_read_data(f,atom_name,4);
|
||||||
|
|
||||||
|
if (!memcmp(atom_name,name,4))
|
||||||
|
{
|
||||||
|
mp4ff_set_position(f,atom_offset);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining -= atom_size;
|
||||||
|
atom_offset += atom_size;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t find_atom_v2(mp4ff_t * f,uint64_t base,uint32_t size,const char * name,uint32_t extraheaders,const char * name_inside)
|
||||||
|
{
|
||||||
|
uint64_t first_base = (uint64_t)(-1);
|
||||||
|
while(find_atom(f,base,size,name))//try to find atom <name> with atom <name_inside> in it
|
||||||
|
{
|
||||||
|
uint64_t mybase = mp4ff_position(f);
|
||||||
|
uint32_t mysize = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
if (first_base == (uint64_t)(-1)) first_base = mybase;
|
||||||
|
|
||||||
|
if (mysize < 8 + extraheaders) break;
|
||||||
|
|
||||||
|
if (find_atom(f,mybase+(8+extraheaders),mysize-(8+extraheaders),name_inside))
|
||||||
|
{
|
||||||
|
mp4ff_set_position(f,mybase);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
base += mysize;
|
||||||
|
if (size<=mysize) {size=0;break;}
|
||||||
|
size -= mysize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_base != (uint64_t)(-1))//wanted atom inside not found
|
||||||
|
{
|
||||||
|
mp4ff_set_position(f,first_base);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t create_meta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
|
||||||
|
{
|
||||||
|
membuffer * buf;
|
||||||
|
uint32_t ilst_size;
|
||||||
|
void * ilst_buffer;
|
||||||
|
|
||||||
|
if (!create_ilst(data,&ilst_buffer,&ilst_size)) return 0;
|
||||||
|
|
||||||
|
buf = membuffer_create();
|
||||||
|
|
||||||
|
membuffer_write_int32(buf,0);
|
||||||
|
membuffer_write_atom(buf,"ilst",ilst_size,ilst_buffer);
|
||||||
|
free(ilst_buffer);
|
||||||
|
|
||||||
|
*out_size = membuffer_get_size(buf);
|
||||||
|
*out_buffer = membuffer_detach(buf);
|
||||||
|
membuffer_free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t create_udta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
|
||||||
|
{
|
||||||
|
membuffer * buf;
|
||||||
|
uint32_t meta_size;
|
||||||
|
void * meta_buffer;
|
||||||
|
|
||||||
|
if (!create_meta(data,&meta_buffer,&meta_size)) return 0;
|
||||||
|
|
||||||
|
buf = membuffer_create();
|
||||||
|
|
||||||
|
membuffer_write_atom(buf,"meta",meta_size,meta_buffer);
|
||||||
|
|
||||||
|
free(meta_buffer);
|
||||||
|
|
||||||
|
*out_size = membuffer_get_size(buf);
|
||||||
|
*out_buffer = membuffer_detach(buf);
|
||||||
|
membuffer_free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t modify_moov(mp4ff_t * f,const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
|
||||||
|
{
|
||||||
|
uint64_t total_base = f->moov_offset + 8;
|
||||||
|
uint32_t total_size = (uint32_t)(f->moov_size - 8);
|
||||||
|
|
||||||
|
uint64_t udta_offset,meta_offset,ilst_offset;
|
||||||
|
uint32_t udta_size, meta_size, ilst_size;
|
||||||
|
|
||||||
|
uint32_t new_ilst_size;
|
||||||
|
void * new_ilst_buffer;
|
||||||
|
|
||||||
|
uint8_t * p_out;
|
||||||
|
int32_t size_delta;
|
||||||
|
|
||||||
|
|
||||||
|
if (!find_atom_v2(f,total_base,total_size,"udta",0,"meta"))
|
||||||
|
{
|
||||||
|
membuffer * buf;
|
||||||
|
void * new_udta_buffer;
|
||||||
|
uint32_t new_udta_size;
|
||||||
|
if (!create_udta(data,&new_udta_buffer,&new_udta_size)) return 0;
|
||||||
|
|
||||||
|
buf = membuffer_create();
|
||||||
|
mp4ff_set_position(f,total_base);
|
||||||
|
membuffer_transfer_from_file(buf,f,total_size);
|
||||||
|
|
||||||
|
membuffer_write_atom(buf,"udta",new_udta_size,new_udta_buffer);
|
||||||
|
|
||||||
|
free(new_udta_buffer);
|
||||||
|
|
||||||
|
*out_size = membuffer_get_size(buf);
|
||||||
|
*out_buffer = membuffer_detach(buf);
|
||||||
|
membuffer_free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
udta_offset = mp4ff_position(f);
|
||||||
|
udta_size = mp4ff_read_int32(f);
|
||||||
|
if (find_atom_v2(f,udta_offset+8,udta_size-8,"meta",4,"ilst")<2)
|
||||||
|
{
|
||||||
|
membuffer * buf;
|
||||||
|
void * new_meta_buffer;
|
||||||
|
uint32_t new_meta_size;
|
||||||
|
if (!create_meta(data,&new_meta_buffer,&new_meta_size)) return 0;
|
||||||
|
|
||||||
|
buf = membuffer_create();
|
||||||
|
mp4ff_set_position(f,total_base);
|
||||||
|
membuffer_transfer_from_file(buf,f,(uint32_t)(udta_offset - total_base));
|
||||||
|
|
||||||
|
membuffer_write_int32(buf,udta_size + 8 + new_meta_size);
|
||||||
|
membuffer_write_atom_name(buf,"udta");
|
||||||
|
membuffer_transfer_from_file(buf,f,udta_size);
|
||||||
|
|
||||||
|
membuffer_write_atom(buf,"meta",new_meta_size,new_meta_buffer);
|
||||||
|
free(new_meta_buffer);
|
||||||
|
|
||||||
|
*out_size = membuffer_get_size(buf);
|
||||||
|
*out_buffer = membuffer_detach(buf);
|
||||||
|
membuffer_free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
meta_offset = mp4ff_position(f);
|
||||||
|
meta_size = mp4ff_read_int32(f);
|
||||||
|
if (!find_atom(f,meta_offset+12,meta_size-12,"ilst")) return 0;//shouldn't happen, find_atom_v2 above takes care of it
|
||||||
|
ilst_offset = mp4ff_position(f);
|
||||||
|
ilst_size = mp4ff_read_int32(f);
|
||||||
|
|
||||||
|
if (!create_ilst(data,&new_ilst_buffer,&new_ilst_size)) return 0;
|
||||||
|
|
||||||
|
size_delta = new_ilst_size - (ilst_size - 8);
|
||||||
|
|
||||||
|
*out_size = total_size + size_delta;
|
||||||
|
*out_buffer = malloc(*out_size);
|
||||||
|
if (*out_buffer == 0)
|
||||||
|
{
|
||||||
|
free(new_ilst_buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_out = (uint8_t*)*out_buffer;
|
||||||
|
|
||||||
|
mp4ff_set_position(f,total_base);
|
||||||
|
mp4ff_read_data(f,p_out,(uint32_t)(udta_offset - total_base )); p_out += (uint32_t)(udta_offset - total_base );
|
||||||
|
*(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
|
||||||
|
mp4ff_read_data(f,p_out,4); p_out += 4;
|
||||||
|
mp4ff_read_data(f,p_out,(uint32_t)(meta_offset - udta_offset - 8)); p_out += (uint32_t)(meta_offset - udta_offset - 8);
|
||||||
|
*(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
|
||||||
|
mp4ff_read_data(f,p_out,4); p_out += 4;
|
||||||
|
mp4ff_read_data(f,p_out,(uint32_t)(ilst_offset - meta_offset - 8)); p_out += (uint32_t)(ilst_offset - meta_offset - 8);
|
||||||
|
*(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
|
||||||
|
mp4ff_read_data(f,p_out,4); p_out += 4;
|
||||||
|
|
||||||
|
memcpy(p_out,new_ilst_buffer,new_ilst_size);
|
||||||
|
p_out += new_ilst_size;
|
||||||
|
|
||||||
|
mp4ff_set_position(f,ilst_offset + ilst_size);
|
||||||
|
mp4ff_read_data(f,p_out,(uint32_t)(total_size - (ilst_offset - total_base) - ilst_size));
|
||||||
|
|
||||||
|
free(new_ilst_buffer);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data)
|
||||||
|
{
|
||||||
|
void * new_moov_data;
|
||||||
|
uint32_t new_moov_size;
|
||||||
|
|
||||||
|
mp4ff_t *ff = malloc(sizeof(mp4ff_t));
|
||||||
|
|
||||||
|
memset(ff, 0, sizeof(mp4ff_t));
|
||||||
|
ff->stream = f;
|
||||||
|
mp4ff_set_position(ff,0);
|
||||||
|
|
||||||
|
parse_atoms(ff,1);
|
||||||
|
|
||||||
|
|
||||||
|
if (!modify_moov(ff,data,&new_moov_data,&new_moov_size))
|
||||||
|
{
|
||||||
|
mp4ff_close(ff);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy moov atom to end of the file */
|
||||||
|
if (ff->last_atom != ATOM_MOOV)
|
||||||
|
{
|
||||||
|
char *free_data = "free";
|
||||||
|
|
||||||
|
/* rename old moov to free */
|
||||||
|
mp4ff_set_position(ff, ff->moov_offset + 4);
|
||||||
|
mp4ff_write_data(ff, free_data, 4);
|
||||||
|
|
||||||
|
mp4ff_set_position(ff, ff->file_size);
|
||||||
|
mp4ff_write_int32(ff,new_moov_size + 8);
|
||||||
|
mp4ff_write_data(ff,"moov",4);
|
||||||
|
mp4ff_write_data(ff, new_moov_data, new_moov_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mp4ff_set_position(ff, ff->moov_offset);
|
||||||
|
mp4ff_write_int32(ff,new_moov_size + 8);
|
||||||
|
mp4ff_write_data(ff,"moov",4);
|
||||||
|
mp4ff_write_data(ff, new_moov_data, new_moov_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp4ff_truncate(ff);
|
||||||
|
|
||||||
|
mp4ff_close(ff);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
188
Libraries/FAAD2/Files/common/mp4ff/mp4util.c
Normal file
188
Libraries/FAAD2/Files/common/mp4ff/mp4util.c
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
||||||
|
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
**
|
||||||
|
** Any non-GPL usage of this software or parts of this software is strictly
|
||||||
|
** forbidden.
|
||||||
|
**
|
||||||
|
** Commercial non-GPL licensing of this software is possible.
|
||||||
|
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
||||||
|
**
|
||||||
|
** $Id$
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "mp4ffint.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size)
|
||||||
|
{
|
||||||
|
int32_t result = 1;
|
||||||
|
|
||||||
|
result = f->stream->read(f->stream->user_data, data, size);
|
||||||
|
|
||||||
|
f->current_position += size;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_truncate(mp4ff_t * f)
|
||||||
|
{
|
||||||
|
return f->stream->truncate(f->stream->user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size)
|
||||||
|
{
|
||||||
|
int32_t result = 1;
|
||||||
|
|
||||||
|
result = f->stream->write(f->stream->user_data, data, size);
|
||||||
|
|
||||||
|
f->current_position += size;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t a, b, c, d;
|
||||||
|
int8_t temp[4];
|
||||||
|
|
||||||
|
*(uint32_t*)temp = data;
|
||||||
|
a = (uint8_t)temp[0];
|
||||||
|
b = (uint8_t)temp[1];
|
||||||
|
c = (uint8_t)temp[2];
|
||||||
|
d = (uint8_t)temp[3];
|
||||||
|
|
||||||
|
result = (a<<24) | (b<<16) | (c<<8) | d;
|
||||||
|
|
||||||
|
return mp4ff_write_data(f,(uint8_t*)&result,sizeof(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position)
|
||||||
|
{
|
||||||
|
f->stream->seek(f->stream->user_data, position);
|
||||||
|
f->current_position = position;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mp4ff_position(const mp4ff_t *f)
|
||||||
|
{
|
||||||
|
return f->current_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mp4ff_read_int64(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint8_t data[8];
|
||||||
|
uint64_t result = 0;
|
||||||
|
int8_t i;
|
||||||
|
|
||||||
|
mp4ff_read_data(f, data, 8);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
result |= ((uint64_t)data[i]) << ((7 - i) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_read_int32(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t a, b, c, d;
|
||||||
|
int8_t data[4];
|
||||||
|
|
||||||
|
mp4ff_read_data(f, data, 4);
|
||||||
|
a = (uint8_t)data[0];
|
||||||
|
b = (uint8_t)data[1];
|
||||||
|
c = (uint8_t)data[2];
|
||||||
|
d = (uint8_t)data[3];
|
||||||
|
|
||||||
|
result = (a<<24) | (b<<16) | (c<<8) | d;
|
||||||
|
return (uint32_t)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_read_int24(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t a, b, c;
|
||||||
|
int8_t data[4];
|
||||||
|
|
||||||
|
mp4ff_read_data(f, data, 3);
|
||||||
|
a = (uint8_t)data[0];
|
||||||
|
b = (uint8_t)data[1];
|
||||||
|
c = (uint8_t)data[2];
|
||||||
|
|
||||||
|
result = (a<<16) | (b<<8) | c;
|
||||||
|
return (uint32_t)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mp4ff_read_int16(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t a, b;
|
||||||
|
int8_t data[2];
|
||||||
|
|
||||||
|
mp4ff_read_data(f, data, 2);
|
||||||
|
a = (uint8_t)data[0];
|
||||||
|
b = (uint8_t)data[1];
|
||||||
|
|
||||||
|
result = (a<<8) | b;
|
||||||
|
return (uint16_t)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
|
||||||
|
{
|
||||||
|
char * str = (char*)malloc(length + 1);
|
||||||
|
if (str!=0)
|
||||||
|
{
|
||||||
|
if ((uint32_t)mp4ff_read_data(f,str,length)!=length)
|
||||||
|
{
|
||||||
|
free(str);
|
||||||
|
str = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str[length] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t mp4ff_read_char(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint8_t output;
|
||||||
|
mp4ff_read_data(f, &output, 1);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f)
|
||||||
|
{
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t numBytes = 0;
|
||||||
|
uint32_t length = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
b = mp4ff_read_char(f);
|
||||||
|
numBytes++;
|
||||||
|
length = (length << 7) | (b & 0x7F);
|
||||||
|
} while ((b & 0x80) && numBytes < 4);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
11
Libraries/Shorten/Files/AUTHORS
Normal file
11
Libraries/Shorten/Files/AUTHORS
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Marcus Heese
|
||||||
|
marc.icq@gmx.de
|
||||||
|
icq : 126202773
|
||||||
|
|
||||||
|
and very special thanks to...
|
||||||
|
|
||||||
|
Frederic Fondriest
|
||||||
|
icq : 17293220
|
||||||
|
irc : /server irc.eu.freenode.net /join #lamip
|
||||||
|
|
||||||
|
...for a linux audio player with a very good API! :)
|
340
Libraries/Shorten/Files/COPYING
Normal file
340
Libraries/Shorten/Files/COPYING
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
6
Libraries/Shorten/Files/ChangeLog
Normal file
6
Libraries/Shorten/Files/ChangeLog
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
lamip-inputSHORTEN_20050405:
|
||||||
|
- fixed a few minor things. Some variables have to be declared static!
|
||||||
|
|
||||||
|
lamip-inputSHORTEN_20050324:
|
||||||
|
- well.... it is the initial release!
|
||||||
|
|
1
Libraries/Shorten/Files/Makefile.am
Normal file
1
Libraries/Shorten/Files/Makefile.am
Normal file
|
@ -0,0 +1 @@
|
||||||
|
SUBDIRS = shorten src
|
2
Libraries/Shorten/Files/NEWS
Normal file
2
Libraries/Shorten/Files/NEWS
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
well... who the hell takes a look in all these damn files?!?
|
||||||
|
|
45
Libraries/Shorten/Files/README
Normal file
45
Libraries/Shorten/Files/README
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
LAMIP-0.0.3 SHORTEN decoder
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
This is a shorten decoder for lamip. SHORTEN has been a widely used lossless
|
||||||
|
codec. Since version 3 shorten has seeking support through seek tables (.skt).
|
||||||
|
They can also be merged into the shorten file (.shn). The code for this plugin
|
||||||
|
derives from the xmms shorten plugin version 2.4.0 written by Jason Jordan.
|
||||||
|
Look at that homepage:
|
||||||
|
|
||||||
|
http://etree.org/shnutils/shorten/
|
||||||
|
|
||||||
|
I have redesigned the xmms-shn plugin for a libshorten decoding library. You
|
||||||
|
should be able to install libshorten as a standalone-lib and decode shorten
|
||||||
|
files through that library
|
||||||
|
|
||||||
|
Config options
|
||||||
|
--------------
|
||||||
|
- error_output_method: can be STDERR and DEVNULL... I think the names are
|
||||||
|
self explanatory
|
||||||
|
|
||||||
|
- swap_bytes: If you have a big-endian machine, switch it on!
|
||||||
|
|
||||||
|
- verbose: It is for some verbose debugging messages in the integrated logging
|
||||||
|
facility of libshorten
|
||||||
|
|
||||||
|
- seek_tables_path: An absolute path to a directory which contains shorten seek-
|
||||||
|
tables
|
||||||
|
|
||||||
|
- relative_seek_tables_path: A relative path to directories which contain
|
||||||
|
shorten seek-tables
|
||||||
|
|
||||||
|
|
||||||
|
INSTALL
|
||||||
|
-------
|
||||||
|
run :
|
||||||
|
- autoreconf -vifs
|
||||||
|
- ./configure --enable-debug
|
||||||
|
- make
|
||||||
|
|
||||||
|
and as root :
|
||||||
|
- make install or make install-strip
|
||||||
|
|
||||||
|
----------
|
||||||
|
marc.icq@gmx.de
|
||||||
|
|
7
Libraries/Shorten/Files/TODO
Normal file
7
Libraries/Shorten/Files/TODO
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
for the future:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
- implement id3v2 tag reading, perhaps... :)
|
||||||
|
- link against a released libshorten (static development version used in this plugin by now)
|
||||||
|
- documentation for libshorten
|
||||||
|
|
78
Libraries/Shorten/Files/configure.ac
Normal file
78
Libraries/Shorten/Files/configure.ac
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
dnl configure.in for lamip-0.0.3 shorten input plugin
|
||||||
|
|
||||||
|
AC_INIT(libinputshorten, 0.0.3)
|
||||||
|
AC_CONFIG_SRCDIR(src/libinputshorten.c)
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE(inputSHORTEN, 0.0.3)
|
||||||
|
AM_CONFIG_HEADER(shorten/include/config.h)
|
||||||
|
|
||||||
|
dnl AC_INIT(src/libinputshorten.c)
|
||||||
|
dnl AM_INIT_AUTOMAKE(libinputshorten, 0.0.3)
|
||||||
|
|
||||||
|
AM_DISABLE_STATIC
|
||||||
|
|
||||||
|
dnl save CFLAGS since AC_PROG_CC insert "-g -O2" if CFLAGS is empty
|
||||||
|
cflags_save="$CFLAGS"
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_AWK
|
||||||
|
AC_PROG_LN_S
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_LIBTOOL_DLOPEN
|
||||||
|
AM_PROG_LIBTOOL
|
||||||
|
AC_HEADER_STDC
|
||||||
|
|
||||||
|
AC_CHECK_LIB(m, main)
|
||||||
|
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS(stdarg.h inttypes.h dirent.h)
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(unsigned long)
|
||||||
|
|
||||||
|
AC_FUNC_SETVBUF_REVERSED
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
AC_CHECK_FUNCS(opendir readdir closedir strerror vsnprintf)
|
||||||
|
|
||||||
|
AC_CHECK_PROGS(LAMIP, lamip,
|
||||||
|
AC_MSG_ERROR(*** lamip not found))
|
||||||
|
|
||||||
|
CFLAGS="$cflags_save -Wall `lamip --cflags`"
|
||||||
|
CPPFLAGS="$CPPFLAGS $CFLAGS"
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
cflags_save="$CFLAGS"
|
||||||
|
|
||||||
|
AC_CHECK_HEADER(lamip.h,,
|
||||||
|
AC_MSG_ERROR(*** LAMIP headers not found check your CFLAGS))
|
||||||
|
|
||||||
|
CFLAGS="$cflags_save -I. -I.. -Ishorten/include"
|
||||||
|
cflags_save="$CFLAGS"
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
[ --enable-debug (for developers only... and people with probs!) ],
|
||||||
|
[enable_debug=$enableval],
|
||||||
|
[enable_debug="no"])
|
||||||
|
|
||||||
|
if test "x$enable_debug" = xyes; then
|
||||||
|
CPPFLAGS="$CPPFLAGS -DDEBUG"
|
||||||
|
CFLAGS="$CFLAGS -g"
|
||||||
|
AC_MSG_RESULT([*** Debugging is enabled... ])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_OUTPUT([Makefile shorten/Makefile shorten/util/Makefile shorten/src/Makefile src/Makefile])
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "*** LAMIP inputSHORTEN (Shorten Codec) plugin succefully configured ***"
|
||||||
|
echo ""
|
||||||
|
echo "This plugin allows you to play *.shn files..."
|
||||||
|
echo ""
|
||||||
|
echo "install-dir : `lamip --plugin-dir`"
|
||||||
|
echo ""
|
||||||
|
echo "CFLAGS : $CFLAGS"
|
||||||
|
echo "LDFLAGS : $LDFLAGS"
|
||||||
|
echo "CPPFLAGS : $CPPFLAGS"
|
||||||
|
echo ""
|
||||||
|
if test "x$enable_debug" = xyes; then
|
||||||
|
echo "- debugging messages are enabled!"
|
||||||
|
echo ""
|
||||||
|
fi
|
1
Libraries/Shorten/Files/shorten/Makefile.am
Normal file
1
Libraries/Shorten/Files/shorten/Makefile.am
Normal file
|
@ -0,0 +1 @@
|
||||||
|
SUBDIRS = util src
|
20
Libraries/Shorten/Files/shorten/doc/LICENSE.shorten
Normal file
20
Libraries/Shorten/Files/shorten/doc/LICENSE.shorten
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
SHORTEN SOFTWARE LICENSE
|
||||||
|
|
||||||
|
This software is being provided to you, the LICENSEE, by Tony Robinson
|
||||||
|
and SoftSound under the following license. By obtaining, using and/or
|
||||||
|
copying this software, you agree that you have read, understood, and
|
||||||
|
will comply with these terms and conditions:
|
||||||
|
|
||||||
|
This software may not be sold or incorporated into any product which is
|
||||||
|
sold without prior permission from SoftSound. When no charge is made,
|
||||||
|
this software may be copied and distributed freely.
|
||||||
|
|
||||||
|
Permission is granted to use this software for decoding and
|
||||||
|
non-commercial encoding (e.g. private or research use). Please email
|
||||||
|
shorten@softsound.com for commercial encoding terms.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software carries no warranty, expressed or implied. The user
|
||||||
|
assumes all risks, known or unknown, direct or indirect, which involve
|
||||||
|
this software in any way.
|
1
Libraries/Shorten/Files/shorten/doc/xmms-shn/AUTHORS
Normal file
1
Libraries/Shorten/Files/shorten/doc/xmms-shn/AUTHORS
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Jason Jordan <shnutils@freeshell.org>
|
39
Libraries/Shorten/Files/shorten/doc/xmms-shn/CREDITS
Normal file
39
Libraries/Shorten/Files/shorten/doc/xmms-shn/CREDITS
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
Thanks goes to the XMMS development team, as version 0.x through 1.x of this
|
||||||
|
plugin were originally based on the Input/wav/wav.[ch] files from the XMMS
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
Thanks also goes to Caleb Epstein for testing and reporting bugs, and for
|
||||||
|
providing .deb and .rpm packages.
|
||||||
|
|
||||||
|
Wayne Stielau provided specs and code that became the basis of the 2.x version
|
||||||
|
of this plugin. Without his help, this version would have taken much longer to
|
||||||
|
write.
|
||||||
|
|
||||||
|
Thanks goes to scottv for reporting a crash-inducing bug, as well as providing
|
||||||
|
me a way to download the file that caused it for analysis.
|
||||||
|
|
||||||
|
Thanks goes to Daniel Robbins for reporting the truncated-scope bug.
|
||||||
|
|
||||||
|
Thanks goes to Paul Mather for reporting the m:ss.ff rounding bug in shntool
|
||||||
|
(which also affected xmms-shn), as well as providing a detailed analysis of the
|
||||||
|
problem which expedited its fix.
|
||||||
|
|
||||||
|
Thanks goes to Ari Pollak for reporting a crash that led to the discovery of a
|
||||||
|
race condition in the .shn unloading code.
|
||||||
|
|
||||||
|
Thanks to Alex Prestin for sending a byte-swap patch that fixed a problem where
|
||||||
|
all files would play back as static on his Ultra 10 and Ultra 30, as well as
|
||||||
|
providing a patch to load text files in the file information box, which became
|
||||||
|
the basis of the current implementation.
|
||||||
|
|
||||||
|
Thanks to Rhett Monteg Hollander for reporting a bug that prevented xmms-shn
|
||||||
|
from playing files encoded with alternate options, e.g. "-b1280 -p16 -m4".
|
||||||
|
|
||||||
|
Thanks to Peter Kunath for sending a one-line patch to fix a bug in shorten that
|
||||||
|
caused incorrect seek tables to be generated under certain conditions, as well
|
||||||
|
as for providing a way for xmms-shn to automatically detect this bug so that it
|
||||||
|
can disable seeking in affected files.
|
||||||
|
|
||||||
|
Finally, thanks goes to SoftSound for creating a great waveform encoder,
|
||||||
|
shorten, and especially for providing the source code to it. Without the
|
||||||
|
source, there would be no seek-enabled versions of shorten, and no xmms-shn 2.x.
|
1
Libraries/Shorten/Files/shorten/doc/xmms-shn/NEWS
Normal file
1
Libraries/Shorten/Files/shorten/doc/xmms-shn/NEWS
Normal file
|
@ -0,0 +1 @@
|
||||||
|
No news is good news.
|
346
Libraries/Shorten/Files/shorten/doc/xmms-shn/README
Normal file
346
Libraries/Shorten/Files/shorten/doc/xmms-shn/README
Normal file
|
@ -0,0 +1,346 @@
|
||||||
|
xmms-shn version 2.4.x
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
xmms-shn provides playback support for shorten (.shn) files in XMMS. Real-time
|
||||||
|
seeking support is provided for .shn files that have accompanying seek tables
|
||||||
|
generated by shorten 3.x. Otherwise, seeking is not supported.
|
||||||
|
|
||||||
|
See the "Shorten 3.x overview" section below for more information about this new
|
||||||
|
seek-enabled version of shorten.
|
||||||
|
|
||||||
|
|
||||||
|
------------
|
||||||
|
Availability
|
||||||
|
------------
|
||||||
|
|
||||||
|
The latest version of this plugin can always be found at the sites below:
|
||||||
|
|
||||||
|
http://www.etree.org/shnutils/
|
||||||
|
http://shnutils.freeshell.org/
|
||||||
|
|
||||||
|
Please see the ChangeLog file for changes to this plugin since its creation.
|
||||||
|
|
||||||
|
|
||||||
|
------------
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
As of version 2.0, xmms-shn no longer depends on an external shorten executable
|
||||||
|
to work, since the core shorten algorithm has been incorporated directly into
|
||||||
|
xmms-shn.
|
||||||
|
|
||||||
|
You should have XMMS 1.0.0 or newer, and GTK & GLIB 1.2.2 or newer. The
|
||||||
|
configure script will usually find these if you installed them from source.
|
||||||
|
However, if you installed any of the above via .rpm's, then you may need to tell
|
||||||
|
the configure script where to find them. To see what options are available,
|
||||||
|
type:
|
||||||
|
|
||||||
|
% ./configure --help
|
||||||
|
|
||||||
|
The applicable options are the following:
|
||||||
|
|
||||||
|
--with-xmms-prefix=PFX Prefix where XMMS is installed (optional)
|
||||||
|
--with-xmms-exec-prefix=PFX Exec prefix where XMMS is installed (optional)
|
||||||
|
--with-glib-prefix=PFX Prefix where GLIB is installed (optional)
|
||||||
|
--with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)
|
||||||
|
--disable-glibtest Do not try to compile and run a test GLIB program
|
||||||
|
--with-gtk-prefix=PFX Prefix where GTK is installed (optional)
|
||||||
|
--with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)
|
||||||
|
--disable-gtktest Do not try to compile and run a test GTK program
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
Building and installing this plugin
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
For instructions on how to build and install this plugin, please consult the
|
||||||
|
INSTALL file. It is usually as simple as the following:
|
||||||
|
|
||||||
|
% ./configure
|
||||||
|
% make
|
||||||
|
% su -c "make install"
|
||||||
|
Password: (give your root password here)
|
||||||
|
%
|
||||||
|
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
Configuration options
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This section details the options that can be found in the plugin's configuration
|
||||||
|
window in XMMS, under Preferences -> Audio I/O Plugins -> SHN Player 2.4.x ->
|
||||||
|
Configure.
|
||||||
|
|
||||||
|
|
||||||
|
Error Display tab:
|
||||||
|
==================
|
||||||
|
|
||||||
|
Error display options:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
This option determines where any error messages go - to a popup window,
|
||||||
|
to standard error, or to the bit bucket. Pretty self-explanatory.
|
||||||
|
|
||||||
|
|
||||||
|
Seek Tables tab:
|
||||||
|
================
|
||||||
|
|
||||||
|
Alternate seek table file locations:
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
These options allow you to specify alternate directores to search for .skt
|
||||||
|
(seek table) files. These directories will be searched after all other attempts
|
||||||
|
to locate a seek table for a given file have failed.
|
||||||
|
|
||||||
|
The "Relative seek table path" option allows you to specify a subdirectory
|
||||||
|
relative to the base directory of a given file, where seek tables may reside.
|
||||||
|
This is useful if you create seek table files for a group of .shn files, and
|
||||||
|
store them in a commonly-named subdirectory of that group.
|
||||||
|
|
||||||
|
The "Absolute seek table path" option allows you to specify an absolute directory
|
||||||
|
where seek tables may reside. This is useful if you create seek table files for
|
||||||
|
multiple groups of .shn files and store them in the same directory.
|
||||||
|
|
||||||
|
When searching for seek tables belonging to a file (e.g. '/mnt/shn/filename.shn'),
|
||||||
|
xmms-shn will do the following, in this order, until it either finds a seek table
|
||||||
|
or runs out of places to check for one:
|
||||||
|
|
||||||
|
1. look for a seek table appended to '/mnt/shn/filename.shn' (whether at the end,
|
||||||
|
or hidden behind an ID3v1 tag)
|
||||||
|
|
||||||
|
2. look for a seek table in '/mnt/shn/filename.skt'
|
||||||
|
|
||||||
|
3. look for a seek table in '/mnt/shn/relative_dir/filename.skt', where
|
||||||
|
'relative_dir' is the directory specified in the "Relative seek table path"
|
||||||
|
option
|
||||||
|
|
||||||
|
4. look for a seek table in '/absolute_dir/filename.skt', where 'absolute_dir'
|
||||||
|
is the directory specified in the "Absolute seek table path" option
|
||||||
|
|
||||||
|
|
||||||
|
Miscellaneous tab:
|
||||||
|
==================
|
||||||
|
|
||||||
|
Miscellaneous options:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The "Swap audio bytes on output" option is useful in situations where every file
|
||||||
|
you play back is static. This is known to help on the following platforms:
|
||||||
|
|
||||||
|
+ Sun Ultra 10 and Ultra 30 both running Solaris 8
|
||||||
|
+ SGI Octane/Irix 6.5
|
||||||
|
|
||||||
|
|
||||||
|
The "Display debug info to stderr" option specifies whether to display debugging
|
||||||
|
messages to stderr. This is potentially useful for remote debugging, and also
|
||||||
|
just to see what's going on. Debug lines are always shown with a prefix of
|
||||||
|
"xmms-shn [debug]:".
|
||||||
|
|
||||||
|
Note that if "Display debug info to stderr" is enabled, and the error display
|
||||||
|
option is set to /dev/null, then all non-debug messages that normally would be
|
||||||
|
suppressed are displayed to stderr with a prefix of "xmms-shn [error]:".
|
||||||
|
|
||||||
|
The "Load text files in file information box" option specifies whether text files
|
||||||
|
found in the same or parent directory as the given file should be loaded into the
|
||||||
|
file information box. Each file found will be loaded in a separate tab. The tabs
|
||||||
|
will be labeled "Text file n", where n starts at 1 and increases with each new
|
||||||
|
text file.
|
||||||
|
|
||||||
|
The "Text file extensions" option lets you specify a comma-separated list of case-
|
||||||
|
sensitive file extensions that xmms-shn will recognize as text files. The default
|
||||||
|
list is "txt,nfo". This option is only useful if "Load text files in file
|
||||||
|
information box" is enabled.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
Text file support is useful for quickly determining information about the given
|
||||||
|
file and/or the show it belongs to, assuming such information is contained within
|
||||||
|
the text files.
|
||||||
|
|
||||||
|
Text file location assumes some combination of the following two directory
|
||||||
|
structures: all text files and .shn files in the same directory, or text files
|
||||||
|
in a directory with all .shn files in subdirectories one level deep. This
|
||||||
|
pretty much covers all directory structures seen on live music servers and file-
|
||||||
|
sharing programs.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
File information box
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
This section describes the output shown in the file information window, which
|
||||||
|
can be viewed by choosing 'File Inf.' from the 'Misc. Opt' button in the
|
||||||
|
playlist editor, or selecting 'View File Info' from XMMS's main popup menu.
|
||||||
|
|
||||||
|
Properties tab:
|
||||||
|
===============
|
||||||
|
|
||||||
|
Filename: Shows the full path to the .shn file being examined.
|
||||||
|
|
||||||
|
Length: Shows the length of the WAVE data in the file, in m:ss.nnn format.
|
||||||
|
If the WAVE data is CD-quality (see below for definition), then the length is
|
||||||
|
shown in m:ss.ff format, where ff is a number from 00 to 74 that best
|
||||||
|
approximates the number of frames (2352-byte blocks) remaining after m:ss.
|
||||||
|
|
||||||
|
Note on rounding: If the WAVE data is CD-quality, then its length is
|
||||||
|
rounded to the nearest frame. Otherwise, it is rounded
|
||||||
|
to the nearest millisecond.
|
||||||
|
|
||||||
|
Seekable: Shows whether a seek table was found for the given file.
|
||||||
|
|
||||||
|
Seek table revision: Shows the revision number of the seek tables, if
|
||||||
|
present. Note that it is possible for this field to contain a numeric value,
|
||||||
|
even when the file is not seekable - for example, xmms-shn might detect that
|
||||||
|
certain seek tables are buggy, and disable seeking in those files.
|
||||||
|
|
||||||
|
Compression ratio: Shows the compression ratio for the given file. This is
|
||||||
|
simply the file's actual size divided by its total size, as calculated from
|
||||||
|
the chunk size contained in the WAVE header. Note that if the given file is
|
||||||
|
truncated (or has junk appended to it), then the compression ratio will be
|
||||||
|
skewed accordingly.
|
||||||
|
|
||||||
|
CD-quality properties:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
CD-quality: Shows whether the given file is CD-quality. A file is considered
|
||||||
|
to be CD-quality if its header indicates 2 channels, 16 bits/sample, 44100
|
||||||
|
samples/second, and 176400 average bytes/second.
|
||||||
|
|
||||||
|
Cut on a sector boundary: If the given file is CD-quality, then this shows
|
||||||
|
whether the length of its WAVE data is a multiple of 2352 bytes (1/75 of a
|
||||||
|
second). Otherwise, "n/a" is displayed.
|
||||||
|
|
||||||
|
Sector misalignemt: If the file is CD-quality, then the sector misalignment
|
||||||
|
is simply the remainder when the data size is divided by 2352; i.e. it is the
|
||||||
|
number of bytes by which the audio data exceeds the previous sector boundary.
|
||||||
|
|
||||||
|
Long enough to be burned: If the given file is CD-quality, then this shows
|
||||||
|
whether the length of its WAVE data is long enough to be burned (705600 bytes,
|
||||||
|
or 3 seconds in length). Otherwise, "n/a" is displayed.
|
||||||
|
|
||||||
|
WAVE properties:
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Non-canonical header: Shows whether the WAVE header is canonical. A header
|
||||||
|
is considered canonical if it is 44 bytes long (this is the smallest possible
|
||||||
|
size that a WAVE header can be).
|
||||||
|
|
||||||
|
Extra RIFF chunks: Shows whether there are any extra RIFF chunks following
|
||||||
|
the data chunk in the WAVE stream.
|
||||||
|
|
||||||
|
Possible problems:
|
||||||
|
------------------
|
||||||
|
|
||||||
|
File contains ID3v2 tag: Shows whether the file contains an ID3v2 tag, and
|
||||||
|
if so, how many bytes it occupies. This is not a problem for xmms-shn (it
|
||||||
|
was able to read the file after all), but could pose a problem for programs
|
||||||
|
that are not able to process files with ID3v2 tags.
|
||||||
|
|
||||||
|
|
||||||
|
Details tab:
|
||||||
|
============
|
||||||
|
|
||||||
|
This tab primarily shows the raw information taken from the WAVE header of the
|
||||||
|
given file. Each entry is self-explanatory.
|
||||||
|
|
||||||
|
|
||||||
|
Text file n tab(s):
|
||||||
|
===================
|
||||||
|
|
||||||
|
These tabs, if any, show the contents of all text files found in the same
|
||||||
|
directory or parent directory as the given file. The associated file name for
|
||||||
|
each tab is contained in the frame surrounding the text, and the full path to
|
||||||
|
the file being displayed is shown just above the text. You can control which
|
||||||
|
files are considered to be text files with the "Text file extensions" option in
|
||||||
|
the configuration window. Make sure to select the "Load text files in file
|
||||||
|
information box" option if you want to see these tabs.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
Shorten 3.x overview
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Wayne Stielau has extended shorten 2.3 to support the creation of seek tables.
|
||||||
|
Seek tables are simply descriptions of the internal state of the shorten
|
||||||
|
algorithm at specific points in the decompression. This allows a modified
|
||||||
|
shorten decoder to restore the decoder state of the shorten algorithm for a
|
||||||
|
point at (or very close to) the desired seek point. You can get the latest
|
||||||
|
version at any of the URLs below:
|
||||||
|
|
||||||
|
http://www.etree.org/shnutils/shorten/
|
||||||
|
http://shnutils.freeshell.org/shorten/
|
||||||
|
|
||||||
|
Seek tables may be appended to the .shn itself, or stored in a separate file
|
||||||
|
(usually with a suffix of '.skt'). xmms-shn supports both of these options.
|
||||||
|
|
||||||
|
The current implementation creates a seek table entry once every 25600 samples.
|
||||||
|
For 'CD-quality' WAVE data (44100 samples/sec), this provides a granularity of 1
|
||||||
|
seek table entry per 25600/44100 ~= 0.58 seconds, more than what is needed by
|
||||||
|
either XMMS or WinAmp.
|
||||||
|
|
||||||
|
At 80 bytes per seek table entry, you can expect the seek table to add about
|
||||||
|
0.1% to the size of the existing shortened file, for 'CD-quality' WAVE data.
|
||||||
|
So the seek table generated for 1 GB of already-shortened 'CD-quality' WAVE data
|
||||||
|
will fit on a floppy! Quite a deal, if you ask me. :-)
|
||||||
|
|
||||||
|
Best of all, shorten 3.x is fully backward compatible with version 2.3, meaning
|
||||||
|
that any files created by shorten 3.x can be processed by version 2.3 with no
|
||||||
|
problems.
|
||||||
|
|
||||||
|
The command line options for dealing with seek tables in shorten 3.x are:
|
||||||
|
|
||||||
|
-e erase seek table appended to input file *
|
||||||
|
-i inquire as to whether a seek table is appended to input file *
|
||||||
|
-k append seek table information to existing shorten file
|
||||||
|
-s generate seek table information in separate file [input file].skt
|
||||||
|
-S[name] generate seek table information in separate file given by [name]
|
||||||
|
-v 3 format version number (2: no seek info; 3: default) *
|
||||||
|
|
||||||
|
* only available in versions 3.2 and up
|
||||||
|
|
||||||
|
By default, any file shortened with version 3.x will automatically have seek
|
||||||
|
tables appended to it. In later versions (3.2 and up), you can disable this
|
||||||
|
with the -v2 switch.
|
||||||
|
|
||||||
|
** NOTE ON SEEKING IN FILES ENCODED WITH NON-DEFAULT OPTIONS **
|
||||||
|
|
||||||
|
Seek tables generated by shorten for files that were encoded with non-default
|
||||||
|
options do not seem to work correctly in most cases. Normal playback works
|
||||||
|
fine, but any attempt to seek within such a file may cause the audio to become
|
||||||
|
garbled. This appears to be due to an unforseen limitation in the design of
|
||||||
|
seek table generation in shorten - for example, as stated above, seek tables
|
||||||
|
were intended to be generated once every 25600 samples, but this is not true if
|
||||||
|
an alternate block size is given with the -b option. Encoding options that seem
|
||||||
|
to be able to cause this problem when set to non-default values are the -b, -m
|
||||||
|
and -p options. Since there is no reliable way to identify such files, the best
|
||||||
|
xmms-shn can do is attempt to seek based on the values in the seek tables. If
|
||||||
|
the sound becomes garbled, then you have likely run across one of these files,
|
||||||
|
and are out of luck.
|
||||||
|
|
||||||
|
|
||||||
|
----------
|
||||||
|
Known bugs
|
||||||
|
----------
|
||||||
|
|
||||||
|
1. Not really a bug in xmms-shn, but under certain conditions, seeking may not
|
||||||
|
work correctly. The primary symptom of this is garbled audio after a seek is
|
||||||
|
performed. See the section above titled "NOTE ON SEEKING IN FILES ENCODED
|
||||||
|
WITH NON-DEFAULT OPTIONS" for more information.
|
||||||
|
|
||||||
|
|
||||||
|
I test this plugin aggressively until I can no longer make it crash. That does
|
||||||
|
not mean that there are no bugs. If you can crash it, I want to hear about it -
|
||||||
|
please report it to me at the address below. The xmms-shn webpage (see the
|
||||||
|
Availability section above) will always contain an up-to-date list of reported
|
||||||
|
bugs, so be sure to check that page before you send me a bug report.
|
||||||
|
|
||||||
|
Also, feel free to send me any questions, comments, feature requests, patches...
|
||||||
|
I always enjoy getting feedback.
|
||||||
|
|
||||||
|
Enjoy!
|
||||||
|
|
||||||
|
Jason Jordan <shnutils@freeshell.org>
|
33
Libraries/Shorten/Files/shorten/include/bitshift.h
Normal file
33
Libraries/Shorten/Files/shorten/include/bitshift.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
char ulaw_maxshift[256] = {12,8,7,9,7,8,7,10,7,8,7,9,7,8,7,11,6,7,6,8,6,7,6,9,6,7,6,8,6,7,6,10,5,6,5,7,5,6,5,8,5,6,5,7,5,6,5,9,5,4,6,4,5,4,7,4,5,4,6,4,5,4,8,4,3,5,3,4,3,6,3,4,3,5,3,4,3,7,3,4,2,3,2,5,2,3,2,4,2,3,2,6,2,3,2,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,0,7,8,7,9,7,8,7,10,7,8,7,9,7,8,7,11,6,7,6,8,6,7,6,9,6,7,6,8,6,7,6,10,5,6,5,7,5,6,5,8,5,6,5,7,5,6,5,9,5,4,6,4,5,4,7,4,5,4,6,4,5,4,8,4,3,5,3,4,3,6,3,4,3,5,3,4,3,7,3,4,2,3,2,5,2,3,2,4,2,3,2,6,2,3,2,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,12};
|
||||||
|
|
||||||
|
schar ulaw_inward[13][256] = {
|
||||||
|
{-127,-126,-125,-124,-123,-122,-121,-120,-119,-118,-117,-116,-115,-114,-113,-112,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-101,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,-128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0},
|
||||||
|
{-119,-118,-117,-116,-115,-114,-113,-112,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-101,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-128,-7,-127,-6,-126,-5,-125,-4,-124,-3,-123,-2,-122,-1,-121,-120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,127,7,126,6,125,5,124,4,123,3,122,2,121,1,120,0},
|
||||||
|
{-107,-106,-105,-104,-103,-102,-101,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-128,-11,-127,-10,-126,-9,-125,-8,-124,-7,-123,-6,-122,-5,-121,-4,-120,-119,-118,-3,-117,-116,-115,-2,-114,-113,-112,-1,-111,-110,-109,-108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,127,11,126,10,125,9,124,8,123,7,122,6,121,5,120,4,119,118,117,3,116,115,114,2,113,112,111,1,110,109,108,0},
|
||||||
|
{-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-128,-13,-127,-12,-126,-11,-125,-10,-124,-9,-123,-8,-122,-7,-121,-6,-120,-119,-118,-5,-117,-116,-115,-4,-114,-113,-112,-3,-111,-110,-109,-2,-108,-107,-106,-105,-104,-103,-102,-1,-101,-100,-99,-98,-97,-96,-95,-94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,127,13,126,12,125,11,124,10,123,9,122,8,121,7,120,6,119,118,117,5,116,115,114,4,113,112,111,3,110,109,108,2,107,106,105,104,103,102,101,1,100,99,98,97,96,95,94,0},
|
||||||
|
{-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-128,-14,-127,-13,-126,-12,-125,-11,-124,-10,-123,-9,-122,-8,-121,-7,-120,-119,-118,-6,-117,-116,-115,-5,-114,-113,-112,-4,-111,-110,-109,-3,-108,-107,-106,-105,-104,-103,-102,-2,-101,-100,-99,-98,-97,-96,-95,-1,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,127,14,126,13,125,12,124,11,123,10,122,9,121,8,120,7,119,118,117,6,116,115,114,5,113,112,111,4,110,109,108,3,107,106,105,104,103,102,101,2,100,99,98,97,96,95,94,1,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,0},
|
||||||
|
{-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-128,-14,-127,-13,-126,-12,-125,-11,-124,-10,-123,-9,-122,-8,-121,-120,-7,-119,-118,-117,-6,-116,-115,-114,-5,-113,-112,-111,-4,-110,-109,-108,-107,-106,-3,-105,-104,-103,-102,-101,-100,-99,-2,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-1,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,127,14,126,13,125,12,124,11,123,10,122,9,121,8,120,119,7,118,117,116,6,115,114,113,5,112,111,110,4,109,108,107,106,105,3,104,103,102,101,100,99,98,2,97,96,95,94,93,92,91,90,89,88,87,1,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,0},
|
||||||
|
{-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-128,-15,-127,-14,-126,-13,-125,-12,-124,-11,-123,-10,-122,-9,-121,-8,-120,-119,-7,-118,-117,-116,-6,-115,-114,-113,-5,-112,-111,-110,-4,-109,-108,-107,-106,-105,-104,-3,-103,-102,-101,-100,-99,-98,-97,-2,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-1,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,127,15,126,14,125,13,124,12,123,11,122,10,121,9,120,8,119,118,7,117,116,115,6,114,113,112,5,111,110,109,4,108,107,106,105,104,103,3,102,101,100,99,98,97,96,2,95,94,93,92,91,90,89,88,87,86,85,84,83,1,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,0},
|
||||||
|
{-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-128,-15,-127,-14,-126,-13,-125,-12,-124,-11,-123,-10,-122,-9,-121,-8,-120,-119,-118,-7,-117,-116,-115,-6,-114,-113,-112,-5,-111,-110,-109,-4,-108,-107,-106,-105,-104,-103,-3,-102,-101,-100,-99,-98,-97,-96,-2,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-1,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,127,15,126,14,125,13,124,12,123,11,122,10,121,9,120,8,119,118,117,7,116,115,114,6,113,112,111,5,110,109,108,4,107,106,105,104,103,102,3,101,100,99,98,97,96,95,2,94,93,92,91,90,89,88,87,86,85,84,83,82,81,1,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,0},
|
||||||
|
{-16,-15,-128,-14,-127,-13,-126,-12,-125,-11,-124,-10,-123,-9,-122,-8,-121,-120,-119,-7,-118,-117,-116,-6,-115,-114,-113,-5,-112,-111,-110,-4,-109,-108,-107,-106,-105,-104,-103,-3,-102,-101,-100,-99,-98,-97,-96,-2,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-1,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,127,15,126,14,125,13,124,12,123,11,122,10,121,9,120,8,119,118,117,7,116,115,114,6,113,112,111,5,110,109,108,4,107,106,105,104,103,102,101,3,100,99,98,97,96,95,94,2,93,92,91,90,89,88,87,86,85,84,83,82,81,80,1,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,0},
|
||||||
|
{-8,-128,-127,-7,-126,-125,-124,-6,-123,-122,-121,-5,-120,-119,-118,-4,-117,-116,-115,-114,-113,-112,-111,-3,-110,-109,-108,-107,-106,-105,-104,-2,-103,-102,-101,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-1,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,127,126,125,7,124,123,122,6,121,120,119,5,118,117,116,4,115,114,113,112,111,110,109,3,108,107,106,105,104,103,102,2,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,1,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,0},
|
||||||
|
{-4,-128,-127,-126,-125,-124,-123,-3,-122,-121,-120,-119,-118,-117,-116,-2,-115,-114,-113,-112,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-101,-1,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,127,126,125,124,123,122,121,3,120,119,118,117,116,115,114,2,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,1,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,0},
|
||||||
|
{-2,-128,-127,-126,-125,-124,-123,-122,-121,-120,-119,-118,-117,-116,-115,-1,-114,-113,-112,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-101,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,1,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,0},
|
||||||
|
{-1,-128,-127,-126,-125,-124,-123,-122,-121,-120,-119,-118,-117,-116,-115,-114,-113,-112,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-101,-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
uchar ulaw_outward[13][256] = {
|
||||||
|
{127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,255,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128},
|
||||||
|
{112,114,116,118,120,122,124,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,113,115,117,119,121,123,125,255,253,251,249,247,245,243,241,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,252,250,248,246,244,242,240},
|
||||||
|
{96,98,100,102,104,106,108,110,112,113,114,116,117,118,120,121,122,124,125,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,97,99,101,103,105,107,109,111,115,119,123,255,251,247,243,239,237,235,233,231,229,227,225,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,253,252,250,249,248,246,245,244,242,241,240,238,236,234,232,230,228,226,224},
|
||||||
|
{80,82,84,86,88,90,92,94,96,97,98,100,101,102,104,105,106,108,109,110,112,113,114,115,116,117,118,120,121,122,123,124,125,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,81,83,85,87,89,91,93,95,99,103,107,111,119,255,247,239,235,231,227,223,221,219,217,215,213,211,209,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,253,252,251,250,249,248,246,245,244,243,242,241,240,238,237,236,234,233,232,230,229,228,226,225,224,222,220,218,216,214,212,210,208},
|
||||||
|
{64,66,68,70,72,74,76,78,80,81,82,84,85,86,88,89,90,92,93,94,96,97,98,99,100,101,102,104,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,65,67,69,71,73,75,77,79,83,87,91,95,103,111,255,239,231,223,219,215,211,207,205,203,201,199,197,195,193,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,238,237,236,235,234,233,232,230,229,228,227,226,225,224,222,221,220,218,217,216,214,213,212,210,209,208,206,204,202,200,198,196,194,192},
|
||||||
|
{49,51,53,55,57,59,61,63,64,66,67,68,70,71,72,74,75,76,78,79,80,81,82,84,85,86,87,88,89,90,92,93,94,95,96,97,98,99,100,101,102,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,52,54,56,58,60,62,65,69,73,77,83,91,103,255,231,219,211,205,201,197,193,190,188,186,184,182,180,178,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,230,229,228,227,226,225,224,223,222,221,220,218,217,216,215,214,213,212,210,209,208,207,206,204,203,202,200,199,198,196,195,194,192,191,189,187,185,183,181,179,177},
|
||||||
|
{32,34,36,38,40,42,44,46,48,49,51,52,53,55,56,57,59,60,61,63,64,65,66,67,68,70,71,72,73,74,75,76,78,79,80,81,82,83,84,85,86,87,88,89,90,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,35,37,39,41,43,45,47,50,54,58,62,69,77,91,255,219,205,197,190,186,182,178,175,173,171,169,167,165,163,161,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,218,217,216,215,214,213,212,211,210,209,208,207,206,204,203,202,201,200,199,198,196,195,194,193,192,191,189,188,187,185,184,183,181,180,179,177,176,174,172,170,168,166,164,162,160},
|
||||||
|
{16,18,20,22,24,26,28,30,32,33,34,36,37,38,40,41,42,44,45,46,48,49,50,51,52,53,55,56,57,58,59,60,61,63,64,65,66,67,68,69,70,71,72,73,74,75,76,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,19,21,23,25,27,29,31,35,39,43,47,54,62,77,255,205,190,182,175,171,167,163,159,157,155,153,151,149,147,145,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,204,203,202,201,200,199,198,197,196,195,194,193,192,191,189,188,187,186,185,184,183,181,180,179,178,177,176,174,173,172,170,169,168,166,165,164,162,161,160,158,156,154,152,150,148,146,144},
|
||||||
|
{2,4,6,8,10,12,14,16,17,18,20,21,22,24,25,26,28,29,30,32,33,34,35,36,37,38,40,41,42,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,1,3,5,7,9,11,13,15,19,23,27,31,39,47,62,255,190,175,167,159,155,151,147,143,141,139,137,135,133,131,129,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,189,188,187,186,185,184,183,182,181,180,179,178,177,176,174,173,172,171,170,169,168,166,165,164,163,162,161,160,158,157,156,154,153,152,150,149,148,146,145,144,142,140,138,136,134,132,130,128},
|
||||||
|
{1,2,4,5,6,8,9,10,12,13,14,16,17,18,19,20,21,22,24,25,26,27,28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,3,7,11,15,23,31,47,255,175,159,151,143,139,135,131,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,158,157,156,155,154,153,152,150,149,148,147,146,145,144,142,141,140,138,137,136,134,133,132,130,129,128},
|
||||||
|
{1,2,3,4,5,6,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,7,15,31,255,159,143,135,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,142,141,140,139,138,137,136,134,133,132,131,130,129,128},
|
||||||
|
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,15,255,143,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128},
|
||||||
|
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,0,255,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128}
|
||||||
|
};
|
96
Libraries/Shorten/Files/shorten/include/config.h
Normal file
96
Libraries/Shorten/Files/shorten/include/config.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/* shorten/include/config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `closedir' function. */
|
||||||
|
#define HAVE_CLOSEDIR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dirent.h> header file. */
|
||||||
|
#define HAVE_DIRENT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#define HAVE_DLFCN_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#define HAVE_INTTYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `m' library (-lm). */
|
||||||
|
#define HAVE_LIBM 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#define HAVE_MEMORY_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `opendir' function. */
|
||||||
|
#define HAVE_OPENDIR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `readdir' function. */
|
||||||
|
#define HAVE_READDIR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||||
|
#define HAVE_STDARG_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#define HAVE_STDINT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#define HAVE_STDLIB_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#define HAVE_STRERROR 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#define HAVE_STRINGS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#define HAVE_STRING_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vsnprintf' function. */
|
||||||
|
#define HAVE_VSNPRINTF 1
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#define PACKAGE "libshorten"
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define to 1 if the C compiler supports function prototypes. */
|
||||||
|
#undef PROTOTYPES
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||||
|
#undef RETSIGTYPE
|
||||||
|
|
||||||
|
/* Define to 1 if the `setvbuf' function takes the buffering type as its
|
||||||
|
second argument and the buffer pointer as the third, as on System V before
|
||||||
|
release 3. */
|
||||||
|
#undef SETVBUF_REVERSED
|
||||||
|
|
||||||
|
/* The size of a `unsigned long', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#define VERSION "unknown-cog"
|
||||||
|
|
||||||
|
/* Define like PROTOTYPES; this can be used by system headers. */
|
||||||
|
#undef __PROTOTYPES
|
96
Libraries/Shorten/Files/shorten/include/config.h.in
Normal file
96
Libraries/Shorten/Files/shorten/include/config.h.in
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/* shorten/include/config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `closedir' function. */
|
||||||
|
#undef HAVE_CLOSEDIR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dirent.h> header file. */
|
||||||
|
#undef HAVE_DIRENT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `m' library (-lm). */
|
||||||
|
#undef HAVE_LIBM
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `opendir' function. */
|
||||||
|
#undef HAVE_OPENDIR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `readdir' function. */
|
||||||
|
#undef HAVE_READDIR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||||
|
#undef HAVE_STDARG_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vsnprintf' function. */
|
||||||
|
#undef HAVE_VSNPRINTF
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#undef PACKAGE
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define to 1 if the C compiler supports function prototypes. */
|
||||||
|
#undef PROTOTYPES
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||||
|
#undef RETSIGTYPE
|
||||||
|
|
||||||
|
/* Define to 1 if the `setvbuf' function takes the buffering type as its
|
||||||
|
second argument and the buffer pointer as the third, as on System V before
|
||||||
|
release 3. */
|
||||||
|
#undef SETVBUF_REVERSED
|
||||||
|
|
||||||
|
/* The size of a `unsigned long', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#undef VERSION
|
||||||
|
|
||||||
|
/* Define like PROTOTYPES; this can be used by system headers. */
|
||||||
|
#undef __PROTOTYPES
|
45
Libraries/Shorten/Files/shorten/include/decode.h
Normal file
45
Libraries/Shorten/Files/shorten/include/decode.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef _DECODE_H
|
||||||
|
#define _DECODE_H
|
||||||
|
|
||||||
|
#include "shorten.h"
|
||||||
|
#include "shn.h"
|
||||||
|
|
||||||
|
#define NUM_DEFAULT_BUFFER_BLOCKS 512L
|
||||||
|
|
||||||
|
#ifndef _SHN_CONFIG
|
||||||
|
#define _SHN_CONFIG
|
||||||
|
|
||||||
|
/* First fill out a shn_config struct... */
|
||||||
|
typedef struct _shn_config
|
||||||
|
{
|
||||||
|
int error_output_method;
|
||||||
|
char *seek_tables_path;
|
||||||
|
char *relative_seek_tables_path;
|
||||||
|
int verbose;
|
||||||
|
int swap_bytes;
|
||||||
|
} shn_config;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ... then you can load a file, normally you have to use the functions in this order */
|
||||||
|
shn_file *shn_load(char *filename, shn_config config); /* Loads the file in filename and uses config... returns a shn_file context */
|
||||||
|
int shn_init_decoder(shn_file *this_shn); /* inits the decoder for this_shn necessary to do shn_read() */
|
||||||
|
|
||||||
|
/* shn_get_buffer_block_size() returns the minimal size that read_buffer should have *
|
||||||
|
* blocks should be around 512 *
|
||||||
|
* You have to allocate a buffer with the size returned by shn_get_buffer_block_size() yourself */
|
||||||
|
int shn_get_buffer_block_size(shn_file *this_shn, int blocks);
|
||||||
|
unsigned int shn_get_song_length(shn_file *this_shn); /* returns song length in milliseconds */
|
||||||
|
unsigned int shn_get_samplerate(shn_file *this_shn); /* returns the number of samples per second */
|
||||||
|
unsigned int shn_get_channels(shn_file *this_shn); /* returns the number of channels of the audio file */
|
||||||
|
unsigned int shn_get_bitspersample(shn_file *this_shn); /* returns the number of bits per sample */
|
||||||
|
|
||||||
|
/* Play with the shorten file */
|
||||||
|
int shn_read(shn_file *this_shn, uchar *read_buffer, int bytes_to_read); /* bytes_to_read should be the size returned by shn_get_buffer_block_size */
|
||||||
|
int shn_seekable(shn_file *this_shn); /* Returns 1 if file is seekables (has seek tables) otherwise 0 */
|
||||||
|
int shn_seek(shn_file *this_shn, unsigned int time); /* Seek to position "time" in seconds */
|
||||||
|
|
||||||
|
/* Unload everything */
|
||||||
|
int shn_cleanup_decoder(shn_file *this_shn); /* Frees some buffers */
|
||||||
|
void shn_unload(shn_file *this_shn); /* Unloads the file */
|
||||||
|
|
||||||
|
#endif
|
284
Libraries/Shorten/Files/shorten/include/shn.h
Normal file
284
Libraries/Shorten/Files/shorten/include/shn.h
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
/* xmms-shn - a shorten (.shn) plugin for XMMS
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SHN_H
|
||||||
|
#define _SHN_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRERROR
|
||||||
|
extern char *sys_errlist[];
|
||||||
|
#define strerror(x) sys_errlist[x]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_VSNPRINTF
|
||||||
|
#define shn_vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
|
||||||
|
#else
|
||||||
|
#define shn_vsnprintf(a,b,c,d) vsprintf(a,c,d)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define min(a,b) (((a)<(b))?(a):(b))
|
||||||
|
|
||||||
|
/* surely no headers will be this large. right? RIGHT? */
|
||||||
|
#define OUT_BUFFER_SIZE 16384
|
||||||
|
|
||||||
|
#define BUF_SIZE 4096
|
||||||
|
|
||||||
|
#define ERROR_OUTPUT_DEVNULL 0
|
||||||
|
#define ERROR_OUTPUT_STDERR 1
|
||||||
|
#define ERROR_OUTPUT_WINDOW 2
|
||||||
|
|
||||||
|
#define SEEK_SUFFIX "skt"
|
||||||
|
|
||||||
|
#define NO_SEEK_TABLE -1
|
||||||
|
|
||||||
|
#define SEEK_HEADER_SIGNATURE "SEEK"
|
||||||
|
#define SEEK_TRAILER_SIGNATURE "SHNAMPSK"
|
||||||
|
|
||||||
|
#define SEEK_HEADER_SIZE 12
|
||||||
|
#define SEEK_TRAILER_SIZE 12
|
||||||
|
#define SEEK_ENTRY_SIZE 80
|
||||||
|
#define SEEK_RESOLUTION 25600
|
||||||
|
|
||||||
|
#define WAVE_RIFF (0x46464952) /* 'RIFF' in little-endian */
|
||||||
|
#define WAVE_WAVE (0x45564157) /* 'WAVE' in little-endian */
|
||||||
|
#define WAVE_FMT (0x20746d66) /* ' fmt' in little-endian */
|
||||||
|
#define WAVE_DATA (0x61746164) /* 'data' in little-endian */
|
||||||
|
|
||||||
|
#define AIFF_FORM (0x4D524F46) /* 'FORM' in little-endian */
|
||||||
|
|
||||||
|
#define WAVE_FORMAT_UNKNOWN (0x0000)
|
||||||
|
#define WAVE_FORMAT_PCM (0x0001)
|
||||||
|
#define WAVE_FORMAT_ADPCM (0x0002)
|
||||||
|
#define WAVE_FORMAT_IEEE_FLOAT (0x0003)
|
||||||
|
#define WAVE_FORMAT_ALAW (0x0006)
|
||||||
|
#define WAVE_FORMAT_MULAW (0x0007)
|
||||||
|
#define WAVE_FORMAT_OKI_ADPCM (0x0010)
|
||||||
|
#define WAVE_FORMAT_IMA_ADPCM (0x0011)
|
||||||
|
#define WAVE_FORMAT_DIGISTD (0x0015)
|
||||||
|
#define WAVE_FORMAT_DIGIFIX (0x0016)
|
||||||
|
#define WAVE_FORMAT_DOLBY_AC2 (0x0030)
|
||||||
|
#define WAVE_FORMAT_GSM610 (0x0031)
|
||||||
|
#define WAVE_FORMAT_ROCKWELL_ADPCM (0x003b)
|
||||||
|
#define WAVE_FORMAT_ROCKWELL_DIGITALK (0x003c)
|
||||||
|
#define WAVE_FORMAT_G721_ADPCM (0x0040)
|
||||||
|
#define WAVE_FORMAT_G728_CELP (0x0041)
|
||||||
|
#define WAVE_FORMAT_MPEG (0x0050)
|
||||||
|
#define WAVE_FORMAT_MPEGLAYER3 (0x0055)
|
||||||
|
#define WAVE_FORMAT_G726_ADPCM (0x0064)
|
||||||
|
#define WAVE_FORMAT_G722_ADPCM (0x0065)
|
||||||
|
|
||||||
|
#define CD_BLOCK_SIZE (2352)
|
||||||
|
#define CD_BLOCKS_PER_SEC (75)
|
||||||
|
#define CD_MIN_BURNABLE_SIZE (705600)
|
||||||
|
#define CD_CHANNELS (2)
|
||||||
|
#define CD_SAMPLES_PER_SEC (44100)
|
||||||
|
#define CD_BITS_PER_SAMPLE (16)
|
||||||
|
#define CD_RATE (176400)
|
||||||
|
|
||||||
|
#define CANONICAL_HEADER_SIZE (44)
|
||||||
|
|
||||||
|
#define PROBLEM_NOT_CD_QUALITY (0x00000001)
|
||||||
|
#define PROBLEM_CD_BUT_BAD_BOUND (0x00000002)
|
||||||
|
#define PROBLEM_CD_BUT_TOO_SHORT (0x00000004)
|
||||||
|
#define PROBLEM_HEADER_NOT_CANONICAL (0x00000008)
|
||||||
|
#define PROBLEM_EXTRA_CHUNKS (0x00000010)
|
||||||
|
#define PROBLEM_HEADER_INCONSISTENT (0x00000020)
|
||||||
|
|
||||||
|
#define PROB_NOT_CD(f) ((f.problems) & (PROBLEM_NOT_CD_QUALITY))
|
||||||
|
#define PROB_BAD_BOUND(f) ((f.problems) & (PROBLEM_CD_BUT_BAD_BOUND))
|
||||||
|
#define PROB_TOO_SHORT(f) ((f.problems) & (PROBLEM_CD_BUT_TOO_SHORT))
|
||||||
|
#define PROB_HDR_NOT_CANONICAL(f) ((f.problems) & (PROBLEM_HEADER_NOT_CANONICAL))
|
||||||
|
#define PROB_EXTRA_CHUNKS(f) ((f.problems) & (PROBLEM_EXTRA_CHUNKS))
|
||||||
|
#define PROB_HDR_INCONSISTENT(f) ((f.problems) & (PROBLEM_HEADER_INCONSISTENT))
|
||||||
|
|
||||||
|
#ifndef _SHN_CONFIG
|
||||||
|
#define _SHN_CONFIG
|
||||||
|
typedef struct _shn_config
|
||||||
|
{
|
||||||
|
int error_output_method;
|
||||||
|
char *seek_tables_path;
|
||||||
|
char *relative_seek_tables_path;
|
||||||
|
int verbose;
|
||||||
|
int swap_bytes;
|
||||||
|
} shn_config;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _shn_decode_state
|
||||||
|
{
|
||||||
|
uchar *getbuf;
|
||||||
|
uchar *getbufp;
|
||||||
|
int nbitget;
|
||||||
|
int nbyteget;
|
||||||
|
ulong gbuffer;
|
||||||
|
schar *writebuf;
|
||||||
|
schar *writefub;
|
||||||
|
int nwritebuf;
|
||||||
|
} shn_decode_state;
|
||||||
|
|
||||||
|
typedef struct _shn_seek_header
|
||||||
|
{
|
||||||
|
uchar data[SEEK_HEADER_SIZE];
|
||||||
|
slong version;
|
||||||
|
ulong shnFileSize;
|
||||||
|
} shn_seek_header;
|
||||||
|
|
||||||
|
typedef struct _shn_seek_trailer
|
||||||
|
{
|
||||||
|
uchar data[SEEK_TRAILER_SIZE];
|
||||||
|
ulong seekTableSize;
|
||||||
|
} shn_seek_trailer;
|
||||||
|
|
||||||
|
typedef struct _shn_seek_entry
|
||||||
|
{
|
||||||
|
uchar data[SEEK_ENTRY_SIZE];
|
||||||
|
} shn_seek_entry;
|
||||||
|
|
||||||
|
/* old way, kept for reference.
|
||||||
|
(changed because some compilers apparently don't support #pragma pack(1))
|
||||||
|
|
||||||
|
typedef struct _shn_seek_header
|
||||||
|
{
|
||||||
|
char signature[4];
|
||||||
|
unsigned long version;
|
||||||
|
unsigned long shnFileSize;
|
||||||
|
} shn_seek_header;
|
||||||
|
|
||||||
|
typedef struct _shn_seek_trailer
|
||||||
|
{
|
||||||
|
unsigned long seekTableSize;
|
||||||
|
char signature[8];
|
||||||
|
} shn_seek_trailer;
|
||||||
|
|
||||||
|
typedef struct _shn_seek_entry
|
||||||
|
{
|
||||||
|
unsigned long shnSample;
|
||||||
|
unsigned long shnByteOffset;
|
||||||
|
unsigned long shnLastPosition;
|
||||||
|
unsigned short shnByteGet;
|
||||||
|
unsigned short shnBufferOffset;
|
||||||
|
unsigned short shnBitOffset;
|
||||||
|
unsigned long shnGBuffer;
|
||||||
|
unsigned short shnBitShift;
|
||||||
|
long cbuf0[3];
|
||||||
|
long cbuf1[3];
|
||||||
|
long offset0[4];
|
||||||
|
long offset1[4];
|
||||||
|
} shn_seek_entry;
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _shn_wave_header
|
||||||
|
{
|
||||||
|
char *filename,
|
||||||
|
m_ss[16];
|
||||||
|
|
||||||
|
uint header_size;
|
||||||
|
|
||||||
|
ushort channels,
|
||||||
|
block_align,
|
||||||
|
bits_per_sample,
|
||||||
|
wave_format;
|
||||||
|
|
||||||
|
ulong samples_per_sec,
|
||||||
|
avg_bytes_per_sec,
|
||||||
|
rate,
|
||||||
|
length,
|
||||||
|
data_size,
|
||||||
|
total_size,
|
||||||
|
chunk_size,
|
||||||
|
actual_size;
|
||||||
|
|
||||||
|
double exact_length;
|
||||||
|
|
||||||
|
int file_has_id3v2_tag;
|
||||||
|
long id3v2_tag_size;
|
||||||
|
|
||||||
|
ulong problems;
|
||||||
|
} shn_wave_header;
|
||||||
|
|
||||||
|
typedef struct _shn_vars
|
||||||
|
{
|
||||||
|
FILE *fd;
|
||||||
|
int seek_to;
|
||||||
|
int eof;
|
||||||
|
int going;
|
||||||
|
slong seek_table_entries;
|
||||||
|
ulong seek_resolution;
|
||||||
|
int bytes_in_buf;
|
||||||
|
uchar buffer[OUT_BUFFER_SIZE];
|
||||||
|
int bytes_in_header;
|
||||||
|
uchar header[OUT_BUFFER_SIZE];
|
||||||
|
int fatal_error;
|
||||||
|
schar fatal_error_msg[BUF_SIZE];
|
||||||
|
int reading_function_code;
|
||||||
|
ulong last_file_position;
|
||||||
|
ulong last_file_position_no_really;
|
||||||
|
ulong initial_file_position;
|
||||||
|
ulong bytes_read;
|
||||||
|
unsigned short bitshift;
|
||||||
|
long seek_offset;
|
||||||
|
} shn_vars;
|
||||||
|
|
||||||
|
typedef struct _shn_file
|
||||||
|
{
|
||||||
|
shn_vars vars;
|
||||||
|
shn_decode_state *decode_state;
|
||||||
|
shn_wave_header wave_header;
|
||||||
|
shn_seek_header seek_header;
|
||||||
|
shn_seek_trailer seek_trailer;
|
||||||
|
shn_seek_entry *seek_table;
|
||||||
|
shn_config config;
|
||||||
|
} shn_file;
|
||||||
|
|
||||||
|
extern shn_seek_entry *shn_seek_entry_search(shn_config,shn_seek_entry *,ulong,ulong,ulong,ulong);
|
||||||
|
extern void shn_load_seek_table(shn_file *,char *);
|
||||||
|
extern void shn_unload(shn_file *);
|
||||||
|
extern void shn_display_about(void);
|
||||||
|
extern void shn_display_configure(void);
|
||||||
|
extern void shn_display_info(shn_file *);
|
||||||
|
extern int shn_verify_header(shn_file *);
|
||||||
|
extern int shn_filename_contains_a_dot(char *);
|
||||||
|
extern char *shn_get_base_filename(char *);
|
||||||
|
extern char *shn_get_base_directory(char *);
|
||||||
|
extern void shn_length_to_str(shn_file *);
|
||||||
|
extern ulong shn_uchar_to_ulong_le(uchar *);
|
||||||
|
extern slong shn_uchar_to_slong_le(uchar *);
|
||||||
|
extern ushort shn_uchar_to_ushort_le(uchar *);
|
||||||
|
extern char *shn_format_to_str(ushort);
|
||||||
|
extern void shn_debug(shn_config,char *, ...);
|
||||||
|
extern void shn_error(shn_config,char *, ...);
|
||||||
|
extern void shn_error_fatal(shn_file *,char *, ...);
|
||||||
|
extern void shn_snprintf(char *,int,char *, ...);
|
||||||
|
extern FILE *shn_open_and_discard_id3v2_tag(char *,int *,long *);
|
||||||
|
|
||||||
|
#endif
|
220
Libraries/Shorten/Files/shorten/include/shorten.h
Normal file
220
Libraries/Shorten/Files/shorten/include/shorten.h
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SHORTEN_H
|
||||||
|
#define _SHORTEN_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
# include <inttypes.h>
|
||||||
|
#else
|
||||||
|
# if SIZEOF_UNSIGNED_LONG == 4
|
||||||
|
# define uint32_t unsigned long
|
||||||
|
# define int32_t long
|
||||||
|
# else
|
||||||
|
# define uint32_t unsigned int
|
||||||
|
# define int32_t int
|
||||||
|
# endif
|
||||||
|
# define uint16_t unsigned short
|
||||||
|
# define uint8_t unsigned char
|
||||||
|
# define int16_t short
|
||||||
|
# define int8_t char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef ulong
|
||||||
|
#undef ushort
|
||||||
|
#undef uchar
|
||||||
|
#undef slong
|
||||||
|
#undef sshort
|
||||||
|
#undef schar
|
||||||
|
#define ulong uint32_t
|
||||||
|
#define ushort uint16_t
|
||||||
|
#define uchar uint8_t
|
||||||
|
#define slong int32_t
|
||||||
|
#define sshort int16_t
|
||||||
|
#define schar int8_t
|
||||||
|
|
||||||
|
#include "shn.h"
|
||||||
|
|
||||||
|
#define MAGIC "ajkg"
|
||||||
|
#define FORMAT_VERSION 2
|
||||||
|
#define MIN_SUPPORTED_VERSION 1
|
||||||
|
#define MAX_SUPPORTED_VERSION 3
|
||||||
|
#define MAX_VERSION 7
|
||||||
|
|
||||||
|
#define UNDEFINED_UINT -1
|
||||||
|
#define DEFAULT_BLOCK_SIZE 256
|
||||||
|
#define DEFAULT_V0NMEAN 0
|
||||||
|
#define DEFAULT_V2NMEAN 4
|
||||||
|
#define DEFAULT_MAXNLPC 0
|
||||||
|
#define DEFAULT_NCHAN 1
|
||||||
|
#define DEFAULT_NSKIP 0
|
||||||
|
#define DEFAULT_NDISCARD 0
|
||||||
|
#define NBITPERLONG 32
|
||||||
|
#define DEFAULT_MINSNR 256
|
||||||
|
#define DEFAULT_MAXRESNSTR "32.0"
|
||||||
|
#define DEFAULT_QUANTERROR 0
|
||||||
|
#define MINBITRATE 2.5
|
||||||
|
|
||||||
|
#define MAX_LPC_ORDER 64
|
||||||
|
#define CHANSIZE 0
|
||||||
|
#define ENERGYSIZE 3
|
||||||
|
#define BITSHIFTSIZE 2
|
||||||
|
#define NWRAP 3
|
||||||
|
|
||||||
|
#define FNSIZE 2
|
||||||
|
#define FN_DIFF0 0
|
||||||
|
#define FN_DIFF1 1
|
||||||
|
#define FN_DIFF2 2
|
||||||
|
#define FN_DIFF3 3
|
||||||
|
#define FN_QUIT 4
|
||||||
|
#define FN_BLOCKSIZE 5
|
||||||
|
#define FN_BITSHIFT 6
|
||||||
|
#define FN_QLPC 7
|
||||||
|
#define FN_ZERO 8
|
||||||
|
#define FN_VERBATIM 9
|
||||||
|
|
||||||
|
#define VERBATIM_CKSIZE_SIZE 5 /* a var_put code size */
|
||||||
|
#define VERBATIM_BYTE_SIZE 8 /* code size 8 on single bytes means
|
||||||
|
* no compression at all */
|
||||||
|
#define VERBATIM_CHUNK_MAX 256 /* max. size of a FN_VERBATIM chunk */
|
||||||
|
|
||||||
|
#define ULONGSIZE 2
|
||||||
|
#define NSKIPSIZE 1
|
||||||
|
#define LPCQSIZE 2
|
||||||
|
#define LPCQUANT 5
|
||||||
|
#define XBYTESIZE 7
|
||||||
|
|
||||||
|
#define TYPESIZE 4
|
||||||
|
#define TYPE_AU1 0 /* original lossless ulaw */
|
||||||
|
#define TYPE_S8 1 /* signed 8 bit characters */
|
||||||
|
#define TYPE_U8 2 /* unsigned 8 bit characters */
|
||||||
|
#define TYPE_S16HL 3 /* signed 16 bit shorts: high-low */
|
||||||
|
#define TYPE_U16HL 4 /* unsigned 16 bit shorts: high-low */
|
||||||
|
#define TYPE_S16LH 5 /* signed 16 bit shorts: low-high */
|
||||||
|
#define TYPE_U16LH 6 /* unsigned 16 bit shorts: low-high */
|
||||||
|
#define TYPE_ULAW 7 /* lossy ulaw: internal conversion to linear */
|
||||||
|
#define TYPE_AU2 8 /* new ulaw with zero mapping */
|
||||||
|
#define TYPE_AU3 9 /* lossless alaw */
|
||||||
|
#define TYPE_ALAW 10 /* lossy alaw: internal conversion to linear */
|
||||||
|
#define TYPE_RIFF_WAVE 11 /* Microsoft .WAV files */
|
||||||
|
#define TYPE_EOF 12
|
||||||
|
#define TYPE_GENERIC_ULAW 128
|
||||||
|
#define TYPE_GENERIC_ALAW 129
|
||||||
|
|
||||||
|
#define POSITIVE_ULAW_ZERO 0xff
|
||||||
|
#define NEGATIVE_ULAW_ZERO 0x7f
|
||||||
|
|
||||||
|
#ifndef MAX_PATH
|
||||||
|
#define MAX_PATH 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(unix) && !defined(linux)
|
||||||
|
#define labs abs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ROUNDEDSHIFTDOWN(x, n) (((n) == 0) ? (x) : ((x) >> ((n) - 1)) >> 1)
|
||||||
|
|
||||||
|
#ifndef M_LN2
|
||||||
|
#define M_LN2 0.69314718055994530942
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BUFSIZ must be a multiple of four to contain a whole number of words */
|
||||||
|
#ifdef BUFSIZ
|
||||||
|
#undef BUFSIZ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BUFSIZ 512
|
||||||
|
|
||||||
|
#define V2LPCQOFFSET (1 << LPCQUANT);
|
||||||
|
|
||||||
|
#define UINT_GET(nbit, file) \
|
||||||
|
((version == 0) ? uvar_get(nbit, file) : ulong_get(file))
|
||||||
|
|
||||||
|
#define putc_exit(val, stream)\
|
||||||
|
{ char rval;\
|
||||||
|
if((rval = putc((val), (stream))) != (char) (val))\
|
||||||
|
complain("FATALERROR: write failed: putc returns EOF");\
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int getc_exit_val;
|
||||||
|
#define getc_exit(stream)\
|
||||||
|
(((getc_exit_val = getc(stream)) == EOF) ? \
|
||||||
|
complain("FATALERROR: read failed: getc returns EOF"), 0: getc_exit_val)
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* defined in shorten.c */
|
||||||
|
extern void init_offset(slong**, int, int, int);
|
||||||
|
extern int shorten(FILE*, FILE*, int, char**);
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* defined in Sulawalaw.c */
|
||||||
|
extern int Sulaw2lineartab[];
|
||||||
|
#define Sulaw2linear(i) (Sulaw2lineartab[i])
|
||||||
|
#ifndef Sulaw2linear
|
||||||
|
extern int Sulaw2linear(uchar);
|
||||||
|
#endif
|
||||||
|
extern uchar Slinear2ulaw(int);
|
||||||
|
|
||||||
|
extern int Salaw2lineartab[];
|
||||||
|
#define Salaw2linear(i) (Salaw2lineartab[i])
|
||||||
|
#ifndef Salaw2linear
|
||||||
|
extern int Salaw2linear(uchar);
|
||||||
|
#endif
|
||||||
|
extern uchar Slinear2alaw(int);
|
||||||
|
|
||||||
|
/**********************/
|
||||||
|
/* defined in fixio.c */
|
||||||
|
extern void init_sizeof_sample(void);
|
||||||
|
extern void fwrite_type_init(shn_file*);
|
||||||
|
extern void fwrite_type(slong**,int,int,int,shn_file*);
|
||||||
|
extern void fwrite_type_quit(shn_file*);
|
||||||
|
extern void fix_bitshift(slong*, int, int, int);
|
||||||
|
|
||||||
|
/**********************/
|
||||||
|
/* defined in vario.c */
|
||||||
|
extern void var_get_init(shn_file*);
|
||||||
|
extern slong uvar_get(int, shn_file*);
|
||||||
|
extern slong var_get(int, shn_file*);
|
||||||
|
extern ulong ulong_get(shn_file*);
|
||||||
|
extern void var_get_quit(shn_file*);
|
||||||
|
|
||||||
|
extern int sizeof_uvar(ulong, int);
|
||||||
|
extern int sizeof_var(slong, int);
|
||||||
|
|
||||||
|
extern void mkmasktab(void);
|
||||||
|
extern ulong word_get(shn_file*);
|
||||||
|
|
||||||
|
/**********************/
|
||||||
|
/* defined in array.c */
|
||||||
|
extern void* pmalloc(ulong, shn_file*);
|
||||||
|
extern slong** long2d(ulong, ulong, shn_file*);
|
||||||
|
|
||||||
|
#endif
|
21
Libraries/Shorten/Files/shorten/src/Makefile.am
Normal file
21
Libraries/Shorten/Files/shorten/src/Makefile.am
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
noinst_LTLIBRARIES = libshorten.la
|
||||||
|
BUILT_SOURCES = bitshift.h
|
||||||
|
|
||||||
|
libshorten_la_LDFLAGS = -module -export-dynamic -avoid-version
|
||||||
|
libshorten_la_SOURCES = array.c convert.c fixio.c id3v2.c misc.c output.c shorten.c seek.c sulawalaw.c vario.c wave.c decode.c
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
CLEANFILES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
array.c: $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
bitshift.h:
|
||||||
|
-@if [ -x "../util/mkbshift" ] ; then \
|
||||||
|
../util/mkbshift ; \
|
||||||
|
else \
|
||||||
|
echo "" ; \
|
||||||
|
echo "*** missing ../util/mkbshift - run '$(MAKE)' in the top-level directory to build it ***" ; \
|
||||||
|
echo "" ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
40
Libraries/Shorten/Files/shorten/src/array.c
Normal file
40
Libraries/Shorten/Files/shorten/src/array.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
void *pmalloc(ulong size, shn_file *this_shn) {
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = malloc(size);
|
||||||
|
|
||||||
|
if(ptr == NULL)
|
||||||
|
shn_error_fatal(this_shn,"Call to malloc(%ld) failed in pmalloc() -\nyour system may be low on memory", size);
|
||||||
|
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
slong **long2d(ulong n0, ulong n1, shn_file *this_shn) {
|
||||||
|
slong **array0 = NULL;
|
||||||
|
|
||||||
|
if((array0 = (slong**) pmalloc((ulong) (n0 * sizeof(slong*) +
|
||||||
|
n0 * n1 * sizeof(slong)),this_shn)) != NULL ) {
|
||||||
|
slong *array1 = (slong*) (array0 + n0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n0; i++)
|
||||||
|
array0[i] = array1 + i * n1;
|
||||||
|
}
|
||||||
|
return(array0);
|
||||||
|
}
|
42
Libraries/Shorten/Files/shorten/src/convert.c
Normal file
42
Libraries/Shorten/Files/shorten/src/convert.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* convert.c - functions to convert little-endian data to endian of host
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
ulong shn_uchar_to_ulong_le(uchar *buf)
|
||||||
|
/* converts 4 bytes stored in little-endian format to a ulong */
|
||||||
|
{
|
||||||
|
return (ulong)((buf[3] << 24) + (buf[2] << 16) + (buf[1] << 8) + buf[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
slong shn_uchar_to_slong_le(uchar *buf)
|
||||||
|
/* converts 4 bytes stored in little-endian format to an slong */
|
||||||
|
{
|
||||||
|
return (slong)shn_uchar_to_ulong_le(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort shn_uchar_to_ushort_le(uchar *buf)
|
||||||
|
/* converts 4 bytes stored in little-endian format to a ushort */
|
||||||
|
{
|
||||||
|
return (ushort)((buf[1] << 8) + buf[0]);
|
||||||
|
}
|
1154
Libraries/Shorten/Files/shorten/src/decode.c
Normal file
1154
Libraries/Shorten/Files/shorten/src/decode.c
Normal file
File diff suppressed because it is too large
Load diff
276
Libraries/Shorten/Files/shorten/src/fixio.c
Normal file
276
Libraries/Shorten/Files/shorten/src/fixio.c
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
#include "bitshift.h"
|
||||||
|
|
||||||
|
#define CAPMAXSCHAR(x) ((x > 127) ? 127 : x)
|
||||||
|
#define CAPMAXUCHAR(x) ((x > 255) ? 255 : x)
|
||||||
|
#define CAPMAXSHORT(x) ((x > 32767) ? 32767 : x)
|
||||||
|
#define CAPMAXUSHORT(x) ((x > 65535) ? 65535 : x)
|
||||||
|
|
||||||
|
static int sizeof_sample[TYPE_EOF];
|
||||||
|
|
||||||
|
void init_sizeof_sample() {
|
||||||
|
sizeof_sample[TYPE_AU1] = sizeof(uchar);
|
||||||
|
sizeof_sample[TYPE_S8] = sizeof(schar);
|
||||||
|
sizeof_sample[TYPE_U8] = sizeof(uchar);
|
||||||
|
sizeof_sample[TYPE_S16HL] = sizeof(ushort);
|
||||||
|
sizeof_sample[TYPE_U16HL] = sizeof(ushort);
|
||||||
|
sizeof_sample[TYPE_S16LH] = sizeof(ushort);
|
||||||
|
sizeof_sample[TYPE_U16LH] = sizeof(ushort);
|
||||||
|
sizeof_sample[TYPE_ULAW] = sizeof(uchar);
|
||||||
|
sizeof_sample[TYPE_AU2] = sizeof(uchar);
|
||||||
|
sizeof_sample[TYPE_AU3] = sizeof(uchar);
|
||||||
|
sizeof_sample[TYPE_ALAW] = sizeof(uchar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************/
|
||||||
|
/* fixed write */
|
||||||
|
/***************/
|
||||||
|
|
||||||
|
void fwrite_type_init(shn_file *this_shn) {
|
||||||
|
init_sizeof_sample();
|
||||||
|
this_shn->decode_state->writebuf = (schar*) NULL;
|
||||||
|
this_shn->decode_state->writefub = (schar*) NULL;
|
||||||
|
this_shn->decode_state->nwritebuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fwrite_type_quit(shn_file *this_shn) {
|
||||||
|
if(this_shn->decode_state->writebuf != NULL) {
|
||||||
|
free(this_shn->decode_state->writebuf);
|
||||||
|
this_shn->decode_state->writebuf = NULL;
|
||||||
|
}
|
||||||
|
if(this_shn->decode_state->writefub != NULL) {
|
||||||
|
free(this_shn->decode_state->writefub);
|
||||||
|
this_shn->decode_state->writefub = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert from signed ints to a given type and write */
|
||||||
|
void fwrite_type(slong **data,int ftype,int nchan,int nitem,shn_file *this_shn)
|
||||||
|
{
|
||||||
|
int hiloint = 1, hilo = !(*((char*) &hiloint));
|
||||||
|
int i, nwrite = 0, datasize = sizeof_sample[ftype], chan;
|
||||||
|
slong *data0 = data[0];
|
||||||
|
int bufAvailable = OUT_BUFFER_SIZE - this_shn->vars.bytes_in_buf;
|
||||||
|
|
||||||
|
if(this_shn->decode_state->nwritebuf < nchan * nitem * datasize) {
|
||||||
|
this_shn->decode_state->nwritebuf = nchan * nitem * datasize;
|
||||||
|
if(this_shn->decode_state->writebuf != NULL) free(this_shn->decode_state->writebuf);
|
||||||
|
if(this_shn->decode_state->writefub != NULL) free(this_shn->decode_state->writefub);
|
||||||
|
this_shn->decode_state->writebuf = (schar*) pmalloc((ulong) this_shn->decode_state->nwritebuf,this_shn);
|
||||||
|
if (!this_shn->decode_state->writebuf)
|
||||||
|
return;
|
||||||
|
this_shn->decode_state->writefub = (schar*) pmalloc((ulong) this_shn->decode_state->nwritebuf,this_shn);
|
||||||
|
if (!this_shn->decode_state->writefub)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ftype) {
|
||||||
|
case TYPE_AU1: /* leave the conversion to fix_bitshift() */
|
||||||
|
case TYPE_AU2: {
|
||||||
|
uchar *writebufp = (uchar*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = data0[i];
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = data[chan][i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_U8: {
|
||||||
|
uchar *writebufp = (uchar*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = CAPMAXUCHAR(data0[i]);
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = CAPMAXUCHAR(data[chan][i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_S8: {
|
||||||
|
schar *writebufp = (schar*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = CAPMAXSCHAR(data0[i]);
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = CAPMAXSCHAR(data[chan][i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_S16HL:
|
||||||
|
case TYPE_S16LH: {
|
||||||
|
short *writebufp = (short*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = CAPMAXSHORT(data0[i]);
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = CAPMAXSHORT(data[chan][i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_U16HL:
|
||||||
|
case TYPE_U16LH: {
|
||||||
|
ushort *writebufp = (ushort*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = CAPMAXUSHORT(data0[i]);
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = CAPMAXUSHORT(data[chan][i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_ULAW: {
|
||||||
|
uchar *writebufp = (uchar*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = Slinear2ulaw(CAPMAXSHORT((data0[i] << 3)));
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = Slinear2ulaw(CAPMAXSHORT((data[chan][i] << 3)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_AU3: {
|
||||||
|
uchar *writebufp = (uchar*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
if(data0[i] < 0)
|
||||||
|
*writebufp++ = (127 - data0[i]) ^ 0xd5;
|
||||||
|
else
|
||||||
|
*writebufp++ = (data0[i] + 128) ^ 0x55;
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
if(data[chan][i] < 0)
|
||||||
|
*writebufp++ = (127 - data[chan][i]) ^ 0xd5;
|
||||||
|
else
|
||||||
|
*writebufp++ = (data[chan][i] + 128) ^ 0x55;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_ALAW: {
|
||||||
|
uchar *writebufp = (uchar*) this_shn->decode_state->writebuf;
|
||||||
|
if(nchan == 1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
*writebufp++ = Slinear2alaw(CAPMAXSHORT((data0[i] << 3)));
|
||||||
|
else
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
*writebufp++ = Slinear2alaw(CAPMAXSHORT((data[chan][i] << 3)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ftype) {
|
||||||
|
case TYPE_AU1:
|
||||||
|
case TYPE_S8:
|
||||||
|
case TYPE_U8:
|
||||||
|
case TYPE_ULAW:
|
||||||
|
case TYPE_AU2:
|
||||||
|
case TYPE_AU3:
|
||||||
|
case TYPE_ALAW:
|
||||||
|
if (datasize*nchan*nitem <= bufAvailable) {
|
||||||
|
memcpy((void *)&this_shn->vars.buffer[this_shn->vars.bytes_in_buf],(const void *)this_shn->decode_state->writebuf,datasize*nchan*nitem);
|
||||||
|
this_shn->vars.bytes_in_buf += datasize*nchan*nitem;
|
||||||
|
nwrite = nitem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shn_debug(this_shn->config, "Buffer overrun in fwrite_type() [case 1]: %d bytes to read, but only %d bytes are available",datasize*nchan*nitem,bufAvailable);
|
||||||
|
break;
|
||||||
|
case TYPE_S16HL:
|
||||||
|
case TYPE_U16HL:
|
||||||
|
if(hilo)
|
||||||
|
{
|
||||||
|
if (datasize*nchan*nitem <= bufAvailable) {
|
||||||
|
memcpy((void *)&this_shn->vars.buffer[this_shn->vars.bytes_in_buf],(const void *)this_shn->decode_state->writebuf,datasize*nchan*nitem);
|
||||||
|
this_shn->vars.bytes_in_buf += datasize*nchan*nitem;
|
||||||
|
nwrite = nitem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shn_debug(this_shn->config, "Buffer overrun in fwrite_type() [case 2]: %d bytes to read, but only %d bytes are available",datasize*nchan*nitem,bufAvailable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
swab(this_shn->decode_state->writebuf, this_shn->decode_state->writefub, datasize * nchan * nitem);
|
||||||
|
if (datasize*nchan*nitem <= bufAvailable) {
|
||||||
|
memcpy((void *)&this_shn->vars.buffer[this_shn->vars.bytes_in_buf],(const void *)this_shn->decode_state->writefub,datasize*nchan*nitem);
|
||||||
|
this_shn->vars.bytes_in_buf += datasize*nchan*nitem;
|
||||||
|
nwrite = nitem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shn_debug(this_shn->config, "Buffer overrun in fwrite_type() [case 3]: %d bytes to read, but only %d bytes are available",datasize*nchan*nitem,bufAvailable);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_S16LH:
|
||||||
|
case TYPE_U16LH:
|
||||||
|
if(hilo)
|
||||||
|
{
|
||||||
|
swab(this_shn->decode_state->writebuf, this_shn->decode_state->writefub, datasize * nchan * nitem);
|
||||||
|
if (datasize*nchan*nitem <= bufAvailable) {
|
||||||
|
memcpy((void *)&this_shn->vars.buffer[this_shn->vars.bytes_in_buf],(const void *)this_shn->decode_state->writefub,datasize*nchan*nitem);
|
||||||
|
this_shn->vars.bytes_in_buf += datasize*nchan*nitem;
|
||||||
|
nwrite = nitem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shn_debug(this_shn->config, "Buffer overrun in fwrite_type() [case 4]: %d bytes to read, but only %d bytes are available",datasize*nchan*nitem,bufAvailable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (datasize*nchan*nitem <= bufAvailable) {
|
||||||
|
memcpy((void *)&this_shn->vars.buffer[this_shn->vars.bytes_in_buf],(const void *)this_shn->decode_state->writebuf,datasize*nchan*nitem);
|
||||||
|
this_shn->vars.bytes_in_buf += datasize*nchan*nitem;
|
||||||
|
nwrite = nitem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shn_debug(this_shn->config, "Buffer overrun in fwrite_type() [case 5]: %d bytes to read, but only %d bytes are available",datasize*nchan*nitem,bufAvailable);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nwrite != nitem)
|
||||||
|
shn_error_fatal(this_shn,"Failed to write decompressed stream -\npossible corrupt or truncated file");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************/
|
||||||
|
/* bitshifts */
|
||||||
|
/*************/
|
||||||
|
|
||||||
|
void fix_bitshift(buffer, nitem, bitshift, ftype) slong *buffer; int nitem,
|
||||||
|
bitshift, ftype; {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(ftype == TYPE_AU1)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
buffer[i] = ulaw_outward[bitshift][buffer[i] + 128];
|
||||||
|
else if(ftype == TYPE_AU2)
|
||||||
|
for(i = 0; i < nitem; i++) {
|
||||||
|
if(buffer[i] >= 0)
|
||||||
|
buffer[i] = ulaw_outward[bitshift][buffer[i] + 128];
|
||||||
|
else if(buffer[i] == -1)
|
||||||
|
buffer[i] = NEGATIVE_ULAW_ZERO;
|
||||||
|
else
|
||||||
|
buffer[i] = ulaw_outward[bitshift][buffer[i] + 129];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(bitshift != 0)
|
||||||
|
for(i = 0; i < nitem; i++)
|
||||||
|
buffer[i] <<= bitshift;
|
||||||
|
}
|
120
Libraries/Shorten/Files/shorten/src/id3v2.c
Normal file
120
Libraries/Shorten/Files/shorten/src/id3v2.c
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/* id3v2.c - functions to handle ID3v2 tags prepended to shn files
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ID3V2_MAGIC "ID3"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char magic[3];
|
||||||
|
unsigned char version[2];
|
||||||
|
unsigned char flags[1];
|
||||||
|
unsigned char size[4];
|
||||||
|
} _id3v2_header;
|
||||||
|
|
||||||
|
int tagcmp(char *got,char *expected)
|
||||||
|
/* compare got against expected, up to the length of expected */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0;*(expected+i);i++) {
|
||||||
|
if (*(got+i) != *(expected+i))
|
||||||
|
return i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long synchsafe_int_to_ulong(unsigned char *buf)
|
||||||
|
/* converts 4 bytes stored in synchsafe integer format to an unsigned long */
|
||||||
|
{
|
||||||
|
return (unsigned long)(((buf[0] & 0x7f) << 21) | ((buf[1] & 0x7f) << 14) | ((buf[2] & 0x7f) << 7) | (buf[3] & 0x7f));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long check_for_id3v2_tag(FILE *f)
|
||||||
|
{
|
||||||
|
_id3v2_header id3v2_header;
|
||||||
|
unsigned long tag_size;
|
||||||
|
|
||||||
|
/* read an ID3v2 header's size worth of data */
|
||||||
|
if (sizeof(_id3v2_header) != fread(&id3v2_header,1,sizeof(_id3v2_header),f)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify this is an ID3v2 header */
|
||||||
|
if (tagcmp(id3v2_header.magic,ID3V2_MAGIC) ||
|
||||||
|
0xff == id3v2_header.version[0] || 0xff == id3v2_header.version[1] ||
|
||||||
|
0x80 <= id3v2_header.size[0] || 0x80 <= id3v2_header.size[1] ||
|
||||||
|
0x80 <= id3v2_header.size[2] || 0x80 <= id3v2_header.size[3])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate and return ID3v2 tag size */
|
||||||
|
tag_size = synchsafe_int_to_ulong(id3v2_header.size);
|
||||||
|
|
||||||
|
return tag_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *shn_open_and_discard_id3v2_tag(char *filename,int *file_has_id3v2_tag,long *id3v2_tag_size)
|
||||||
|
/* opens a file, and if it contains an ID3v2 tag, skips past it */
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
unsigned long tag_size;
|
||||||
|
|
||||||
|
if (NULL == (f = fopen(filename,"rb"))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_has_id3v2_tag)
|
||||||
|
*file_has_id3v2_tag = 0;
|
||||||
|
|
||||||
|
if (id3v2_tag_size)
|
||||||
|
*id3v2_tag_size = 0;
|
||||||
|
|
||||||
|
/* check for ID3v2 tag on input */
|
||||||
|
if (0 == (tag_size = check_for_id3v2_tag(f))) {
|
||||||
|
fclose(f);
|
||||||
|
return fopen(filename,"rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_has_id3v2_tag)
|
||||||
|
*file_has_id3v2_tag = 2;
|
||||||
|
|
||||||
|
if (id3v2_tag_size)
|
||||||
|
*id3v2_tag_size = (long)(tag_size + sizeof(_id3v2_header));
|
||||||
|
|
||||||
|
fprintf(stderr, "Discarding %lu-byte ID3v2 tag at beginning of file '%s'.",tag_size+sizeof(_id3v2_header),filename);
|
||||||
|
|
||||||
|
if (0 != fseek(f,(long)tag_size,SEEK_CUR)) {
|
||||||
|
fprintf(stderr, "Error while discarding ID3v2 tag in file '%s'.",filename);
|
||||||
|
fclose(f);
|
||||||
|
return fopen(filename,"rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
149
Libraries/Shorten/Files/shorten/src/misc.c
Normal file
149
Libraries/Shorten/Files/shorten/src/misc.c
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/* misc.c - miscellaneous functions
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
void shn_snprintf(char *dest,int maxlen,char *formatstr, ...)
|
||||||
|
/* acts like snprintf, but makes 100% sure the string is NULL-terminated */
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args,formatstr);
|
||||||
|
|
||||||
|
shn_vsnprintf(dest,maxlen,formatstr,args);
|
||||||
|
|
||||||
|
dest[maxlen-1] = 0;
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int shn_filename_contains_a_dot(char *filename)
|
||||||
|
{
|
||||||
|
char *slash,*dot;
|
||||||
|
|
||||||
|
dot = strrchr(filename,'.');
|
||||||
|
if (!dot)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
slash = strrchr(filename,'/');
|
||||||
|
if (!slash)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (slash < dot)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *shn_get_base_filename(char *filename)
|
||||||
|
{
|
||||||
|
char *b,*e,*p,*base;
|
||||||
|
|
||||||
|
b = strrchr(filename,'/');
|
||||||
|
|
||||||
|
if (b)
|
||||||
|
b++;
|
||||||
|
else
|
||||||
|
b = filename;
|
||||||
|
|
||||||
|
e = strrchr(filename,'.');
|
||||||
|
|
||||||
|
if (e < b)
|
||||||
|
e = filename + strlen(filename);
|
||||||
|
|
||||||
|
if (NULL == (base = malloc((e - b + 1) * sizeof(char))))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not allocate memory for base filename");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p=b;p<e;p++)
|
||||||
|
*(base + (p - b)) = *p;
|
||||||
|
|
||||||
|
*(base + (p - b)) = '\0';
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *shn_get_base_directory(char *filename)
|
||||||
|
{
|
||||||
|
char *e,*p,*base;
|
||||||
|
|
||||||
|
e = strrchr(filename,'/');
|
||||||
|
|
||||||
|
if (!e)
|
||||||
|
e = filename;
|
||||||
|
|
||||||
|
if (NULL == (base = malloc((e - filename + 1) * sizeof(char))))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not allocate memory for base directory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p=filename;p<e;p++)
|
||||||
|
*(base + (p - filename)) = *p;
|
||||||
|
|
||||||
|
*(base + (p - filename)) = '\0';
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shn_length_to_str(shn_file *info)
|
||||||
|
/* converts length of file to a string in m:ss or m:ss.ff format */
|
||||||
|
{
|
||||||
|
ulong newlength,rem1,rem2,frames,ms;
|
||||||
|
double tmp;
|
||||||
|
|
||||||
|
if (PROB_NOT_CD(info->wave_header)) {
|
||||||
|
newlength = (ulong)info->wave_header.exact_length;
|
||||||
|
|
||||||
|
tmp = info->wave_header.exact_length - (double)((ulong)info->wave_header.exact_length);
|
||||||
|
ms = (ulong)((tmp * 1000.0) + 0.5);
|
||||||
|
|
||||||
|
if (1000 == ms) {
|
||||||
|
ms = 0;
|
||||||
|
newlength++;
|
||||||
|
}
|
||||||
|
|
||||||
|
shn_snprintf(info->wave_header.m_ss,16,"%lu:%02lu.%03lu",newlength/60,newlength%60,ms);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newlength = info->wave_header.length;
|
||||||
|
|
||||||
|
rem1 = info->wave_header.data_size % CD_RATE;
|
||||||
|
rem2 = rem1 % CD_BLOCK_SIZE;
|
||||||
|
|
||||||
|
frames = rem1 / CD_BLOCK_SIZE;
|
||||||
|
if (rem2 >= (CD_BLOCK_SIZE / 2))
|
||||||
|
frames++;
|
||||||
|
|
||||||
|
if (frames == CD_BLOCKS_PER_SEC) {
|
||||||
|
frames = 0;
|
||||||
|
newlength++;
|
||||||
|
}
|
||||||
|
|
||||||
|
shn_snprintf(info->wave_header.m_ss,16,"%lu:%02lu.%02lu",newlength/60,newlength%60,frames);
|
||||||
|
}
|
||||||
|
}
|
99
Libraries/Shorten/Files/shorten/src/output.c
Normal file
99
Libraries/Shorten/Files/shorten/src/output.c
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/* output.c - functions for message and error output
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void print_lines(char *prefix,char *message)
|
||||||
|
{
|
||||||
|
char *head, *tail;
|
||||||
|
|
||||||
|
head = tail = message;
|
||||||
|
while (*head != '\0') {
|
||||||
|
if (*head == '\n') {
|
||||||
|
*head = '\0';
|
||||||
|
fprintf(stderr,"%s%s\n",prefix,tail);
|
||||||
|
tail = head + 1;
|
||||||
|
}
|
||||||
|
head++;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"%s%s\n",prefix,tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shn_error(shn_config config, char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char msgbuf[BUF_SIZE];
|
||||||
|
|
||||||
|
va_start(args,msg);
|
||||||
|
|
||||||
|
shn_vsnprintf(msgbuf,BUF_SIZE,msg,args);
|
||||||
|
|
||||||
|
switch (config.error_output_method) {
|
||||||
|
case ERROR_OUTPUT_STDERR:
|
||||||
|
print_lines(PACKAGE ": ",msgbuf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (0 != config.verbose)
|
||||||
|
print_lines(PACKAGE " [error]: ",msgbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shn_debug(shn_config config, char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char msgbuf[BUF_SIZE];
|
||||||
|
|
||||||
|
va_start(args,msg);
|
||||||
|
|
||||||
|
shn_vsnprintf(msgbuf,BUF_SIZE,msg,args);
|
||||||
|
|
||||||
|
if (0 != config.verbose)
|
||||||
|
print_lines(PACKAGE " [debug]: ",msgbuf);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shn_error_fatal(shn_file *this_shn,char *complaint, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args,complaint);
|
||||||
|
|
||||||
|
if (NULL != this_shn) {
|
||||||
|
if (0 == this_shn->vars.fatal_error) {
|
||||||
|
this_shn->vars.fatal_error = 1;
|
||||||
|
this_shn->vars.going = 0;
|
||||||
|
shn_vsnprintf(this_shn->vars.fatal_error_msg,BUF_SIZE,complaint,args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
284
Libraries/Shorten/Files/shorten/src/seek.c
Normal file
284
Libraries/Shorten/Files/shorten/src/seek.c
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
/* seek.c - functions related to real-time seeking
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ID3V1_TAG_SIZE 128
|
||||||
|
|
||||||
|
shn_seek_entry *shn_seek_entry_search(shn_config config, shn_seek_entry *table,ulong goal,ulong min,ulong max,ulong resolution)
|
||||||
|
{
|
||||||
|
ulong med = (min + max) / 2;
|
||||||
|
shn_seek_entry *middle = table + med;
|
||||||
|
ulong sample = shn_uchar_to_ulong_le(middle->data);
|
||||||
|
|
||||||
|
shn_debug(config, "Examining seek table entry %lu with sample %lu (min/max = %lu/%lu, goal sample is %lu, resolution is %lu samples)",med,sample,min,max,goal,resolution);
|
||||||
|
|
||||||
|
if (goal < sample)
|
||||||
|
return shn_seek_entry_search(config, table,goal,min,med-1,resolution);
|
||||||
|
if (goal > sample + resolution)
|
||||||
|
return shn_seek_entry_search(config, table,goal,med+1,max,resolution);
|
||||||
|
return middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_separate_seek_table_generic(char *filename,shn_file *this_shn)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
slong seek_table_len;
|
||||||
|
|
||||||
|
shn_debug(this_shn->config, "Looking for seek table in separate file: '%s'",filename);
|
||||||
|
|
||||||
|
if (!(f=fopen(filename,"rb")))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f,0,SEEK_END);
|
||||||
|
seek_table_len = (slong)ftell(f) - SEEK_HEADER_SIZE;
|
||||||
|
fseek(f,0,SEEK_SET);
|
||||||
|
|
||||||
|
if (fread((void *)this_shn->seek_header.data,1,SEEK_HEADER_SIZE,f) == SEEK_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
this_shn->seek_header.version = (slong)shn_uchar_to_ulong_le(this_shn->seek_header.data+4);
|
||||||
|
this_shn->seek_header.shnFileSize = shn_uchar_to_ulong_le(this_shn->seek_header.data+8);
|
||||||
|
if (memcmp(this_shn->seek_header.data,SEEK_HEADER_SIGNATURE,strlen(SEEK_HEADER_SIGNATURE)) == 0)
|
||||||
|
{
|
||||||
|
if (this_shn->seek_header.shnFileSize != this_shn->wave_header.actual_size)
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "warning: Seek table expected .shn file size %lu differs from actual .shn file size %lu - seek table might not belong to this file",
|
||||||
|
this_shn->seek_header.shnFileSize,this_shn->wave_header.actual_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this_shn->seek_table = malloc(seek_table_len)))
|
||||||
|
{
|
||||||
|
if (fread((void *)this_shn->seek_table,1,seek_table_len,f) == seek_table_len)
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "Successfully loaded seek table in separate file: '%s'",filename);
|
||||||
|
|
||||||
|
this_shn->vars.seek_table_entries = seek_table_len / SEEK_ENTRY_SIZE;
|
||||||
|
|
||||||
|
if (this_shn->vars.seek_table_entries > 1)
|
||||||
|
this_shn->vars.seek_resolution = shn_uchar_to_ulong_le(this_shn->seek_table->data+SEEK_ENTRY_SIZE);
|
||||||
|
else
|
||||||
|
this_shn->vars.seek_resolution = SEEK_RESOLUTION;
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_appended_seek_table(shn_file *this_shn,char *filename,long bytes_from_end)
|
||||||
|
{
|
||||||
|
switch (bytes_from_end)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
shn_debug(this_shn->config, "Looking for seek table appended to file: '%s'",filename);
|
||||||
|
break;
|
||||||
|
case ID3V1_TAG_SIZE:
|
||||||
|
shn_debug(this_shn->config, "Looking for seek table hidden behind an ID3v1 tag at the end of file: '%s'",filename);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shn_debug(this_shn->config, "Looking for seek table located %ld bytes from the end of file: '%s'",bytes_from_end,filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(this_shn->vars.fd,-(SEEK_TRAILER_SIZE+bytes_from_end),SEEK_END);
|
||||||
|
if (fread((void *)this_shn->seek_trailer.data,1,SEEK_TRAILER_SIZE,this_shn->vars.fd) == SEEK_TRAILER_SIZE)
|
||||||
|
{
|
||||||
|
this_shn->seek_trailer.seekTableSize = shn_uchar_to_ulong_le(this_shn->seek_trailer.data);
|
||||||
|
if (memcmp(this_shn->seek_trailer.data+4,SEEK_TRAILER_SIGNATURE,strlen(SEEK_TRAILER_SIGNATURE)) == 0)
|
||||||
|
{
|
||||||
|
fseek(this_shn->vars.fd,-(this_shn->seek_trailer.seekTableSize+bytes_from_end),SEEK_END);
|
||||||
|
this_shn->seek_trailer.seekTableSize -= (SEEK_HEADER_SIZE + SEEK_TRAILER_SIZE);
|
||||||
|
if (fread((void *)this_shn->seek_header.data,1,SEEK_HEADER_SIZE,this_shn->vars.fd) == SEEK_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
this_shn->seek_header.version = (slong)shn_uchar_to_ulong_le(this_shn->seek_header.data+4);
|
||||||
|
this_shn->seek_header.shnFileSize = shn_uchar_to_ulong_le(this_shn->seek_header.data+8);
|
||||||
|
if ((this_shn->seek_table = malloc(this_shn->seek_trailer.seekTableSize)))
|
||||||
|
{
|
||||||
|
if (fread((void *)this_shn->seek_table,1,this_shn->seek_trailer.seekTableSize,this_shn->vars.fd) == this_shn->seek_trailer.seekTableSize)
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "Successfully loaded seek table appended to file: '%s'",filename);
|
||||||
|
|
||||||
|
this_shn->vars.seek_table_entries = this_shn->seek_trailer.seekTableSize / SEEK_ENTRY_SIZE;
|
||||||
|
|
||||||
|
if (this_shn->vars.seek_table_entries > 1)
|
||||||
|
this_shn->vars.seek_resolution = shn_uchar_to_ulong_le(this_shn->seek_table->data+SEEK_ENTRY_SIZE);
|
||||||
|
else
|
||||||
|
this_shn->vars.seek_resolution = SEEK_RESOLUTION;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_separate_seek_table_samedir(shn_file *this_shn,char *filename)
|
||||||
|
{
|
||||||
|
char *altfilename,*basefile,*basedir;
|
||||||
|
|
||||||
|
if (!(basefile = shn_get_base_filename(filename)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(basedir = shn_get_base_directory(filename)))
|
||||||
|
{
|
||||||
|
free(basefile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(altfilename = malloc(strlen(basedir)+strlen(basefile)+sizeof(SEEK_SUFFIX)+3)))
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "Could not allocate memory for same dir filename");
|
||||||
|
free(basefile);
|
||||||
|
free(basedir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(altfilename,"%s/%s.%s",basedir,basefile,SEEK_SUFFIX);
|
||||||
|
|
||||||
|
free(basefile);
|
||||||
|
free(basedir);
|
||||||
|
|
||||||
|
if (load_separate_seek_table_generic(altfilename,this_shn))
|
||||||
|
{
|
||||||
|
free(altfilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(altfilename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_separate_seek_table_relative(shn_file *this_shn,char *filename)
|
||||||
|
{
|
||||||
|
char *altfilename,*basefile,*basedir;
|
||||||
|
/* Checking if this_shn->config.relative_seek_tables_path is NULL */
|
||||||
|
if(!(this_shn->config.relative_seek_tables_path))
|
||||||
|
this_shn->config.relative_seek_tables_path = "";
|
||||||
|
|
||||||
|
if (0 == strcmp(this_shn->config.relative_seek_tables_path,""))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (!(basefile = shn_get_base_filename(filename)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(basedir = shn_get_base_directory(filename)))
|
||||||
|
{
|
||||||
|
free(basefile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(altfilename = malloc(strlen(basedir)+strlen(this_shn->config.relative_seek_tables_path)+strlen(basefile)+sizeof(SEEK_SUFFIX)+4)))
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "Could not allocate memory for absolute filename");
|
||||||
|
free(basefile);
|
||||||
|
free(basedir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(altfilename,"%s/%s/%s.%s",basedir,this_shn->config.relative_seek_tables_path,basefile,SEEK_SUFFIX);
|
||||||
|
|
||||||
|
free(basefile);
|
||||||
|
free(basedir);
|
||||||
|
|
||||||
|
if (load_separate_seek_table_generic(altfilename,this_shn))
|
||||||
|
{
|
||||||
|
free(altfilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(altfilename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_separate_seek_table_absolute(shn_file *this_shn,char *filename)
|
||||||
|
{
|
||||||
|
char *altfilename,*basefile;
|
||||||
|
/* Checking this_shn->config.seek_tables_path */
|
||||||
|
if(!(this_shn->config.seek_tables_path))
|
||||||
|
this_shn->config.seek_tables_path = "";
|
||||||
|
|
||||||
|
if (!(basefile = shn_get_base_filename(filename)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(altfilename = malloc(strlen(this_shn->config.seek_tables_path)+strlen(basefile)+sizeof(SEEK_SUFFIX)+3)))
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "Could not allocate memory for same dir filename");
|
||||||
|
free(basefile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(altfilename,"%s/%s.%s",this_shn->config.seek_tables_path,basefile,SEEK_SUFFIX);
|
||||||
|
|
||||||
|
free(basefile);
|
||||||
|
|
||||||
|
if (load_separate_seek_table_generic(altfilename,this_shn))
|
||||||
|
{
|
||||||
|
free(altfilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(altfilename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shn_load_seek_table(shn_file *this_shn,char *filename)
|
||||||
|
{
|
||||||
|
if (load_appended_seek_table(this_shn,filename,0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (load_appended_seek_table(this_shn,filename,ID3V1_TAG_SIZE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (load_separate_seek_table_samedir(this_shn,filename))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (load_separate_seek_table_relative(this_shn,filename))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (load_separate_seek_table_absolute(this_shn,filename))
|
||||||
|
return;
|
||||||
|
|
||||||
|
shn_debug(this_shn->config, "Could not find any seek tables");
|
||||||
|
}
|
54
Libraries/Shorten/Files/shorten/src/shorten.c
Normal file
54
Libraries/Shorten/Files/shorten/src/shorten.c
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
void init_offset(slong **offset,int nchan,int nblock,int ftype)
|
||||||
|
{
|
||||||
|
slong mean = 0;
|
||||||
|
int chan, i;
|
||||||
|
|
||||||
|
/* initialise offset */
|
||||||
|
switch(ftype)
|
||||||
|
{
|
||||||
|
case TYPE_AU1:
|
||||||
|
case TYPE_S8:
|
||||||
|
case TYPE_S16HL:
|
||||||
|
case TYPE_S16LH:
|
||||||
|
case TYPE_ULAW:
|
||||||
|
case TYPE_AU2:
|
||||||
|
case TYPE_AU3:
|
||||||
|
case TYPE_ALAW:
|
||||||
|
mean = 0;
|
||||||
|
break;
|
||||||
|
case TYPE_U8:
|
||||||
|
mean = 0x80;
|
||||||
|
break;
|
||||||
|
case TYPE_U16HL:
|
||||||
|
case TYPE_U16LH:
|
||||||
|
mean = 0x8000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown file type: %d", ftype);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(chan = 0; chan < nchan; chan++)
|
||||||
|
for(i = 0; i < nblock; i++)
|
||||||
|
offset[chan][i] = mean;
|
||||||
|
}
|
192
Libraries/Shorten/Files/shorten/src/sulawalaw.c
Normal file
192
Libraries/Shorten/Files/shorten/src/sulawalaw.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
int Sulaw2lineartab[] = {-32124, -31100, -30076, -29052, -28028, -27004,
|
||||||
|
-25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812,
|
||||||
|
-17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436,
|
||||||
|
-12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828,
|
||||||
|
-8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884,
|
||||||
|
-5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644,
|
||||||
|
-3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364,
|
||||||
|
-2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500,
|
||||||
|
-1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876,
|
||||||
|
-844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524,
|
||||||
|
-492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276,
|
||||||
|
-260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112,
|
||||||
|
-104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0,
|
||||||
|
32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908,
|
||||||
|
21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460,
|
||||||
|
13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340,
|
||||||
|
8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884,
|
||||||
|
5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516,
|
||||||
|
3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108,
|
||||||
|
1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308,
|
||||||
|
1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684,
|
||||||
|
652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308,
|
||||||
|
292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104,
|
||||||
|
96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0};
|
||||||
|
|
||||||
|
#ifndef Sulaw2linear
|
||||||
|
#ifdef __STDC__
|
||||||
|
int Sulaw2linear(uchar ulaw) {
|
||||||
|
#else
|
||||||
|
int Sulaw2linear(ulaw) uchar ulaw; {
|
||||||
|
#endif
|
||||||
|
return(Sulaw2lineartab[ulaw]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* adapted by ajr for int input */
|
||||||
|
#ifdef __STDC__
|
||||||
|
uchar Slinear2ulaw(int sample) {
|
||||||
|
#else
|
||||||
|
uchar Slinear2ulaw(sample) int sample; {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
** This routine converts from linear to ulaw.
|
||||||
|
**
|
||||||
|
** Craig Reese: IDA/Supercomputing Research Center
|
||||||
|
** Joe Campbell: Department of Defense
|
||||||
|
** 29 September 1989
|
||||||
|
**
|
||||||
|
** References:
|
||||||
|
** 1) CCITT Recommendation G.711 (very difficult to follow)
|
||||||
|
** 2) "A New Digital Technique for Implementation of Any
|
||||||
|
** Continuous PCM Companding Law," Villeret, Michel,
|
||||||
|
** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
|
||||||
|
** 1973, pg. 11.12-11.17
|
||||||
|
** 3) MIL-STD-188-113,"Interoperability and Performance Standards
|
||||||
|
** for Analog-to_Digital Conversion Techniques,"
|
||||||
|
** 17 February 1987
|
||||||
|
**
|
||||||
|
** Input: Signed 16 bit linear sample
|
||||||
|
** Output: 8 bit ulaw sample
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
|
||||||
|
#define CLIP 32635
|
||||||
|
|
||||||
|
static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
|
||||||
|
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||||
|
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||||
|
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
|
||||||
|
int sign, exponent, mantissa;
|
||||||
|
uchar ulawbyte;
|
||||||
|
|
||||||
|
/* Get the sample into sign-magnitude. */
|
||||||
|
if(sample < 0) {
|
||||||
|
sign = 0x80;
|
||||||
|
sample = -sample;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sign = 0;
|
||||||
|
|
||||||
|
/* clip the magnitude */
|
||||||
|
if(sample > CLIP) sample = CLIP;
|
||||||
|
|
||||||
|
/* Convert from 16 bit linear to ulaw. */
|
||||||
|
sample = sample + BIAS;
|
||||||
|
exponent = exp_lut[( sample >> 7 ) & 0xFF];
|
||||||
|
mantissa = (sample >> (exponent + 3)) & 0x0F;
|
||||||
|
ulawbyte = ~(sign | (exponent << 4) | mantissa);
|
||||||
|
|
||||||
|
return(ulawbyte);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* ALAW starts here
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Salaw2lineartab[] = {-5504, -5248, -6016, -5760, -4480, -4224,
|
||||||
|
-4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
|
||||||
|
-2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648,
|
||||||
|
-4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064,
|
||||||
|
-23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256,
|
||||||
|
-31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032,
|
||||||
|
-11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616,
|
||||||
|
-13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264,
|
||||||
|
-312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72,
|
||||||
|
-120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136,
|
||||||
|
-184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
|
||||||
|
-1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656,
|
||||||
|
-752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816,
|
||||||
|
-784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
|
||||||
|
7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008,
|
||||||
|
2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136,
|
||||||
|
3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
|
||||||
|
30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496,
|
||||||
|
12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616,
|
||||||
|
13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296,
|
||||||
|
472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56,
|
||||||
|
40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440,
|
||||||
|
1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760,
|
||||||
|
1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976,
|
||||||
|
816, 784, 880, 848};
|
||||||
|
|
||||||
|
#ifndef Salaw2linear
|
||||||
|
#ifdef __STDC__
|
||||||
|
int Salaw2linear(uchar alaw) {
|
||||||
|
#else
|
||||||
|
int Salaw2linear(alaw) uchar alaw; {
|
||||||
|
#endif
|
||||||
|
return(Salaw2lineartab[alaw]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this is derived from the Sun code - it is a bit simpler and has int input */
|
||||||
|
#define QUANT_MASK (0xf) /* Quantization field mask. */
|
||||||
|
#define NSEGS (8) /* Number of A-law segments. */
|
||||||
|
#define SEG_SHIFT (4) /* Left shift for segment number. */
|
||||||
|
#ifdef __STDC__
|
||||||
|
uchar Slinear2alaw(int linear) {
|
||||||
|
#else
|
||||||
|
uchar Slinear2alaw(linear) int linear; {
|
||||||
|
#endif
|
||||||
|
int seg;
|
||||||
|
uchar aval, mask;
|
||||||
|
static sshort seg_aend[NSEGS] = {0x1f,0x3f,0x7f,0xff,0x1ff,0x3ff,0x7ff,0xfff};
|
||||||
|
|
||||||
|
linear = linear >> 3;
|
||||||
|
|
||||||
|
if(linear >= 0) {
|
||||||
|
mask = 0xd5; /* sign (7th) bit = 1 */
|
||||||
|
} else {
|
||||||
|
mask = 0x55; /* sign bit = 0 */
|
||||||
|
linear = -linear - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the scaled magnitude to segment number. */
|
||||||
|
for(seg = 0; seg < NSEGS && linear > seg_aend[seg]; seg++);
|
||||||
|
|
||||||
|
/* Combine the sign, segment, and quantization bits. */
|
||||||
|
if(seg >= NSEGS) /* out of range, return maximum value. */
|
||||||
|
return (uchar) (0x7F ^ mask);
|
||||||
|
else {
|
||||||
|
aval = (uchar) seg << SEG_SHIFT;
|
||||||
|
if (seg < 2)
|
||||||
|
aval |= (linear >> 1) & QUANT_MASK;
|
||||||
|
else
|
||||||
|
aval |= (linear >> seg) & QUANT_MASK;
|
||||||
|
return (aval ^ mask);
|
||||||
|
}
|
||||||
|
}
|
146
Libraries/Shorten/Files/shorten/src/vario.c
Normal file
146
Libraries/Shorten/Files/shorten/src/vario.c
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
#define MASKTABSIZE 33
|
||||||
|
ulong masktab[MASKTABSIZE];
|
||||||
|
|
||||||
|
void mkmasktab() {
|
||||||
|
int i;
|
||||||
|
ulong val = 0;
|
||||||
|
|
||||||
|
masktab[0] = val;
|
||||||
|
for(i = 1; i < MASKTABSIZE; i++) {
|
||||||
|
val <<= 1;
|
||||||
|
val |= 1;
|
||||||
|
masktab[i] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void var_get_init(shn_file *this_shn)
|
||||||
|
{
|
||||||
|
mkmasktab();
|
||||||
|
|
||||||
|
this_shn->decode_state->getbuf = (uchar*) pmalloc((ulong) BUFSIZ,this_shn);
|
||||||
|
this_shn->decode_state->getbufp = this_shn->decode_state->getbuf;
|
||||||
|
this_shn->decode_state->nbyteget = 0;
|
||||||
|
this_shn->decode_state->gbuffer = 0;
|
||||||
|
this_shn->decode_state->nbitget = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong word_get(shn_file *this_shn)
|
||||||
|
{
|
||||||
|
ulong buffer;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
if(this_shn->decode_state->nbyteget < 4)
|
||||||
|
{
|
||||||
|
this_shn->vars.last_file_position = this_shn->vars.bytes_read;
|
||||||
|
|
||||||
|
bytes = fread((uchar*) this_shn->decode_state->getbuf, 1, BUFSIZ, this_shn->vars.fd);
|
||||||
|
this_shn->decode_state->nbyteget += bytes;
|
||||||
|
|
||||||
|
if(this_shn->decode_state->nbyteget < 4) {
|
||||||
|
shn_error_fatal(this_shn,"Premature EOF on compressed stream -\npossible corrupt or truncated file");
|
||||||
|
return (ulong)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_shn->vars.bytes_read += bytes;
|
||||||
|
|
||||||
|
this_shn->decode_state->getbufp = this_shn->decode_state->getbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = (((slong) (this_shn->decode_state->getbufp[0])) << 24) | (((slong) (this_shn->decode_state->getbufp[1])) << 16) |
|
||||||
|
(((slong) (this_shn->decode_state->getbufp[2])) << 8) | ((slong) (this_shn->decode_state->getbufp[3]));
|
||||||
|
|
||||||
|
this_shn->decode_state->getbufp += 4;
|
||||||
|
this_shn->decode_state->nbyteget -= 4;
|
||||||
|
|
||||||
|
return(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
slong uvar_get(int nbin,shn_file *this_shn)
|
||||||
|
{
|
||||||
|
slong result;
|
||||||
|
|
||||||
|
if (this_shn->vars.reading_function_code) {
|
||||||
|
this_shn->vars.last_file_position_no_really = this_shn->vars.last_file_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this_shn->decode_state->nbitget == 0)
|
||||||
|
{
|
||||||
|
this_shn->decode_state->gbuffer = word_get(this_shn);
|
||||||
|
if (this_shn->vars.fatal_error)
|
||||||
|
return (ulong)0;
|
||||||
|
this_shn->decode_state->nbitget = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(result = 0; !(this_shn->decode_state->gbuffer & (1L << --(this_shn->decode_state->nbitget))); result++)
|
||||||
|
{
|
||||||
|
if(this_shn->decode_state->nbitget == 0)
|
||||||
|
{
|
||||||
|
this_shn->decode_state->gbuffer = word_get(this_shn);
|
||||||
|
if (this_shn->vars.fatal_error)
|
||||||
|
return (ulong)0;
|
||||||
|
this_shn->decode_state->nbitget = 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(nbin != 0)
|
||||||
|
{
|
||||||
|
if(this_shn->decode_state->nbitget >= nbin)
|
||||||
|
{
|
||||||
|
result = (result << nbin) | ((this_shn->decode_state->gbuffer >> (this_shn->decode_state->nbitget-nbin)) &masktab[nbin]);
|
||||||
|
this_shn->decode_state->nbitget -= nbin;
|
||||||
|
nbin = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (result << this_shn->decode_state->nbitget) | (this_shn->decode_state->gbuffer & masktab[this_shn->decode_state->nbitget]);
|
||||||
|
this_shn->decode_state->gbuffer = word_get(this_shn);
|
||||||
|
if (this_shn->vars.fatal_error)
|
||||||
|
return (ulong)0;
|
||||||
|
nbin -= this_shn->decode_state->nbitget;
|
||||||
|
this_shn->decode_state->nbitget = 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong ulong_get(shn_file *this_shn)
|
||||||
|
{
|
||||||
|
unsigned int nbit = uvar_get(ULONGSIZE,this_shn);
|
||||||
|
if (this_shn->vars.fatal_error)
|
||||||
|
return (ulong)0;
|
||||||
|
return(uvar_get(nbit,this_shn));
|
||||||
|
}
|
||||||
|
|
||||||
|
slong var_get(int nbin,shn_file *this_shn)
|
||||||
|
{
|
||||||
|
ulong uvar = uvar_get(nbin + 1,this_shn);
|
||||||
|
if (this_shn->vars.fatal_error)
|
||||||
|
return (slong)0;
|
||||||
|
|
||||||
|
if(uvar & 1) return((slong) ~(uvar >> 1));
|
||||||
|
else return((slong) (uvar >> 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void var_get_quit(shn_file *this_shn)
|
||||||
|
{
|
||||||
|
free((void *) this_shn->decode_state->getbuf);
|
||||||
|
this_shn->decode_state->getbuf = NULL;
|
||||||
|
}
|
267
Libraries/Shorten/Files/shorten/src/wave.c
Normal file
267
Libraries/Shorten/Files/shorten/src/wave.c
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
/* wave.c - functions to parse and verify WAVE headers
|
||||||
|
* Copyright (C) 2000-2004 Jason Jordan <shnutils@freeshell.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "shorten.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//int is_valid_file(shn_file *info)
|
||||||
|
/* determines whether the given filename (info->filename) is a regular file, and is readable */
|
||||||
|
/*{
|
||||||
|
struct stat sz;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (0 != stat(info->wave_header.filename,&sz)) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
shn_error("cannot open '%s' because it does not exist",info->wave_header.filename);
|
||||||
|
else if (errno == EACCES)
|
||||||
|
shn_error("cannot open '%s' due to insufficient permissions",info->wave_header.filename);
|
||||||
|
else if (errno == EFAULT)
|
||||||
|
shn_error("cannot open '%s' due to bad address",info->wave_header.filename);
|
||||||
|
else if (errno == ENOMEM)
|
||||||
|
shn_error("cannot open '%s' because the kernel ran out of memory",info->wave_header.filename);
|
||||||
|
else if (errno == ENAMETOOLONG)
|
||||||
|
shn_error("cannot open '%s' because the file name is too long",info->wave_header.filename);
|
||||||
|
else
|
||||||
|
shn_error("cannot open '%s' due to an unknown problem",info->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (0 == S_ISREG(sz.st_mode)) {
|
||||||
|
if (S_ISLNK(sz.st_mode))
|
||||||
|
shn_error("'%s' is a symbolic link, not a regular file",info->wave_header.filename);
|
||||||
|
else if (S_ISDIR(sz.st_mode))
|
||||||
|
shn_error("'%s' is a directory, not a regular file",info->wave_header.filename);
|
||||||
|
else if (S_ISCHR(sz.st_mode))
|
||||||
|
shn_error("'%s' is a character device, not a regular file",info->wave_header.filename);
|
||||||
|
else if (S_ISBLK(sz.st_mode))
|
||||||
|
shn_error("'%s' is a block device, not a regular file",info->wave_header.filename);
|
||||||
|
else if (S_ISFIFO(sz.st_mode))
|
||||||
|
shn_error("'%s' is a fifo, not a regular file",info->wave_header.filename);
|
||||||
|
else if (S_ISSOCK(sz.st_mode))
|
||||||
|
shn_error("'%s' is a socket, not a regular file",info->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info->wave_header.actual_size = (ulong)sz.st_size;
|
||||||
|
|
||||||
|
if (NULL == (f = fopen(info->wave_header.filename,"rb"))) {
|
||||||
|
shn_error("could not open '%s': %s",info->wave_header.filename,strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int shn_verify_header(shn_file *this_shn)
|
||||||
|
{
|
||||||
|
ulong l;
|
||||||
|
int cur = 0;
|
||||||
|
|
||||||
|
/* if (0 == is_valid_file(this_shn))
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': something went wrong while opening this file, see above",this_shn->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (this_shn->vars.bytes_in_header < CANONICAL_HEADER_SIZE) {
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': header is only %d bytes (should be at least %d bytes)",
|
||||||
|
this_shn->wave_header.filename,this_shn->vars.bytes_in_header,CANONICAL_HEADER_SIZE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WAVE_RIFF != shn_uchar_to_ulong_le(this_shn->vars.header+cur))
|
||||||
|
{
|
||||||
|
if (AIFF_FORM == shn_uchar_to_ulong_le(this_shn->vars.header+cur))
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': file contains AIFF data, which is currently not supported",this_shn->wave_header.filename);
|
||||||
|
else
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': WAVE header is missing RIFF tag - possible corrupt file",this_shn->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
this_shn->wave_header.chunk_size = shn_uchar_to_ulong_le(this_shn->vars.header+cur);
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
if (WAVE_WAVE != shn_uchar_to_ulong_le(this_shn->vars.header+cur))
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': WAVE header is missing WAVE tag",this_shn->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
l = shn_uchar_to_ulong_le(this_shn->vars.header+cur);
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
if (WAVE_FMT == shn_uchar_to_ulong_le(this_shn->vars.header+cur-8))
|
||||||
|
break;
|
||||||
|
|
||||||
|
cur += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l < 16)
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': fmt chunk in WAVE header was too short",this_shn->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_shn->wave_header.wave_format = shn_uchar_to_ushort_le(this_shn->vars.header+cur);
|
||||||
|
cur += 2;
|
||||||
|
|
||||||
|
switch (this_shn->wave_header.wave_format)
|
||||||
|
{
|
||||||
|
case WAVE_FORMAT_PCM:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': unsupported format 0x%04x (%s) - only PCM data is supported at this time",
|
||||||
|
this_shn->wave_header.filename,this_shn->wave_header.wave_format,shn_format_to_str(this_shn->wave_header.wave_format));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_shn->wave_header.channels = shn_uchar_to_ushort_le(this_shn->vars.header+cur);
|
||||||
|
cur += 2;
|
||||||
|
this_shn->wave_header.samples_per_sec = shn_uchar_to_ulong_le(this_shn->vars.header+cur);
|
||||||
|
cur += 4;
|
||||||
|
this_shn->wave_header.avg_bytes_per_sec = shn_uchar_to_ulong_le(this_shn->vars.header+cur);
|
||||||
|
cur += 4;
|
||||||
|
this_shn->wave_header.block_align = shn_uchar_to_ushort_le(this_shn->vars.header+cur);
|
||||||
|
cur += 2;
|
||||||
|
this_shn->wave_header.bits_per_sample = shn_uchar_to_ushort_le(this_shn->vars.header+cur);
|
||||||
|
cur += 2;
|
||||||
|
|
||||||
|
if (this_shn->wave_header.bits_per_sample != 8 && this_shn->wave_header.bits_per_sample != 16)
|
||||||
|
{
|
||||||
|
shn_debug(this_shn->config, "while processing '%s': bits per sample is neither 8 nor 16",this_shn->wave_header.filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
l -= 16;
|
||||||
|
|
||||||
|
if (l > 0)
|
||||||
|
cur += l;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
l = shn_uchar_to_ulong_le(this_shn->vars.header+cur);
|
||||||
|
cur += 4;
|
||||||
|
|
||||||
|
if (WAVE_DATA == shn_uchar_to_ulong_le(this_shn->vars.header+cur-8))
|
||||||
|
break;
|
||||||
|
|
||||||
|
cur += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_shn->wave_header.rate = ((uint)this_shn->wave_header.samples_per_sec *
|
||||||
|
(uint)this_shn->wave_header.channels *
|
||||||
|
(uint)this_shn->wave_header.bits_per_sample) / 8;
|
||||||
|
this_shn->wave_header.header_size = cur;
|
||||||
|
this_shn->wave_header.data_size = l;
|
||||||
|
this_shn->wave_header.total_size = this_shn->wave_header.chunk_size + 8;
|
||||||
|
this_shn->wave_header.length = this_shn->wave_header.data_size / this_shn->wave_header.rate;
|
||||||
|
this_shn->wave_header.exact_length = (double)this_shn->wave_header.data_size / (double)this_shn->wave_header.rate;
|
||||||
|
|
||||||
|
if (this_shn->wave_header.channels == CD_CHANNELS &&
|
||||||
|
this_shn->wave_header.bits_per_sample == CD_BITS_PER_SAMPLE &&
|
||||||
|
this_shn->wave_header.samples_per_sec == CD_SAMPLES_PER_SEC &&
|
||||||
|
this_shn->wave_header.avg_bytes_per_sec == CD_RATE &&
|
||||||
|
this_shn->wave_header.rate == CD_RATE)
|
||||||
|
{
|
||||||
|
if (this_shn->wave_header.data_size < CD_MIN_BURNABLE_SIZE)
|
||||||
|
this_shn->wave_header.problems |= PROBLEM_CD_BUT_TOO_SHORT;
|
||||||
|
if (this_shn->wave_header.data_size % CD_BLOCK_SIZE != 0)
|
||||||
|
this_shn->wave_header.problems |= PROBLEM_CD_BUT_BAD_BOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this_shn->wave_header.problems |= PROBLEM_NOT_CD_QUALITY;
|
||||||
|
|
||||||
|
if (this_shn->wave_header.header_size != CANONICAL_HEADER_SIZE)
|
||||||
|
this_shn->wave_header.problems |= PROBLEM_HEADER_NOT_CANONICAL;
|
||||||
|
|
||||||
|
if ((ulong)this_shn->wave_header.header_size + this_shn->wave_header.data_size > this_shn->wave_header.total_size)
|
||||||
|
this_shn->wave_header.problems |= PROBLEM_HEADER_INCONSISTENT;
|
||||||
|
|
||||||
|
if ((ulong)this_shn->wave_header.header_size + this_shn->wave_header.data_size < this_shn->wave_header.total_size)
|
||||||
|
this_shn->wave_header.problems |= PROBLEM_EXTRA_CHUNKS;
|
||||||
|
|
||||||
|
shn_length_to_str(this_shn);
|
||||||
|
|
||||||
|
/* header looks ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *shn_format_to_str(ushort format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case WAVE_FORMAT_UNKNOWN:
|
||||||
|
return "Microsoft Official Unknown";
|
||||||
|
case WAVE_FORMAT_PCM:
|
||||||
|
return "Microsoft PCM";
|
||||||
|
case WAVE_FORMAT_ADPCM:
|
||||||
|
return "Microsoft ADPCM";
|
||||||
|
case WAVE_FORMAT_IEEE_FLOAT:
|
||||||
|
return "IEEE Float";
|
||||||
|
case WAVE_FORMAT_ALAW:
|
||||||
|
return "Microsoft A-law";
|
||||||
|
case WAVE_FORMAT_MULAW:
|
||||||
|
return "Microsoft U-law";
|
||||||
|
case WAVE_FORMAT_OKI_ADPCM:
|
||||||
|
return "OKI ADPCM format";
|
||||||
|
case WAVE_FORMAT_IMA_ADPCM:
|
||||||
|
return "IMA ADPCM";
|
||||||
|
case WAVE_FORMAT_DIGISTD:
|
||||||
|
return "Digistd format";
|
||||||
|
case WAVE_FORMAT_DIGIFIX:
|
||||||
|
return "Digifix format";
|
||||||
|
case WAVE_FORMAT_DOLBY_AC2:
|
||||||
|
return "Dolby AC2";
|
||||||
|
case WAVE_FORMAT_GSM610:
|
||||||
|
return "GSM 6.10";
|
||||||
|
case WAVE_FORMAT_ROCKWELL_ADPCM:
|
||||||
|
return "Rockwell ADPCM";
|
||||||
|
case WAVE_FORMAT_ROCKWELL_DIGITALK:
|
||||||
|
return "Rockwell DIGITALK";
|
||||||
|
case WAVE_FORMAT_G721_ADPCM:
|
||||||
|
return "G.721 ADPCM";
|
||||||
|
case WAVE_FORMAT_G728_CELP:
|
||||||
|
return "G.728 CELP";
|
||||||
|
case WAVE_FORMAT_MPEG:
|
||||||
|
return "MPEG";
|
||||||
|
case WAVE_FORMAT_MPEGLAYER3:
|
||||||
|
return "MPEG Layer 3";
|
||||||
|
case WAVE_FORMAT_G726_ADPCM:
|
||||||
|
return "G.726 ADPCM";
|
||||||
|
case WAVE_FORMAT_G722_ADPCM:
|
||||||
|
return "G.722 ADPCM";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
5
Libraries/Shorten/Files/shorten/util/Makefile.am
Normal file
5
Libraries/Shorten/Files/shorten/util/Makefile.am
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
noinst_PROGRAMS = mkbshift
|
||||||
|
|
||||||
|
mkbshift_SOURCES = Sulawalaw.c array.c exit.c mkbshift.c
|
||||||
|
|
||||||
|
EXTRA_DIST = mkbshift.h
|
192
Libraries/Shorten/Files/shorten/util/Sulawalaw.c
Normal file
192
Libraries/Shorten/Files/shorten/util/Sulawalaw.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "mkbshift.h"
|
||||||
|
|
||||||
|
int Sulaw2lineartab[] = {-32124, -31100, -30076, -29052, -28028, -27004,
|
||||||
|
-25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812,
|
||||||
|
-17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436,
|
||||||
|
-12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828,
|
||||||
|
-8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884,
|
||||||
|
-5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644,
|
||||||
|
-3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364,
|
||||||
|
-2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500,
|
||||||
|
-1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876,
|
||||||
|
-844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524,
|
||||||
|
-492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276,
|
||||||
|
-260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112,
|
||||||
|
-104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0,
|
||||||
|
32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908,
|
||||||
|
21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460,
|
||||||
|
13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340,
|
||||||
|
8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884,
|
||||||
|
5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516,
|
||||||
|
3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108,
|
||||||
|
1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308,
|
||||||
|
1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684,
|
||||||
|
652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308,
|
||||||
|
292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104,
|
||||||
|
96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0};
|
||||||
|
|
||||||
|
#ifndef Sulaw2linear
|
||||||
|
#ifdef __STDC__
|
||||||
|
int Sulaw2linear(uchar ulaw) {
|
||||||
|
#else
|
||||||
|
int Sulaw2linear(ulaw) uchar ulaw; {
|
||||||
|
#endif
|
||||||
|
return(Sulaw2lineartab[ulaw]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* adapted by ajr for int input */
|
||||||
|
#ifdef __STDC__
|
||||||
|
uchar Slinear2ulaw(int sample) {
|
||||||
|
#else
|
||||||
|
uchar Slinear2ulaw(sample) int sample; {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
** This routine converts from linear to ulaw.
|
||||||
|
**
|
||||||
|
** Craig Reese: IDA/Supercomputing Research Center
|
||||||
|
** Joe Campbell: Department of Defense
|
||||||
|
** 29 September 1989
|
||||||
|
**
|
||||||
|
** References:
|
||||||
|
** 1) CCITT Recommendation G.711 (very difficult to follow)
|
||||||
|
** 2) "A New Digital Technique for Implementation of Any
|
||||||
|
** Continuous PCM Companding Law," Villeret, Michel,
|
||||||
|
** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
|
||||||
|
** 1973, pg. 11.12-11.17
|
||||||
|
** 3) MIL-STD-188-113,"Interoperability and Performance Standards
|
||||||
|
** for Analog-to_Digital Conversion Techniques,"
|
||||||
|
** 17 February 1987
|
||||||
|
**
|
||||||
|
** Input: Signed 16 bit linear sample
|
||||||
|
** Output: 8 bit ulaw sample
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
|
||||||
|
#define CLIP 32635
|
||||||
|
|
||||||
|
static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
|
||||||
|
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||||
|
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||||
|
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
|
||||||
|
int sign, exponent, mantissa;
|
||||||
|
uchar ulawbyte;
|
||||||
|
|
||||||
|
/* Get the sample into sign-magnitude. */
|
||||||
|
if(sample < 0) {
|
||||||
|
sign = 0x80;
|
||||||
|
sample = -sample;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sign = 0;
|
||||||
|
|
||||||
|
/* clip the magnitude */
|
||||||
|
if(sample > CLIP) sample = CLIP;
|
||||||
|
|
||||||
|
/* Convert from 16 bit linear to ulaw. */
|
||||||
|
sample = sample + BIAS;
|
||||||
|
exponent = exp_lut[( sample >> 7 ) & 0xFF];
|
||||||
|
mantissa = (sample >> (exponent + 3)) & 0x0F;
|
||||||
|
ulawbyte = ~(sign | (exponent << 4) | mantissa);
|
||||||
|
|
||||||
|
return(ulawbyte);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* ALAW starts here
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Salaw2lineartab[] = {-5504, -5248, -6016, -5760, -4480, -4224,
|
||||||
|
-4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
|
||||||
|
-2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648,
|
||||||
|
-4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064,
|
||||||
|
-23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256,
|
||||||
|
-31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032,
|
||||||
|
-11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616,
|
||||||
|
-13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264,
|
||||||
|
-312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72,
|
||||||
|
-120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136,
|
||||||
|
-184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
|
||||||
|
-1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656,
|
||||||
|
-752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816,
|
||||||
|
-784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
|
||||||
|
7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008,
|
||||||
|
2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136,
|
||||||
|
3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
|
||||||
|
30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496,
|
||||||
|
12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616,
|
||||||
|
13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296,
|
||||||
|
472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56,
|
||||||
|
40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440,
|
||||||
|
1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760,
|
||||||
|
1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976,
|
||||||
|
816, 784, 880, 848};
|
||||||
|
|
||||||
|
#ifndef Salaw2linear
|
||||||
|
#ifdef __STDC__
|
||||||
|
int Salaw2linear(uchar alaw) {
|
||||||
|
#else
|
||||||
|
int Salaw2linear(alaw) uchar alaw; {
|
||||||
|
#endif
|
||||||
|
return(Salaw2lineartab[alaw]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this is derived from the Sun code - it is a bit simpler and has int input */
|
||||||
|
#define QUANT_MASK (0xf) /* Quantization field mask. */
|
||||||
|
#define NSEGS (8) /* Number of A-law segments. */
|
||||||
|
#define SEG_SHIFT (4) /* Left shift for segment number. */
|
||||||
|
#ifdef __STDC__
|
||||||
|
uchar Slinear2alaw(int linear) {
|
||||||
|
#else
|
||||||
|
uchar Slinear2alaw(linear) int linear; {
|
||||||
|
#endif
|
||||||
|
int seg;
|
||||||
|
uchar aval, mask;
|
||||||
|
static sshort seg_aend[NSEGS] = {0x1f,0x3f,0x7f,0xff,0x1ff,0x3ff,0x7ff,0xfff};
|
||||||
|
|
||||||
|
linear = linear >> 3;
|
||||||
|
|
||||||
|
if(linear >= 0) {
|
||||||
|
mask = 0xd5; /* sign (7th) bit = 1 */
|
||||||
|
} else {
|
||||||
|
mask = 0x55; /* sign bit = 0 */
|
||||||
|
linear = -linear - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the scaled magnitude to segment number. */
|
||||||
|
for(seg = 0; seg < NSEGS && linear > seg_aend[seg]; seg++);
|
||||||
|
|
||||||
|
/* Combine the sign, segment, and quantization bits. */
|
||||||
|
if(seg >= NSEGS) /* out of range, return maximum value. */
|
||||||
|
return (uchar) (0x7F ^ mask);
|
||||||
|
else {
|
||||||
|
aval = (uchar) seg << SEG_SHIFT;
|
||||||
|
if (seg < 2)
|
||||||
|
aval |= (linear >> 1) & QUANT_MASK;
|
||||||
|
else
|
||||||
|
aval |= (linear >> seg) & QUANT_MASK;
|
||||||
|
return (aval ^ mask);
|
||||||
|
}
|
||||||
|
}
|
63
Libraries/Shorten/Files/shorten/util/array.c
Normal file
63
Libraries/Shorten/Files/shorten/util/array.c
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mkbshift.h"
|
||||||
|
|
||||||
|
void *pmalloc(size) ulong size; {
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
#if defined(DOS_MALLOC_FEATURE) && !defined(_WINDOWS) /* mrhmod */
|
||||||
|
fprintf(stderr, "requesting %ld bytes: ", size);
|
||||||
|
#endif
|
||||||
|
ptr = malloc(size);
|
||||||
|
#if defined(DOS_MALLOC_FEATURE) && !defined(_WINDOWS) /* mrhmod */
|
||||||
|
if(ptr == NULL)
|
||||||
|
fprintf(stderr, "denied\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "accepted\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(ptr == NULL)
|
||||||
|
perror_exit("call to malloc(%ld) failed in pmalloc()", size);
|
||||||
|
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
slong **long2d(n0, n1) ulong n0, n1; {
|
||||||
|
slong **array0;
|
||||||
|
|
||||||
|
if((array0 = (slong**) pmalloc((ulong) (n0 * sizeof(slong*) +
|
||||||
|
n0 * n1 * sizeof(slong)))) != NULL ) {
|
||||||
|
slong *array1 = (slong*) (array0 + n0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n0; i++)
|
||||||
|
array0[i] = array1 + i * n1;
|
||||||
|
}
|
||||||
|
return(array0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float **float2d(n0, n1) ulong n0, n1; {
|
||||||
|
float **array0;
|
||||||
|
|
||||||
|
if((array0 = (float**) pmalloc((ulong) (n0 * sizeof(float*) +
|
||||||
|
n0 * n1 * sizeof(float)))) != NULL ) {
|
||||||
|
float *array1 = (float*) (array0 + n0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n0; i++)
|
||||||
|
array0[i] = array1 + i * n1;
|
||||||
|
}
|
||||||
|
return(array0);
|
||||||
|
}
|
230
Libraries/Shorten/Files/shorten/util/exit.c
Normal file
230
Libraries/Shorten/Files/shorten/util/exit.c
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifndef MSDOS
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STDARG_H
|
||||||
|
#include <stdarg.h>
|
||||||
|
#else
|
||||||
|
#include <varargs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mkbshift.h"
|
||||||
|
|
||||||
|
extern char *argv0;
|
||||||
|
extern char *filenameo;
|
||||||
|
extern FILE *fileo;
|
||||||
|
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
/* mrhmod - warn about attempt to use stderr (use perror_exit()/error_exit() instead) */
|
||||||
|
char *stderrWarningMsg = "caught attempt to use stderr";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jmp_buf exitenv;
|
||||||
|
char *exitmessage;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
void basic_exit(exitcode) int exitcode; {
|
||||||
|
|
||||||
|
/* try to delete the output file on all abnormal exit conditions */
|
||||||
|
if(exitcode != 0 && fileo != NULL && fileo != stdout)
|
||||||
|
{
|
||||||
|
fclose(fileo);
|
||||||
|
unlink(filenameo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exitmessage == NULL)
|
||||||
|
exit(exitcode < 0 ? 0 : exitcode);
|
||||||
|
else
|
||||||
|
longjmp(exitenv, exitcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** error_exit() - standard error handler with printf() syntax
|
||||||
|
*/
|
||||||
|
# ifdef HAVE_STDARG_H
|
||||||
|
void error_exit(char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
# else
|
||||||
|
void error_exit(va_alist) va_dcl {
|
||||||
|
va_list args;
|
||||||
|
char *fmt;
|
||||||
|
|
||||||
|
va_start(args);
|
||||||
|
fmt = va_arg(args, char*);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if(exitmessage == NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
#if defined(_WINDOWS) && defined(_DEBUG) && !defined(WIN32)
|
||||||
|
_asm { int 3 } / * mrhmod - catch if debugging * /
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WINDOWS /* mrhmod - must use exitmessage 'cos stderr not available */
|
||||||
|
fprintf(stderr, "%s: ", argv0);
|
||||||
|
(void) vfprintf(stderr, fmt, args);
|
||||||
|
#endif /* _WINDOWS */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(void) vsprintf(exitmessage, fmt, args);
|
||||||
|
strcat(exitmessage, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
basic_exit(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** perror_exit() - system error handler with printf() syntax
|
||||||
|
**
|
||||||
|
** Appends system error message based on errno
|
||||||
|
*/
|
||||||
|
# ifdef HAVE_STDARG_H
|
||||||
|
void perror_exit(char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
# else
|
||||||
|
void perror_exit(va_alist) va_dcl {
|
||||||
|
va_list args;
|
||||||
|
char *fmt;
|
||||||
|
|
||||||
|
va_start(args);
|
||||||
|
fmt = va_arg(args, char*);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if(exitmessage == NULL) {
|
||||||
|
/*
|
||||||
|
#if defined(_WINDOWS) && defined(_DEBUG) && !defined(WIN32)
|
||||||
|
_asm { int 3 } / * mrhmod - catch if debugging * /
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WINDOWS /* mrhmod - must use exitmessage 'cos stderr not available */
|
||||||
|
fprintf(stderr, "%s: ", argv0);
|
||||||
|
(void) vfprintf(stderr, fmt, args);
|
||||||
|
(void) fprintf(stderr, ": ");
|
||||||
|
#ifndef MSDOS
|
||||||
|
perror("\0");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _WINDOWS */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(void) vsprintf(exitmessage, fmt, args);
|
||||||
|
strcat(exitmessage, ": ");
|
||||||
|
strcat(exitmessage,strerror(errno));
|
||||||
|
strcat(exitmessage, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
basic_exit(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef HAVE_STDARG_H
|
||||||
|
void usage_exit(int exitcode, char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
# else
|
||||||
|
void usage_exit(va_alist) va_dcl {
|
||||||
|
va_list args;
|
||||||
|
int exitcode;
|
||||||
|
char *fmt;
|
||||||
|
|
||||||
|
va_start(args);
|
||||||
|
exitcode = va_arg(args, int);
|
||||||
|
fmt = va_arg(args, char*);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if(exitmessage == NULL) {
|
||||||
|
#if defined(_WINDOWS) && defined(_DEBUG) && !defined(WIN32)
|
||||||
|
_asm { int 3 } /* mrhmod - catch if debugging */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WINDOWS /* mrhmod - must use exitmessage 'cos stderr not available */
|
||||||
|
if(fmt != NULL) {
|
||||||
|
fprintf(stderr, "%s: ", argv0);
|
||||||
|
(void) vfprintf(stderr, fmt, args);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s: for more information use: %s -h\n", argv0, argv0);
|
||||||
|
#endif /* _WINDOWS */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(void) vsprintf(exitmessage, fmt, args);
|
||||||
|
strcat(exitmessage, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
basic_exit(exitcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ifdef HAVE_STDARG_H
|
||||||
|
void update_exit(int exitcode, char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
# else
|
||||||
|
void update_exit(va_alist) va_dcl {
|
||||||
|
va_list args;
|
||||||
|
int exitcode;
|
||||||
|
char *fmt;
|
||||||
|
|
||||||
|
va_start(args);
|
||||||
|
exitcode = va_arg(args, int);
|
||||||
|
fmt = va_arg(args, char*);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if(exitmessage == NULL) {
|
||||||
|
#if defined(_WINDOWS) && defined(_DEBUG) && !defined(WIN32)
|
||||||
|
_asm { int 3 } /* mrhmod - catch if debugging */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WINDOWS /* mrhmod - must use exitmessage 'cos stderr not available */
|
||||||
|
if(fmt != NULL) {
|
||||||
|
fprintf(stderr, "%s: ", argv0);
|
||||||
|
(void) vfprintf(stderr, fmt, args);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s: version %s\n",argv0,VERSION);
|
||||||
|
fprintf(stderr, "%s: please report this problem to ajr@softsound.com\n", argv0);
|
||||||
|
#endif /* _WINDOWS */
|
||||||
|
}
|
||||||
|
#ifdef _WINDOWS /* mrhmod - output something */
|
||||||
|
error_exit( fmt, args );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
basic_exit(exitcode);
|
||||||
|
}
|
110
Libraries/Shorten/Files/shorten/util/mkbshift.c
Normal file
110
Libraries/Shorten/Files/shorten/util/mkbshift.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "mkbshift.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define USIZE 256
|
||||||
|
#define HUSIZE 128
|
||||||
|
#define SHIFTSIZE 13
|
||||||
|
|
||||||
|
char *argv0 = "mkbshift";
|
||||||
|
char *filenameo = NULL;
|
||||||
|
FILE *fileo = NULL;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
FILE *fout;
|
||||||
|
char *filename = "bitshift.h", *writemode = "w";
|
||||||
|
int shift, i;
|
||||||
|
int tab[USIZE];
|
||||||
|
slong sample;
|
||||||
|
slong **forwardmap = long2d((ulong) SHIFTSIZE, (ulong) USIZE);
|
||||||
|
slong **reversemap = long2d((ulong) SHIFTSIZE, (ulong) USIZE);
|
||||||
|
|
||||||
|
fout = fopen(filename, writemode);
|
||||||
|
if(fout == NULL)
|
||||||
|
perror_exit("fopen(\"%s\", \"%s\")", filename, writemode);
|
||||||
|
|
||||||
|
for(i = 0; i < USIZE; i++) tab[i] = 0;
|
||||||
|
|
||||||
|
/* brute force search of the largest number of zero bits in a linear value */
|
||||||
|
for(shift = 0; shift < SHIFTSIZE; shift++)
|
||||||
|
for(sample = -(1L << 15); sample < (1L << 15); sample += 1 << (shift + 3))
|
||||||
|
tab[Slinear2ulaw(sample)] = shift;
|
||||||
|
|
||||||
|
/* print this out as a lookup table */
|
||||||
|
fprintf(fout, "char ulaw_maxshift[%d] = {", USIZE);
|
||||||
|
for(i = 0; i < USIZE - 1; i++)
|
||||||
|
fprintf(fout, "%d,", tab[i]);
|
||||||
|
fprintf(fout, "%d};\n\n", tab[USIZE - 1]);
|
||||||
|
|
||||||
|
/* compute the greatest inward shift compatable with ??? */
|
||||||
|
for(shift = 0; shift < SHIFTSIZE; shift++) {
|
||||||
|
int nused;
|
||||||
|
|
||||||
|
nused = 0;
|
||||||
|
for(i = 255; i >= 128; i--)
|
||||||
|
if(tab[i] >= shift) forwardmap[shift][i] = nused++;
|
||||||
|
for(i = 255; i >= 128; i--)
|
||||||
|
if(tab[i] < shift) forwardmap[shift][i] = nused++;
|
||||||
|
|
||||||
|
nused = -1;
|
||||||
|
for(i = 126; i >= 0; i--)
|
||||||
|
if(tab[i] >= shift) forwardmap[shift][i] = nused--;
|
||||||
|
forwardmap[shift][127] = nused--;
|
||||||
|
for(i = 126; i >= 0; i--)
|
||||||
|
if(tab[i] < shift) forwardmap[shift][i] = nused--;
|
||||||
|
|
||||||
|
for(i = 0; i < USIZE; i++)
|
||||||
|
reversemap[shift][forwardmap[shift][i] + HUSIZE] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* simple check */
|
||||||
|
for(shift = 0; shift < SHIFTSIZE; shift++)
|
||||||
|
for(i = 0; i < USIZE; i++)
|
||||||
|
if(forwardmap[shift][reversemap[shift][i]] != i - HUSIZE)
|
||||||
|
error_exit("identity maping failed for shift: %d\tindex: %d\n",shift,i);
|
||||||
|
|
||||||
|
/* print out the ulaw_inward lookup table */
|
||||||
|
fprintf(fout, "schar ulaw_inward[%d][%d] = {\n", SHIFTSIZE, USIZE);
|
||||||
|
for(shift = 0; shift < SHIFTSIZE; shift++) {
|
||||||
|
fprintf(fout, "{");
|
||||||
|
for(i = 0; i < USIZE - 1; i++)
|
||||||
|
fprintf(fout, "%ld,", forwardmap[shift][i]);
|
||||||
|
if(shift != SHIFTSIZE - 1)
|
||||||
|
fprintf(fout, "%ld},\n", forwardmap[shift][USIZE - 1]);
|
||||||
|
else
|
||||||
|
fprintf(fout, "%ld}\n};\n", forwardmap[shift][USIZE - 1]);
|
||||||
|
}
|
||||||
|
fprintf(fout, "\n");
|
||||||
|
|
||||||
|
/* print out the ulaw_outward lookup table */
|
||||||
|
fprintf(fout, "uchar ulaw_outward[%d][%d] = {\n", SHIFTSIZE, USIZE);
|
||||||
|
for(shift = 0; shift < SHIFTSIZE; shift++) {
|
||||||
|
fprintf(fout, "{");
|
||||||
|
for(i = 0; i < USIZE - 1; i++)
|
||||||
|
fprintf(fout, "%ld,", reversemap[shift][i]);
|
||||||
|
if(shift != SHIFTSIZE - 1)
|
||||||
|
fprintf(fout, "%ld},\n", reversemap[shift][USIZE - 1]);
|
||||||
|
else
|
||||||
|
fprintf(fout, "%ld}\n};\n", reversemap[shift][USIZE - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fout);
|
||||||
|
|
||||||
|
/* exit happy */
|
||||||
|
return(0);
|
||||||
|
}
|
237
Libraries/Shorten/Files/shorten/util/mkbshift.h
Normal file
237
Libraries/Shorten/Files/shorten/util/mkbshift.h
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-1995 Tony Robinson *
|
||||||
|
* *
|
||||||
|
* See the file doc/LICENSE.shorten for conditions on distribution and usage *
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MKBSHIFT_H
|
||||||
|
#define _MKBSHIFT_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRERROR
|
||||||
|
extern char *sys_errlist[];
|
||||||
|
#define strerror(x) sys_errlist[x]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAGIC "ajkg"
|
||||||
|
#define FORMAT_VERSION 2
|
||||||
|
#define MIN_SUPPORTED_VERSION 1
|
||||||
|
#define MAX_SUPPORTED_VERSION 3
|
||||||
|
#define MAX_VERSION 7
|
||||||
|
|
||||||
|
#define UNDEFINED_UINT -1
|
||||||
|
#define DEFAULT_BLOCK_SIZE 256
|
||||||
|
#define DEFAULT_V0NMEAN 0
|
||||||
|
#define DEFAULT_V2NMEAN 4
|
||||||
|
#define DEFAULT_MAXNLPC 0
|
||||||
|
#define DEFAULT_NCHAN 1
|
||||||
|
#define DEFAULT_NSKIP 0
|
||||||
|
#define DEFAULT_NDISCARD 0
|
||||||
|
#define NBITPERLONG 32
|
||||||
|
#define DEFAULT_MINSNR 256
|
||||||
|
#define DEFAULT_MAXRESNSTR "32.0"
|
||||||
|
#define DEFAULT_QUANTERROR 0
|
||||||
|
#define MINBITRATE 2.5
|
||||||
|
|
||||||
|
#define MAX_LPC_ORDER 64
|
||||||
|
#define CHANSIZE 0
|
||||||
|
#define ENERGYSIZE 3
|
||||||
|
#define BITSHIFTSIZE 2
|
||||||
|
#define NWRAP 3
|
||||||
|
|
||||||
|
#define FNSIZE 2
|
||||||
|
#define FN_DIFF0 0
|
||||||
|
#define FN_DIFF1 1
|
||||||
|
#define FN_DIFF2 2
|
||||||
|
#define FN_DIFF3 3
|
||||||
|
#define FN_QUIT 4
|
||||||
|
#define FN_BLOCKSIZE 5
|
||||||
|
#define FN_BITSHIFT 6
|
||||||
|
#define FN_QLPC 7
|
||||||
|
#define FN_ZERO 8
|
||||||
|
#define FN_VERBATIM 9
|
||||||
|
|
||||||
|
#define VERBATIM_CKSIZE_SIZE 5 /* a var_put code size */
|
||||||
|
#define VERBATIM_BYTE_SIZE 8 /* code size 8 on single bytes means
|
||||||
|
* no compression at all */
|
||||||
|
#define VERBATIM_CHUNK_MAX 256 /* max. size of a FN_VERBATIM chunk */
|
||||||
|
|
||||||
|
#define ULONGSIZE 2
|
||||||
|
#define NSKIPSIZE 1
|
||||||
|
#define LPCQSIZE 2
|
||||||
|
#define LPCQUANT 5
|
||||||
|
#define XBYTESIZE 7
|
||||||
|
|
||||||
|
#define TYPESIZE 4
|
||||||
|
#define TYPE_AU1 0 /* original lossless ulaw */
|
||||||
|
#define TYPE_S8 1 /* signed 8 bit characters */
|
||||||
|
#define TYPE_U8 2 /* unsigned 8 bit characters */
|
||||||
|
#define TYPE_S16HL 3 /* signed 16 bit shorts: high-low */
|
||||||
|
#define TYPE_U16HL 4 /* unsigned 16 bit shorts: high-low */
|
||||||
|
#define TYPE_S16LH 5 /* signed 16 bit shorts: low-high */
|
||||||
|
#define TYPE_U16LH 6 /* unsigned 16 bit shorts: low-high */
|
||||||
|
#define TYPE_ULAW 7 /* lossy ulaw: internal conversion to linear */
|
||||||
|
#define TYPE_AU2 8 /* new ulaw with zero mapping */
|
||||||
|
#define TYPE_AU3 9 /* lossless alaw */
|
||||||
|
#define TYPE_ALAW 10 /* lossy alaw: internal conversion to linear */
|
||||||
|
#define TYPE_RIFF_WAVE 11 /* Microsoft .WAV files */
|
||||||
|
#define TYPE_EOF 12
|
||||||
|
#define TYPE_GENERIC_ULAW 128
|
||||||
|
#define TYPE_GENERIC_ALAW 129
|
||||||
|
|
||||||
|
#define POSITIVE_ULAW_ZERO 0xff
|
||||||
|
#define NEGATIVE_ULAW_ZERO 0x7f
|
||||||
|
|
||||||
|
#undef BOOL
|
||||||
|
#undef TRUE
|
||||||
|
#undef FALSE
|
||||||
|
#define BOOL int
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
#ifndef MAX_PATH
|
||||||
|
#define MAX_PATH 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(unix) && !defined(linux)
|
||||||
|
#define labs abs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ROUNDEDSHIFTDOWN(x, n) (((n) == 0) ? (x) : ((x) >> ((n) - 1)) >> 1)
|
||||||
|
|
||||||
|
#ifndef M_LN2
|
||||||
|
#define M_LN2 0.69314718055994530942
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BUFSIZ must be a multiple of four to contain a whole number of words */
|
||||||
|
#ifdef BUFSIZ
|
||||||
|
#undef BUFSIZ
|
||||||
|
#endif
|
||||||
|
#define BUFSIZ 512
|
||||||
|
|
||||||
|
#define putc_exit(val, stream)\
|
||||||
|
{ char rval;\
|
||||||
|
if((rval = putc((val), (stream))) != (char) (val))\
|
||||||
|
update_exit(1, "write failed: putc returns EOF\n");\
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int getc_exit_val;
|
||||||
|
#define getc_exit(stream)\
|
||||||
|
(((getc_exit_val = getc(stream)) == EOF) ? \
|
||||||
|
update_exit(1, "read failed: getc returns EOF\n"), 0: getc_exit_val)
|
||||||
|
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
# include <inttypes.h>
|
||||||
|
#else
|
||||||
|
# if SIZEOF_UNSIGNED_LONG == 4
|
||||||
|
# define uint32_t unsigned long
|
||||||
|
# define int32_t long
|
||||||
|
# else
|
||||||
|
# define uint32_t unsigned int
|
||||||
|
# define int32_t int
|
||||||
|
# endif
|
||||||
|
# define uint16_t unsigned short
|
||||||
|
# define uint8_t unsigned char
|
||||||
|
# define int16_t short
|
||||||
|
# define int8_t char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef ulong
|
||||||
|
#undef ushort
|
||||||
|
#undef uchar
|
||||||
|
#undef slong
|
||||||
|
#undef sshort
|
||||||
|
#undef schar
|
||||||
|
#define ulong uint32_t
|
||||||
|
#define ushort uint16_t
|
||||||
|
#define uchar uint8_t
|
||||||
|
#define slong int32_t
|
||||||
|
#define sshort int16_t
|
||||||
|
#define schar int8_t
|
||||||
|
|
||||||
|
#if defined(__STDC__) || defined(__GNUC__) || defined(sgi) || !defined(unix)
|
||||||
|
#define PROTO(ARGS) ARGS
|
||||||
|
#else
|
||||||
|
#define PROTO(ARGS) ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEED_OLD_PROTOTYPES
|
||||||
|
/*******************************************/
|
||||||
|
/* this should be in string.h or strings.h */
|
||||||
|
extern int strcmp PROTO ((const char*, const char*));
|
||||||
|
extern char* strcpy PROTO ((char*, const char*));
|
||||||
|
extern char* strcat PROTO ((char*, const char*));
|
||||||
|
extern int strlen PROTO ((const char*));
|
||||||
|
|
||||||
|
/**************************************/
|
||||||
|
/* defined in stdlib.h if you have it */
|
||||||
|
extern void* malloc PROTO ((unsigned long));
|
||||||
|
extern void free PROTO ((void*));
|
||||||
|
extern int atoi PROTO ((const char*));
|
||||||
|
extern void swab PROTO ((char*, char*, int));
|
||||||
|
extern int fseek PROTO ((FILE*, long, int));
|
||||||
|
|
||||||
|
/***************************/
|
||||||
|
/* other misc system calls */
|
||||||
|
extern int unlink PROTO ((const char*));
|
||||||
|
extern void exit PROTO ((int));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/* defined in Sulawalaw.c */
|
||||||
|
extern int Sulaw2lineartab[];
|
||||||
|
#define Sulaw2linear(i) (Sulaw2lineartab[i])
|
||||||
|
#ifndef Sulaw2linear
|
||||||
|
extern int Sulaw2linear PROTO((uchar));
|
||||||
|
#endif
|
||||||
|
extern uchar Slinear2ulaw PROTO((int));
|
||||||
|
|
||||||
|
extern int Salaw2lineartab[];
|
||||||
|
#define Salaw2linear(i) (Salaw2lineartab[i])
|
||||||
|
#ifndef Salaw2linear
|
||||||
|
extern int Salaw2linear PROTO((uchar));
|
||||||
|
#endif
|
||||||
|
extern uchar Slinear2alaw PROTO((int));
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
/* defined in exit.c */
|
||||||
|
extern void basic_exit PROTO ((int));
|
||||||
|
#ifdef HAVE_STDARG_H
|
||||||
|
extern void error_exit PROTO ((char*,...));
|
||||||
|
extern void perror_exit PROTO ((char*,...));
|
||||||
|
extern void usage_exit PROTO ((int, char*,...));
|
||||||
|
extern void update_exit PROTO ((int, char*,...));
|
||||||
|
#else
|
||||||
|
extern void error_exit PROTO (());
|
||||||
|
extern void perror_exit PROTO (());
|
||||||
|
extern void usage_exit PROTO (());
|
||||||
|
extern void update_exit PROTO (());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**********************/
|
||||||
|
/* defined in array.c */
|
||||||
|
extern void* pmalloc PROTO ((ulong));
|
||||||
|
extern slong** long2d PROTO ((ulong, ulong));
|
||||||
|
|
||||||
|
#endif
|
7
Libraries/Shorten/Files/src/Makefile.am
Normal file
7
Libraries/Shorten/Files/src/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
libdir = `lamip --plugin-dir`
|
||||||
|
lib_LTLIBRARIES = libinputshorten.la
|
||||||
|
|
||||||
|
INCLUDES = -I. -I.. -I$(top_srcdir)/shorten -I$(top_srcdir)/shorten/util -I$(top_srcdir)/shorten/src
|
||||||
|
libinputshorten_la_LDFLAGS = -module -avoid-version
|
||||||
|
libinputshorten_la_LIBADD = $(top_srcdir)/shorten/src/libshorten.la
|
||||||
|
libinputshorten_la_SOURCES = libinputshorten.c
|
250
Libraries/Shorten/Files/src/libinputshorten.c
Normal file
250
Libraries/Shorten/Files/src/libinputshorten.c
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
* lamip input plugin - Shorten decoder
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* well... first version is full of memory leaks i guess :)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* General includes */
|
||||||
|
#include <plug_in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* General includes for shorten */
|
||||||
|
#include "decode.h"
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* we declare the functions we use in the plugin here */
|
||||||
|
static int shorten_init(const lamipPluginHandle *);
|
||||||
|
static void shorten_cleanup(void);
|
||||||
|
static void shorten_decode(lamipURL *, int);
|
||||||
|
static void shorten_songinfo(lamipURL *,lamipSonginfo *);
|
||||||
|
|
||||||
|
/* We set the functions in the InputPlugin struct... */
|
||||||
|
static InputPlugin shorten_functions;
|
||||||
|
InputPlugin *lamip_input_info(void)
|
||||||
|
{
|
||||||
|
shorten_functions.common.name = "inputSHORTEN";
|
||||||
|
shorten_functions.common.description = "plays *.shn - Shorten";
|
||||||
|
shorten_functions.common.init = shorten_init;
|
||||||
|
shorten_functions.common.cleanup = shorten_cleanup;
|
||||||
|
shorten_functions.decode = shorten_decode;
|
||||||
|
shorten_functions.set_song_info = shorten_songinfo;
|
||||||
|
|
||||||
|
return(&shorten_functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we set the module PCM format in this struct... like every input plugin should do by now */
|
||||||
|
static lamipPCMInfo pcmi;
|
||||||
|
|
||||||
|
/* some functions */
|
||||||
|
|
||||||
|
/* all things for shorten decoder */
|
||||||
|
shn_file *shnfile;
|
||||||
|
shn_config shn_cfg;
|
||||||
|
static uchar *real_buffer = (uchar *)NULL;
|
||||||
|
|
||||||
|
#define CONFIG_ERROR_OUTPUT_METHOD "error_output_method"
|
||||||
|
#define CONFIG_SEEK_TABLES_PATH "seek_tables_path"
|
||||||
|
#define CONFIG_RELATIVE_SEEK_TABLES_PATH "relative_seek_tables_path"
|
||||||
|
#define CONFIG_VERBOSE "verbose"
|
||||||
|
#define CONFIG_SWAP_BYTES "swap_bytes"
|
||||||
|
|
||||||
|
#define NUM_BUFFER_BLOCKS 4096L
|
||||||
|
|
||||||
|
static int shorten_init(const lamipPluginHandle *handle)
|
||||||
|
{
|
||||||
|
/* Setting when shorten decoder should get active */
|
||||||
|
lamipPluginHandle *config = (lamipPluginHandle *)handle;
|
||||||
|
lamip_set_mime_type(config, ".shn", NULL);
|
||||||
|
|
||||||
|
/* Initializing the shn_cfg struct, we config it later anyway */
|
||||||
|
shn_cfg.error_output_method = ERROR_OUTPUT_DEVNULL;
|
||||||
|
shn_cfg.seek_tables_path = NULL;
|
||||||
|
shn_cfg.relative_seek_tables_path = NULL;
|
||||||
|
shn_cfg.verbose = 0;
|
||||||
|
shn_cfg.swap_bytes = 0;
|
||||||
|
|
||||||
|
/* Necessary config variables */
|
||||||
|
char *val_error_output_method;
|
||||||
|
char *val_seek_tables_path;
|
||||||
|
char *val_relative_seek_tables_path;
|
||||||
|
int val_verbose;
|
||||||
|
int val_swap_bytes;
|
||||||
|
|
||||||
|
/* config: error output */
|
||||||
|
if(!lamip_cfg_getExist(handle, CONFIG_ERROR_OUTPUT_METHOD)) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: no config value for %s found, resetting to default DEVNULL...\n", CONFIG_ERROR_OUTPUT_METHOD);
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: possible values for %s are \"DEVNULL\", \"STDERR\"\n", CONFIG_ERROR_OUTPUT_METHOD);
|
||||||
|
val_error_output_method = strdup("DEVNULL");
|
||||||
|
lamip_cfg_set(config, CONFIG_ERROR_OUTPUT_METHOD, val_error_output_method);
|
||||||
|
} else {
|
||||||
|
val_error_output_method = lamip_cfg_get(handle, CONFIG_ERROR_OUTPUT_METHOD);
|
||||||
|
}
|
||||||
|
if(strcasecmp(val_error_output_method, "DEVNULL") == 0)
|
||||||
|
shn_cfg.error_output_method = ERROR_OUTPUT_DEVNULL;
|
||||||
|
else if(strcasecmp(val_error_output_method, "STDERR") == 0)
|
||||||
|
shn_cfg.error_output_method = ERROR_OUTPUT_STDERR;
|
||||||
|
else {
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: Wrong value for %s found! Resetting to default DEVNULL...\n");
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: possible values for %s are \"DEVNULL\", \"STDERR\", \"WINDOW\"\n", CONFIG_ERROR_OUTPUT_METHOD);
|
||||||
|
val_error_output_method = strdup("DEVNULL");
|
||||||
|
lamip_cfg_set(config, CONFIG_ERROR_OUTPUT_METHOD, val_error_output_method);
|
||||||
|
shn_cfg.error_output_method = ERROR_OUTPUT_DEVNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* config: absolute seek tables path */
|
||||||
|
if(!lamip_cfg_getExist(handle, CONFIG_SEEK_TABLES_PATH)) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: no config value for %s found, resetting to default...\n", CONFIG_SEEK_TABLES_PATH);
|
||||||
|
val_seek_tables_path = strdup("/tmp");
|
||||||
|
lamip_cfg_set(config, CONFIG_SEEK_TABLES_PATH, val_seek_tables_path);
|
||||||
|
} else {
|
||||||
|
val_seek_tables_path = lamip_cfg_get(handle, CONFIG_SEEK_TABLES_PATH);
|
||||||
|
}
|
||||||
|
shn_cfg.seek_tables_path = strdup(val_seek_tables_path);
|
||||||
|
|
||||||
|
/* config: relative seek tables path */
|
||||||
|
if(!lamip_cfg_getExist(handle, CONFIG_RELATIVE_SEEK_TABLES_PATH)) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: no config value for %s found, resetting to default...\n", CONFIG_RELATIVE_SEEK_TABLES_PATH);
|
||||||
|
val_relative_seek_tables_path = strdup("");
|
||||||
|
lamip_cfg_set(config, CONFIG_RELATIVE_SEEK_TABLES_PATH, val_relative_seek_tables_path);
|
||||||
|
} else {
|
||||||
|
val_relative_seek_tables_path = lamip_cfg_get(handle, CONFIG_RELATIVE_SEEK_TABLES_PATH);
|
||||||
|
}
|
||||||
|
shn_cfg.relative_seek_tables_path = strdup(val_relative_seek_tables_path);
|
||||||
|
|
||||||
|
/* config: verbose */
|
||||||
|
if(!lamip_cfg_getExist(handle, CONFIG_VERBOSE)) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: no config value for %s found, resetting to default...\n", CONFIG_VERBOSE);
|
||||||
|
val_verbose = 0;
|
||||||
|
lamip_cfg_setBool(config, CONFIG_VERBOSE, val_verbose);
|
||||||
|
} else {
|
||||||
|
val_verbose = lamip_cfg_getBool(handle, CONFIG_VERBOSE);
|
||||||
|
}
|
||||||
|
shn_cfg.verbose = val_verbose;
|
||||||
|
|
||||||
|
/* config: swap bytes */
|
||||||
|
if(!lamip_cfg_getExist(handle, CONFIG_SWAP_BYTES)) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_init: no config value for %s found, resetting to default...\n", CONFIG_SWAP_BYTES);
|
||||||
|
val_swap_bytes = 0;
|
||||||
|
lamip_cfg_setBool(config, CONFIG_SWAP_BYTES, val_swap_bytes);
|
||||||
|
} else {
|
||||||
|
val_swap_bytes = lamip_cfg_getBool(handle, CONFIG_SWAP_BYTES);
|
||||||
|
}
|
||||||
|
shn_cfg.swap_bytes = val_swap_bytes;
|
||||||
|
|
||||||
|
/* Config cleanup */
|
||||||
|
free(val_error_output_method);
|
||||||
|
free(val_seek_tables_path);
|
||||||
|
free(val_relative_seek_tables_path);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shorten_cleanup(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shorten_decode(lamipURL *url, int subtrack)
|
||||||
|
{
|
||||||
|
if(!url) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: Got no url!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char *filename = lamip_url_getURL(url);
|
||||||
|
if(!filename) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: Got no filename! We cannot play from stream by now!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shnfile = shn_load(filename, shn_cfg);
|
||||||
|
if(!shnfile) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: Error in opening file! Give it another try with skipping id3v2...\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!shn_init_decoder(shnfile)) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: shn_init_decoder() failed! Aborting...\n");
|
||||||
|
shn_unload(shnfile);
|
||||||
|
shnfile = (shn_file *)NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcmi.channels = shn_get_channels(shnfile);
|
||||||
|
pcmi.samplerate = shn_get_samplerate(shnfile);
|
||||||
|
switch(shn_get_bitspersample(shnfile)) {
|
||||||
|
case 8:
|
||||||
|
pcmi.format = PCM_FORMAT_U8;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
pcmi.format = PCM_FORMAT_S16_LE;
|
||||||
|
break;
|
||||||
|
/* Next two bit depths aren't supported by shorten anyway */
|
||||||
|
case 24:
|
||||||
|
pcmi.format = PCM_FORMAT_S24_LE;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
pcmi.format = PCM_FORMAT_S32_LE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: Not supported bits_per_sample format!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Getting a clean buffer */
|
||||||
|
int buffer_size = shn_get_buffer_block_size(shnfile, NUM_BUFFER_BLOCKS);
|
||||||
|
if(real_buffer) {
|
||||||
|
free(real_buffer);
|
||||||
|
real_buffer = (uchar *)NULL;
|
||||||
|
}
|
||||||
|
if(!real_buffer) {
|
||||||
|
real_buffer = (uchar *)malloc(20000);
|
||||||
|
if(!real_buffer) {
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: malloc for real_buffer failed! Aborting...\n");
|
||||||
|
shn_unload(shnfile);
|
||||||
|
shnfile = (shn_file *)NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int read_buffer;
|
||||||
|
int seekable = shn_seekable(shnfile);
|
||||||
|
lamip_open(&pcmi, shn_get_song_length(shnfile));
|
||||||
|
while(lamip_isContinue()) {
|
||||||
|
read_buffer = shn_read(shnfile, real_buffer, buffer_size);
|
||||||
|
if(read_buffer <= 0) {
|
||||||
|
lamip_drain();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lamip_writeData((uchar *)real_buffer, buffer_size);
|
||||||
|
|
||||||
|
/* If seeking */
|
||||||
|
if(lamip_isSeek() && seekable)
|
||||||
|
if(!(shn_seek(shnfile, (unsigned int)(lamip_isSeekGetAndReset() / 1000))))
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: Seeking failed!\n");
|
||||||
|
}
|
||||||
|
lamip_close();
|
||||||
|
if(!shn_cleanup_decoder(shnfile))
|
||||||
|
lamip_send_message("SHORTEN: shorten_decode: shn_cleanup_decoder() failed!\n");
|
||||||
|
shn_unload(shnfile);
|
||||||
|
shnfile = NULL;
|
||||||
|
if(real_buffer) {
|
||||||
|
free((uchar *)real_buffer);
|
||||||
|
real_buffer = (uchar *)NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shorten_songinfo(lamipURL* url, lamipSonginfo* songinfo)
|
||||||
|
{
|
||||||
|
/* TODO - perhaps it ain't necessary... due to a changing lamip core :) */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
0
Libraries/WavPack/Files/AUTHORS
Normal file
0
Libraries/WavPack/Files/AUTHORS
Normal file
106
Libraries/WavPack/Files/ChangeLog
Normal file
106
Libraries/WavPack/Files/ChangeLog
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
---------------------------
|
||||||
|
Release 4.2 - April 2, 2005
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
wavpack.exe (command-line encoder) - 4.2
|
||||||
|
----------------------------------------
|
||||||
|
fixed: handling of wav files larger than 2 gig
|
||||||
|
improved: stereo lossless encoding speed (including "extra" mode)
|
||||||
|
added: -i option to ignore length specified in wav header
|
||||||
|
added: -w option to write APEv2 tags directly from command line
|
||||||
|
|
||||||
|
wvunpack.exe (command-line decoder) - 4.2
|
||||||
|
-----------------------------------------
|
||||||
|
improved: decoding speed
|
||||||
|
|
||||||
|
in_wv.dll (winamp plugin) - 2.2
|
||||||
|
-------------------------------
|
||||||
|
added: winamp media library support
|
||||||
|
improved: decoding speed
|
||||||
|
|
||||||
|
foo_wavpack.dll (foobar plugin) - 2.2
|
||||||
|
-------------------------------------
|
||||||
|
improved: decoding speed
|
||||||
|
|
||||||
|
nxWavPack.dll (Nero plugin) - 1.1
|
||||||
|
Cool_wv4.flt (CoolEdit / Audition filter) - 2.4
|
||||||
|
-----------------------------------------------
|
||||||
|
fixed: handling of wav files larger than 2 gig
|
||||||
|
improved: encoding and decoding speed
|
||||||
|
|
||||||
|
WavPack Library Source Code - 4.2
|
||||||
|
---------------------------------
|
||||||
|
improved: encoding and decoding speed
|
||||||
|
fixed: works correctly with 64-bit compilers
|
||||||
|
added: mode bit to open files in "streaming" mode
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
Update - December 12, 2004
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
WavPack_Apollo.dll (Apollo plugin) - 1.2
|
||||||
|
----------------------------------------
|
||||||
|
fixed: crash when Apollo opened and WavPack plugin can't find config file
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------
|
||||||
|
Release 4.1 - September 14, 2004
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
wavpack.exe (command-line encoder) - 4.1
|
||||||
|
----------------------------------------
|
||||||
|
fixed: hybrid mode + "extra" mode + very low bitrates making corrupt files
|
||||||
|
fixed: mono or multichannel files causing crash (no corruption possible)
|
||||||
|
added: third name specification for "correction" file (EAC specific)
|
||||||
|
added: -t option to preserve timestamps
|
||||||
|
added: error summary for batch mode
|
||||||
|
|
||||||
|
wvunpack.exe (command-line decoder) - 4.1
|
||||||
|
-----------------------------------------
|
||||||
|
fixed: hybrid mode decoding bugs (very obscure situations)
|
||||||
|
added: -s option to dump file summary to stdout
|
||||||
|
added: -t option to preserve timestamps
|
||||||
|
added: error summary for batch mode
|
||||||
|
|
||||||
|
wvselfx.exe (self-extraction stub) - 4.1
|
||||||
|
----------------------------------------
|
||||||
|
fixed: hybrid mode decoding bugs (very obscure situations)
|
||||||
|
|
||||||
|
in_wv.dll (winamp plugin) - 2.1
|
||||||
|
-------------------------------
|
||||||
|
fixed: international characters in tags display properly (UTF-8 to Ansi)
|
||||||
|
added: maximum tag data field width changed from 64 chars to 128 chars
|
||||||
|
added: new infobox items including encoder version & modes, track #, md5
|
||||||
|
|
||||||
|
foo_wavpack.dll (foobar plugin) - 2.1
|
||||||
|
-------------------------------------
|
||||||
|
added: new database items including encoder version & modes and md5
|
||||||
|
|
||||||
|
WavPack_Apollo.dll (Apollo plugin) - 1.1
|
||||||
|
----------------------------------------
|
||||||
|
fixed: international characters in tags display properly (UTF-8 to Ansi)
|
||||||
|
|
||||||
|
Cool_wv4.flt (CoolEdit / Audition filter) - 2.2
|
||||||
|
-----------------------------------------------
|
||||||
|
fixed: hybrid mode + "extra" mode + very low bitrates making corrupt files
|
||||||
|
fixed: saving mono file causing crash (no corruption possible)
|
||||||
|
fixed: hybrid mode decoding bugs (very obscure situations)
|
||||||
|
fixed: partial saves (with "Cancel") have incorrect RIFF header if unpacked
|
||||||
|
|
||||||
|
nxWavPack.dll (Nero plugin) - 1.0
|
||||||
|
---------------------------------
|
||||||
|
new
|
||||||
|
|
||||||
|
WavPack Library Source Code - 4.1
|
||||||
|
---------------------------------
|
||||||
|
fixed: hybrid mode + "extra" mode + very low bitrates making corrupt files
|
||||||
|
fixed: mono or multichannel files causing crash (no corruption possible)
|
||||||
|
fixed: hybrid mode decoding bugs (very obscure situations)
|
||||||
|
added: mode bits for determining additional encode info (extra, sfx)
|
||||||
|
added: function to return total compressed file length (including wvc)
|
||||||
|
added: function to return encoder version (1, 2, 3, or 4)
|
||||||
|
added: ability to obtain MD5 sum before decoding file (requires seek to end)
|
||||||
|
added: mode bit for determining tag type (for proper character translation)
|
||||||
|
added: ability to encode WavPack files without knowing length in advance
|
||||||
|
added: option for small "information only" version of library
|
27
Libraries/WavPack/Files/Makefile.am
Normal file
27
Libraries/WavPack/Files/Makefile.am
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
bin_PROGRAMS = wavpack wvunpack
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libwavpack.la
|
||||||
|
|
||||||
|
wpincludedir = $(prefix)/include/wavpack
|
||||||
|
|
||||||
|
wpinclude_HEADERS = md5.h wavpack.h wputils.h unpack3.h
|
||||||
|
|
||||||
|
libwavpack_la_SOURCES = bits.c float.c metadata.c unpack.c unpack3.c utils.c \
|
||||||
|
wputils.c words.c md5.c extra1.c extra2.c pack.c \
|
||||||
|
md5.h wavpack.h wputils.h unpack3.h
|
||||||
|
libwavpack_la_CFLAGS = -DPACK -DUNPACK -DUSE_FSTREAMS -DTAGS -DSEEKING -DVER3
|
||||||
|
libwavpack_la_LDFLAGS = -lm @ICONV_LIBS@
|
||||||
|
|
||||||
|
wavpack_SOURCES = wavpack.c
|
||||||
|
wavpack_CFLAGS = -DPACK
|
||||||
|
wavpack_LDFLAGS = -lm -lcurses
|
||||||
|
wavpack_LDADD = libwavpack.la
|
||||||
|
|
||||||
|
wvunpack_SOURCES = wvunpack.c
|
||||||
|
wvunpack_CFLAGS = -DUNPACK -DUSE_FSTREAMS
|
||||||
|
wvunpack_LDFLAGS = -lm -lcurses
|
||||||
|
wvunpack_LDADD = libwavpack.la
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = wavpack.pc
|
0
Libraries/WavPack/Files/NEWS
Normal file
0
Libraries/WavPack/Files/NEWS
Normal file
86
Libraries/WavPack/Files/README
Normal file
86
Libraries/WavPack/Files/README
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
This package contains all the source code required to build the WavPack
|
||||||
|
command-line programs and the WavPack library and it has been tested on many
|
||||||
|
platforms. For example code using the library you might want to check some
|
||||||
|
of the plugin sources in the Windows source release.
|
||||||
|
|
||||||
|
To build everything, type:
|
||||||
|
|
||||||
|
1. ./autogen.sh
|
||||||
|
2. ./configure
|
||||||
|
3. make
|
||||||
|
4. make install (optionally, to install into /usr/local/bin)
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
1. This code is designed to be much easier to port to other platforms than
|
||||||
|
the previous version of WavPack. File I/O is done with streams and all file
|
||||||
|
functions (except "fopen") are handled in a wrapper in the "utils.c"
|
||||||
|
module. The code is even written to be endian-independent and a compile
|
||||||
|
option is provided to eliminate the DOS-specific directory searches.
|
||||||
|
|
||||||
|
To maintain compatibility on various platforms, the following conventions
|
||||||
|
are used:
|
||||||
|
|
||||||
|
a "short" must be 16-bits
|
||||||
|
an "int" must be at least 16-bits, but may be larger
|
||||||
|
a "char" must default to signed (Watcom users take note!)
|
||||||
|
|
||||||
|
For version 4.2 references to "long" variables were eliminated to allow
|
||||||
|
compilation on 64-bit machines.
|
||||||
|
|
||||||
|
2. For WavPack file decoding, a library interface in "wputils.c" provides all
|
||||||
|
the functionality required for both the winamp plugin and the "wvunpack"
|
||||||
|
command-line program (including the transparent decoding of "correction"
|
||||||
|
files). There is also an alternate entry point that uses reader callbacks
|
||||||
|
for all input, although in this case it is the caller's responsibility to
|
||||||
|
to open the "correction" file. It is no longer necessary to manipulate the
|
||||||
|
WavPack structures directly; everything is handled with function calls. In
|
||||||
|
fact, a new header file called "wputils.h" can be used that hides all the
|
||||||
|
WavPack internals from the application.
|
||||||
|
|
||||||
|
3. For WavPack file creation, the library interface in "wputils.c" provides
|
||||||
|
all the functionality for both the Audition filter and the "wavpack"
|
||||||
|
command-line program. No file I/O is performed by the library when creating
|
||||||
|
WavPack files. Instead, the user supplies a "write_block" function that
|
||||||
|
accepts completed WavPack blocks. For version 4.2 limited functionality
|
||||||
|
has been added to append APEv2 tags to WavPack files during creation.
|
||||||
|
|
||||||
|
4. The following #define's are used to control the optimum configuration of
|
||||||
|
the library for the desired application and must be the same for the
|
||||||
|
compilation of ALL files:
|
||||||
|
|
||||||
|
UNPACK to unpack audio samples from WavPack files
|
||||||
|
PACK to create WavPack files from raw audio data
|
||||||
|
INFO_ONLY to obtain information from WavPack files, but not audio
|
||||||
|
SEEKING to allow seeking to a specific sample index (unpack only)
|
||||||
|
USE_FSTREAMS to open WavPack files by name using fstreams (via fopen)
|
||||||
|
TAGS to read specified fields from ID3v1 and APEv2 tags and
|
||||||
|
create APEv2 tags
|
||||||
|
VER3 to handle WavPack files from versions prior to 4.0
|
||||||
|
WIN32 required for Win32 platform
|
||||||
|
|
||||||
|
The following files are required for various configurations:
|
||||||
|
|
||||||
|
UNPACK or
|
||||||
|
INFO_ONLY: wputils.c unpack.c words.c bits.c metadata.c float.c
|
||||||
|
|
||||||
|
PACK: wputils.c pack.c extra1.c extra2.c
|
||||||
|
words.c bits.c metadata.c float.c
|
||||||
|
|
||||||
|
PACK and
|
||||||
|
UNPACK: wputils.c unpack.c pack.c extra1.c extra2.c
|
||||||
|
words.c bits.c metadata.c float.c
|
||||||
|
|
||||||
|
5. An alternate version of this library is available specifically designed
|
||||||
|
for "resource limited" CPUs or hardware decoding. This "tiny" decoder
|
||||||
|
library works with less than 32k of code and less than 4k of data.
|
||||||
|
|
||||||
|
6. Questions or comments should be directed to david@wavpack.com
|
7
Libraries/WavPack/Files/autogen.sh
Executable file
7
Libraries/WavPack/Files/autogen.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
touch NEWS README AUTHORS ChangeLog
|
||||||
|
aclocal
|
||||||
|
libtoolize --copy
|
||||||
|
automake --add-missing
|
||||||
|
autoconf
|
259
Libraries/WavPack/Files/bits.c
Normal file
259
Libraries/WavPack/Files/bits.c
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// bits.c
|
||||||
|
|
||||||
|
// This module provides utilities to support the BitStream structure which is
|
||||||
|
// used to read and write all WavPack audio data streams. It also contains a
|
||||||
|
// wrapper for the stream I/O functions and a set of functions dealing with
|
||||||
|
// endian-ness, both for enhancing portability. Finally, a debug wrapper for
|
||||||
|
// the malloc() system is provided.
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <io.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////// Bitstream functions ////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(UNPACK) || defined(INFO_ONLY)
|
||||||
|
|
||||||
|
// Open the specified BitStream and associate with the specified buffer.
|
||||||
|
|
||||||
|
static void bs_read (Bitstream *bs);
|
||||||
|
|
||||||
|
void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end)
|
||||||
|
{
|
||||||
|
bs->error = bs->sr = bs->bc = 0;
|
||||||
|
bs->ptr = (bs->buf = buffer_start) - 1;
|
||||||
|
bs->end = buffer_end;
|
||||||
|
bs->wrap = bs_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is only called from the getbit() and getbits() macros when
|
||||||
|
// the BitStream has been exhausted and more data is required. Sinve these
|
||||||
|
// bistreams no longer access files, this function simple sets an error and
|
||||||
|
// resets the buffer.
|
||||||
|
|
||||||
|
static void bs_read (Bitstream *bs)
|
||||||
|
{
|
||||||
|
bs->ptr = bs->buf - 1;
|
||||||
|
bs->error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called to close the bitstream. It returns the number of
|
||||||
|
// full bytes actually read as bits.
|
||||||
|
|
||||||
|
uint32_t bs_close_read (Bitstream *bs)
|
||||||
|
{
|
||||||
|
uint32_t bytes_read;
|
||||||
|
|
||||||
|
if (bs->bc < 8)
|
||||||
|
bs->ptr++;
|
||||||
|
|
||||||
|
if ((bs->buf - bs->ptr) & 1)
|
||||||
|
bs->ptr++;
|
||||||
|
|
||||||
|
bytes_read = bs->ptr - bs->buf;
|
||||||
|
CLEAR (*bs);
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK
|
||||||
|
|
||||||
|
// Open the specified BitStream using the specified buffer pointers. It is
|
||||||
|
// assumed that enough buffer space has been allocated for all data that will
|
||||||
|
// be written, otherwise an error will be generated.
|
||||||
|
|
||||||
|
static void bs_write (Bitstream *bs);
|
||||||
|
|
||||||
|
void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end)
|
||||||
|
{
|
||||||
|
bs->error = bs->sr = bs->bc = 0;
|
||||||
|
bs->ptr = bs->buf = buffer_start;
|
||||||
|
bs->end = buffer_end;
|
||||||
|
bs->wrap = bs_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is only called from the putbit() and putbits() macros when
|
||||||
|
// the buffer is full, which is now flagged as an error.
|
||||||
|
|
||||||
|
static void bs_write (Bitstream *bs)
|
||||||
|
{
|
||||||
|
bs->ptr = bs->buf;
|
||||||
|
bs->error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function forces a flushing write of the specified BitStream, and
|
||||||
|
// returns the total number of bytes written into the buffer.
|
||||||
|
|
||||||
|
uint32_t bs_close_write (Bitstream *bs)
|
||||||
|
{
|
||||||
|
uint32_t bytes_written;
|
||||||
|
|
||||||
|
if (bs->error)
|
||||||
|
return (uint32_t) -1;
|
||||||
|
|
||||||
|
while (bs->bc || ((bs->ptr - bs->buf) & 1)) putbit_1 (bs);
|
||||||
|
bytes_written = bs->ptr - bs->buf;
|
||||||
|
CLEAR (*bs);
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/////////////////////// Endian Correction Routines ////////////////////////////
|
||||||
|
|
||||||
|
void little_endian_to_native (void *data, char *format)
|
||||||
|
{
|
||||||
|
uchar *cp = (uchar *) data;
|
||||||
|
int32_t temp;
|
||||||
|
|
||||||
|
while (*format) {
|
||||||
|
switch (*format) {
|
||||||
|
case 'L':
|
||||||
|
temp = cp [0] + ((int32_t) cp [1] << 8) + ((int32_t) cp [2] << 16) + ((int32_t) cp [3] << 24);
|
||||||
|
* (int32_t *) cp = temp;
|
||||||
|
cp += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
temp = cp [0] + (cp [1] << 8);
|
||||||
|
* (short *) cp = (short) temp;
|
||||||
|
cp += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (isdigit (*format))
|
||||||
|
cp += *format - '0';
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_to_little_endian (void *data, char *format)
|
||||||
|
{
|
||||||
|
uchar *cp = (uchar *) data;
|
||||||
|
int32_t temp;
|
||||||
|
|
||||||
|
while (*format) {
|
||||||
|
switch (*format) {
|
||||||
|
case 'L':
|
||||||
|
temp = * (int32_t *) cp;
|
||||||
|
*cp++ = (uchar) temp;
|
||||||
|
*cp++ = (uchar) (temp >> 8);
|
||||||
|
*cp++ = (uchar) (temp >> 16);
|
||||||
|
*cp++ = (uchar) (temp >> 24);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
temp = * (short *) cp;
|
||||||
|
*cp++ = (uchar) temp;
|
||||||
|
*cp++ = (uchar) (temp >> 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (isdigit (*format))
|
||||||
|
cp += *format - '0';
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////// Debug Wrapper for Malloc ///////////////////////////
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
|
||||||
|
void *vptrs [512];
|
||||||
|
|
||||||
|
static void *add_ptr (void *ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 512; ++i)
|
||||||
|
if (!vptrs [i]) {
|
||||||
|
vptrs [i] = ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 512)
|
||||||
|
error_line ("too many mallocs!");
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *del_ptr (void *ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 512; ++i)
|
||||||
|
if (vptrs [i] == ptr) {
|
||||||
|
vptrs [i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 512)
|
||||||
|
error_line ("free invalid ptr!");
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *malloc_db (uint32_t size)
|
||||||
|
{
|
||||||
|
if (size)
|
||||||
|
return add_ptr (malloc (size));
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_db (void *ptr)
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
free (del_ptr (ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *realloc_db (void *ptr, uint32_t size)
|
||||||
|
{
|
||||||
|
if (ptr && size)
|
||||||
|
return add_ptr (realloc (del_ptr (ptr), size));
|
||||||
|
else if (size)
|
||||||
|
return malloc_db (size);
|
||||||
|
else
|
||||||
|
free_db (ptr);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dump_alloc (void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (j = i = 0; i < 512; ++i)
|
||||||
|
if (vptrs [i])
|
||||||
|
j++;
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
142
Libraries/WavPack/Files/compile
Executable file
142
Libraries/WavPack/Files/compile
Executable file
|
@ -0,0 +1,142 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
|
||||||
|
scriptversion=2005-02-03.08
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# This file is maintained in Automake, please report
|
||||||
|
# bugs to <bug-automake@gnu.org> or send patches to
|
||||||
|
# <automake-patches@gnu.org>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||||
|
arguments, and rename the output as expected.
|
||||||
|
|
||||||
|
If you are trying to build a whole package this is not the
|
||||||
|
right script to run: please start by reading the file `INSTALL'.
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "compile $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ofile=
|
||||||
|
cfile=
|
||||||
|
eat=
|
||||||
|
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||||
|
# So we strip `-o arg' only if arg is an object.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.obj)
|
||||||
|
ofile=$2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" -o "$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*.c)
|
||||||
|
cfile=$1
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$ofile" || test -z "$cfile"; then
|
||||||
|
# If no `-o' option was seen then we might have been invoked from a
|
||||||
|
# pattern rule where we don't need one. That is ok -- this is a
|
||||||
|
# normal compilation that the losing compiler can handle. If no
|
||||||
|
# `.c' file was seen then we are probably linking. That is also
|
||||||
|
# ok.
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Name of file we expect compiler to create.
|
||||||
|
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
|
||||||
|
|
||||||
|
# Create the lock directory.
|
||||||
|
# Note: use `[/.-]' here to ensure that we don't use the same name
|
||||||
|
# that we are using for the .o file. Also, base the name on the expected
|
||||||
|
# object file name, since that is what matters with a parallel build.
|
||||||
|
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
|
||||||
|
while true; do
|
||||||
|
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# FIXME: race condition here if user kills between mkdir and trap.
|
||||||
|
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||||
|
|
||||||
|
# Run the compile.
|
||||||
|
"$@"
|
||||||
|
ret=$?
|
||||||
|
|
||||||
|
if test -f "$cofile"; then
|
||||||
|
mv "$cofile" "$ofile"
|
||||||
|
elif test -f "${cofile}bj"; then
|
||||||
|
mv "${cofile}bj" "$ofile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir "$lockdir"
|
||||||
|
exit $ret
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
62
Libraries/WavPack/Files/configure.ac
Normal file
62
Libraries/WavPack/Files/configure.ac
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# wavpack 4.2 configure.ac
|
||||||
|
|
||||||
|
AC_INIT(wavpack, 4.2, bryant@wavpack.com)
|
||||||
|
AM_INIT_AUTOMAKE(wavpack, 4.2, bryant@wavpack.com)
|
||||||
|
AC_CONFIG_SRCDIR([pack.c])
|
||||||
|
|
||||||
|
# Check for os version
|
||||||
|
VERSION_OS=$(uname -s)
|
||||||
|
AC_DEFINE_UNQUOTED(VERSION_OS, "$VERSION_OS", [os version])
|
||||||
|
|
||||||
|
# Check for processor characteristics
|
||||||
|
AC_C_BIGENDIAN(AC_DEFINE([HIGHFIRST], [1], [big-endian machine]))
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
AC_CHECK_LIB(m, log10, [], AC_MSG_ERROR(math library not found))
|
||||||
|
|
||||||
|
# Check for iconv
|
||||||
|
AC_ARG_WITH(iconv, [ --with-iconv[=DIR] Add ICONV support (on)])
|
||||||
|
if test "$with_iconv" = "no" ; then
|
||||||
|
AC_MSG_ERROR([[Sorry, you can't deactivate iconv.]])
|
||||||
|
else
|
||||||
|
if test "$with_iconv" != "yes" -a "$with_iconv" != "" ; then
|
||||||
|
CPPFLAGS="${CPPFLAGS} -I$with_iconv/include"
|
||||||
|
ICONV_LIBS="-L$with_iconv/lib"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_HEADER(iconv.h,
|
||||||
|
AC_MSG_CHECKING(for iconv)
|
||||||
|
AC_TRY_LINK([#include <stdlib.h>
|
||||||
|
#include <iconv.h>],[
|
||||||
|
iconv_t cd = iconv_open ("","");
|
||||||
|
iconv (cd, NULL, NULL, NULL, NULL);],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
WITH_ICONV=1
|
||||||
|
ICONV=""],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
AC_MSG_CHECKING(for iconv in -liconv)
|
||||||
|
|
||||||
|
_ldflags="${LDFLAGS}"
|
||||||
|
_libs="${LIBS}"
|
||||||
|
LDFLAGS="${LDFLAGS} ${ICONV_LIBS}"
|
||||||
|
LIBS="${LIBS} -liconv"
|
||||||
|
|
||||||
|
AC_TRY_LINK([#include <stdlib.h>
|
||||||
|
#include <iconv.h>],[
|
||||||
|
iconv_t cd = iconv_open ("","");
|
||||||
|
iconv (cd, NULL, NULL, NULL, NULL);],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
WITH_ICONV=1
|
||||||
|
ICONV_LIBS="${ICONV_LIBS} -liconv"
|
||||||
|
ICONV="${ICONV_LIBS}"],[
|
||||||
|
AC_MSG_ERROR([[Can't find iconv libraries.]])])]),
|
||||||
|
AC_MSG_ERROR([[Can't find iconv headers.]]))
|
||||||
|
fi
|
||||||
|
AC_SUBST(ICONV)
|
||||||
|
AC_SUBST(ICONV_LIBS)
|
||||||
|
|
||||||
|
AC_OUTPUT(Makefile wavpack.pc)
|
529
Libraries/WavPack/Files/depcomp
Executable file
529
Libraries/WavPack/Files/depcomp
Executable file
|
@ -0,0 +1,529 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# depcomp - compile a program generating dependencies as side-effects
|
||||||
|
|
||||||
|
scriptversion=2005-02-09.22
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||||
|
as side-effects.
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
depmode Dependency tracking mode.
|
||||||
|
source Source file read by `PROGRAMS ARGS'.
|
||||||
|
object Object file output by `PROGRAMS ARGS'.
|
||||||
|
DEPDIR directory where to store dependencies.
|
||||||
|
depfile Dependency file to output.
|
||||||
|
tmpdepfile Temporary file to use when outputing dependencies.
|
||||||
|
libtool Whether libtool is used (yes/no).
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "depcomp $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||||
|
depfile=${depfile-`echo "$object" |
|
||||||
|
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||||
|
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We
|
||||||
|
# parameterize here, but still list the modes in the big case below,
|
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||||
|
# here, because this file can only contain one case statement.
|
||||||
|
if test "$depmode" = hp; then
|
||||||
|
# HP compiler uses -M and no extra arg.
|
||||||
|
gccflag=-M
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then
|
||||||
|
# This is just like dashmstdout with a different argument.
|
||||||
|
dashmflag=-xM
|
||||||
|
depmode=dashmstdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$depmode" in
|
||||||
|
gcc3)
|
||||||
|
## gcc 3 implements dependency tracking that does exactly what
|
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||||
|
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
mv "$tmpdepfile" "$depfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
gcc)
|
||||||
|
## There are various ways to get dependency output from gcc. Here's
|
||||||
|
## why we pick this rather obscure method:
|
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end
|
||||||
|
## up in a subdir. Having to rename by hand is ugly.
|
||||||
|
## (We might end up doing this anyway to support other compilers.)
|
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||||
|
## -MM, not -M (despite what the docs say).
|
||||||
|
## - Using -M directly means running the compiler twice (even worse
|
||||||
|
## than renaming).
|
||||||
|
if test -z "$gccflag"; then
|
||||||
|
gccflag=-MD,
|
||||||
|
fi
|
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||||
|
## The second -e expression handles DOS-style file names with drive letters.
|
||||||
|
sed -e 's/^[^:]*: / /' \
|
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||||
|
## This next piece of magic avoids the `deleted header file' problem.
|
||||||
|
## The problem is that when a header file which appears in a .P file
|
||||||
|
## is deleted, the dependency causes make to die (because there is
|
||||||
|
## typically no way to rebuild the header). We avoid this by adding
|
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||||
|
## this for us directly.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" |
|
||||||
|
## Some versions of gcc put a space before the `:'. On the theory
|
||||||
|
## that the space means something, we add a space to the output as
|
||||||
|
## well.
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
sgi)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||||
|
else
|
||||||
|
"$@" -MDupdate "$tmpdepfile"
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
|
||||||
|
# Clip off the initial element (the dependent). Don't try to be
|
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle
|
||||||
|
# lines with more than a fixed number of characters (4096 in
|
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||||
|
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||||
|
# dependency line.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||||
|
tr '
|
||||||
|
' ' ' >> $depfile
|
||||||
|
echo >> $depfile
|
||||||
|
|
||||||
|
# The second pass generates a dummy entry for each header file.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||||
|
>> $depfile
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
aix)
|
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||||
|
# in a .u file. In older versions, this file always lives in the
|
||||||
|
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||||
|
# start of each line; $object doesn't have directory information.
|
||||||
|
# Version 6 uses the directory in both cases.
|
||||||
|
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
|
||||||
|
tmpdepfile="$stripped.u"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" -Wc,-M
|
||||||
|
else
|
||||||
|
"$@" -M
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then :
|
||||||
|
else
|
||||||
|
stripped=`echo "$stripped" | sed 's,^.*/,,'`
|
||||||
|
tmpdepfile="$stripped.u"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
outname="$stripped.o"
|
||||||
|
# Each line is of the form `foo.o: dependent.h'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
icc)
|
||||||
|
# Intel's C compiler understands `-MD -MF file'. However on
|
||||||
|
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||||
|
# ICC 7.0 will fill foo.d with something like
|
||||||
|
# foo.o: sub/foo.c
|
||||||
|
# foo.o: sub/foo.h
|
||||||
|
# which is wrong. We want:
|
||||||
|
# sub/foo.o: sub/foo.c
|
||||||
|
# sub/foo.o: sub/foo.h
|
||||||
|
# sub/foo.c:
|
||||||
|
# sub/foo.h:
|
||||||
|
# ICC 7.1 will output
|
||||||
|
# foo.o: sub/foo.c sub/foo.h
|
||||||
|
# and will wrap long lines using \ :
|
||||||
|
# foo.o: sub/foo.c ... \
|
||||||
|
# sub/foo.h ... \
|
||||||
|
# ...
|
||||||
|
|
||||||
|
"$@" -MD -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
# Each line is of the form `foo.o: dependent.h',
|
||||||
|
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||||
|
sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
tru64)
|
||||||
|
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||||
|
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||||
|
# dependencies in `foo.d' instead, so we check for that too.
|
||||||
|
# Subdirectories are respected.
|
||||||
|
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||||
|
test "x$dir" = "x$object" && dir=
|
||||||
|
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||||
|
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
# With Tru64 cc, shared objects can also be used to make a
|
||||||
|
# static library. This mecanism is used in libtool 1.4 series to
|
||||||
|
# handle both shared and static libraries in a single compilation.
|
||||||
|
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||||
|
#
|
||||||
|
# With libtool 1.5 this exception was removed, and libtool now
|
||||||
|
# generates 2 separate objects for the 2 libraries. These two
|
||||||
|
# compilations output dependencies in in $dir.libs/$base.o.d and
|
||||||
|
# in $dir$base.o.d. We have to check for both files, because
|
||||||
|
# one of the two compilations can be disabled. We should prefer
|
||||||
|
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||||
|
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||||
|
# the former would cause a distcleancheck panic.
|
||||||
|
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||||
|
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||||
|
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||||
|
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||||
|
"$@" -Wc,-MD
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.o.d
|
||||||
|
tmpdepfile2=$dir$base.d
|
||||||
|
tmpdepfile3=$dir$base.d
|
||||||
|
tmpdepfile4=$dir$base.d
|
||||||
|
"$@" -MD
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||||
|
# That's a tab and a space in the [].
|
||||||
|
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
#nosideeffect)
|
||||||
|
# This comment above is used by automake to tell side-effect
|
||||||
|
# dependency tracking mechanisms from slower ones.
|
||||||
|
|
||||||
|
dashmstdout)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout, regardless of -o.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test $1 != '--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove `-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
test -z "$dashmflag" && dashmflag=-M
|
||||||
|
# Require at least two characters before searching for `:'
|
||||||
|
# in the target name. This is to cope with DOS-style filenames:
|
||||||
|
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||||
|
"$@" $dashmflag |
|
||||||
|
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
dashXmstdout)
|
||||||
|
# This case only exists to satisfy depend.m4. It is never actually
|
||||||
|
# run, as this mode is specially recognized in the preamble.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
makedepend)
|
||||||
|
"$@" || exit $?
|
||||||
|
# Remove any Libtool call
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test $1 != '--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
# X makedepend
|
||||||
|
shift
|
||||||
|
cleared=no
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $cleared in
|
||||||
|
no)
|
||||||
|
set ""; shift
|
||||||
|
cleared=yes ;;
|
||||||
|
esac
|
||||||
|
case "$arg" in
|
||||||
|
-D*|-I*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
# Strip any option that makedepend may not understand. Remove
|
||||||
|
# the object too, otherwise makedepend will parse it as a source file.
|
||||||
|
-*|$object)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||||
|
touch "$tmpdepfile"
|
||||||
|
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||||
|
' | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||||
|
;;
|
||||||
|
|
||||||
|
cpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test $1 != '--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove `-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
"$@" -E |
|
||||||
|
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||||
|
sed '$ s: \\$::' > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
cat < "$tmpdepfile" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvisualcpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout, regardless of -o,
|
||||||
|
# because we must use -o when running libtool.
|
||||||
|
"$@" || exit $?
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||||
|
set fnord "$@"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
"$@" -E |
|
||||||
|
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||||
|
echo " " >> "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
none)
|
||||||
|
exec "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown depmode $depmode" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
563
Libraries/WavPack/Files/extra1.c
Normal file
563
Libraries/WavPack/Files/extra1.c
Normal file
|
@ -0,0 +1,563 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// extra1.c
|
||||||
|
|
||||||
|
// This module handles the "extra" mode for mono files.
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// #define EXTRA_DUMP
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
#define malloc malloc_db
|
||||||
|
#define realloc realloc_db
|
||||||
|
#define free free_db
|
||||||
|
void *malloc_db (uint32_t size);
|
||||||
|
void *realloc_db (void *ptr, uint32_t size);
|
||||||
|
void free_db (void *ptr);
|
||||||
|
int32_t dump_alloc (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////// local tables ///////////////////////////////
|
||||||
|
|
||||||
|
extern const char default_terms [], high_terms [], fast_terms [];
|
||||||
|
|
||||||
|
// #define MINMAX_WEIGHTS
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
static int32_t min_weight, max_weight;
|
||||||
|
static int min_term, max_term;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void decorr_mono_pass (int32_t *in_samples, int32_t *out_samples, uint32_t num_samples, struct decorr_pass *dpp, int dir)
|
||||||
|
{
|
||||||
|
int m = 0;
|
||||||
|
|
||||||
|
dpp->sum_A = 0;
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
dpp->min = dpp->max = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dir < 0) {
|
||||||
|
out_samples += (num_samples - 1);
|
||||||
|
in_samples += (num_samples - 1);
|
||||||
|
dir = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dir = 1;
|
||||||
|
|
||||||
|
if (dpp->term > MAX_TERM) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int32_t left, sam_A;
|
||||||
|
|
||||||
|
if (dpp->term & 1)
|
||||||
|
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||||
|
else
|
||||||
|
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||||
|
|
||||||
|
dpp->samples_A [1] = dpp->samples_A [0];
|
||||||
|
dpp->samples_A [0] = left = in_samples [0];
|
||||||
|
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
#endif
|
||||||
|
out_samples [0] = left;
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpp->term > 0) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int k = (m + dpp->term) & (MAX_TERM - 1);
|
||||||
|
int32_t left, sam_A;
|
||||||
|
|
||||||
|
sam_A = dpp->samples_A [m];
|
||||||
|
dpp->samples_A [k] = left = in_samples [0];
|
||||||
|
m = (m + 1) & (MAX_TERM - 1);
|
||||||
|
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
#endif
|
||||||
|
out_samples [0] = left;
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->term != 0) {
|
||||||
|
if (dpp->max > max_weight) { max_weight = dpp->max; max_term = dpp->term; }
|
||||||
|
if (dpp->min < min_weight) { min_weight = dpp->min; min_term = dpp->term; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m && dpp->term > 0 && dpp->term <= MAX_TERM) {
|
||||||
|
int32_t temp_A [MAX_TERM];
|
||||||
|
int k;
|
||||||
|
|
||||||
|
memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A));
|
||||||
|
|
||||||
|
for (k = 0; k < MAX_TERM; k++) {
|
||||||
|
dpp->samples_A [k] = temp_A [m];
|
||||||
|
m = (m + 1) & (MAX_TERM - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reverse_mono_decorr (struct decorr_pass *dpp)
|
||||||
|
{
|
||||||
|
if (dpp->term > MAX_TERM) {
|
||||||
|
int32_t sam_A;
|
||||||
|
|
||||||
|
if (dpp->term & 1)
|
||||||
|
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||||
|
else
|
||||||
|
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||||
|
|
||||||
|
dpp->samples_A [1] = dpp->samples_A [0];
|
||||||
|
dpp->samples_A [0] = sam_A;
|
||||||
|
|
||||||
|
if (dpp->term & 1)
|
||||||
|
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||||
|
else
|
||||||
|
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||||
|
|
||||||
|
dpp->samples_A [1] = sam_A;
|
||||||
|
}
|
||||||
|
else if (dpp->term > 1) {
|
||||||
|
int i = 0, j = dpp->term - 1, cnt = dpp->term / 2;
|
||||||
|
|
||||||
|
while (cnt--) {
|
||||||
|
i &= (MAX_TERM - 1);
|
||||||
|
j &= (MAX_TERM - 1);
|
||||||
|
dpp->samples_A [i] ^= dpp->samples_A [j];
|
||||||
|
dpp->samples_A [j] ^= dpp->samples_A [i];
|
||||||
|
dpp->samples_A [i++] ^= dpp->samples_A [j--];
|
||||||
|
}
|
||||||
|
|
||||||
|
CLEAR (dpp->samples_A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void decorr_mono_buffer (int32_t *samples, int32_t *outsamples, uint32_t num_samples, struct decorr_pass *dpp)
|
||||||
|
{
|
||||||
|
int delta = dpp->delta, pre_delta, term = dpp->term;
|
||||||
|
struct decorr_pass dp;
|
||||||
|
|
||||||
|
if (delta == 7)
|
||||||
|
pre_delta = 7;
|
||||||
|
else if (delta < 2)
|
||||||
|
pre_delta = 3;
|
||||||
|
else
|
||||||
|
pre_delta = delta + 1;
|
||||||
|
|
||||||
|
CLEAR (dp);
|
||||||
|
dp.term = term;
|
||||||
|
dp.delta = pre_delta;
|
||||||
|
decorr_mono_pass (samples, outsamples, num_samples > 2048 ? 2048 : num_samples, &dp, -1);
|
||||||
|
dp.delta = delta;
|
||||||
|
reverse_mono_decorr (&dp);
|
||||||
|
memcpy (dpp->samples_A, dp.samples_A, sizeof (dp.samples_A));
|
||||||
|
dpp->weight_A = dp.weight_A;
|
||||||
|
|
||||||
|
if (delta == 0) {
|
||||||
|
dp.delta = 1;
|
||||||
|
decorr_mono_pass (samples, outsamples, num_samples, &dp, 1);
|
||||||
|
dp.delta = 0;
|
||||||
|
memcpy (dp.samples_A, dpp->samples_A, sizeof (dp.samples_A));
|
||||||
|
dpp->weight_A = dp.weight_A = dp.sum_A / num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (memcmp (dpp, &dp, sizeof (dp)))
|
||||||
|
// error_line ("decorr_passes don't match, delta = %d", delta);
|
||||||
|
|
||||||
|
decorr_mono_pass (samples, outsamples, num_samples, &dp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recurse_mono (WavpackContext *wpc, int32_t *sampleptrs[], struct decorr_pass dps[],
|
||||||
|
int depth, int nterms, int delta, uint32_t input_bits, uint32_t *best_bits)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
int term, branches = ((wpc->config.extra_flags & EXTRA_BRANCHES) >> 6) - depth;
|
||||||
|
int32_t *samples, *outsamples;
|
||||||
|
uint32_t term_bits [22], bits;
|
||||||
|
|
||||||
|
if (branches < 1 || depth + 1 == nterms)
|
||||||
|
branches = 1;
|
||||||
|
|
||||||
|
CLEAR (term_bits);
|
||||||
|
samples = sampleptrs [depth];
|
||||||
|
outsamples = sampleptrs [depth + 1];
|
||||||
|
|
||||||
|
for (term = 1; term <= 18; ++term) {
|
||||||
|
if (term == 17 && branches == 1 && depth + 1 < nterms)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (term >= 9 && term <= 16)
|
||||||
|
if (term > MAX_TERM || !(wpc->config.flags & CONFIG_HIGH_FLAG) || (wpc->config.extra_flags & EXTRA_SKIP_8TO16))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((wpc->config.flags & CONFIG_FAST_FLAG) && (term >= 5 && term <= 16))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dps [depth].term = term;
|
||||||
|
dps [depth].delta = delta;
|
||||||
|
decorr_mono_buffer (samples, outsamples, wps->wphdr.block_samples, &dps [depth]);
|
||||||
|
bits = log2buffer (outsamples, wps->wphdr.block_samples);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * (depth + 1));
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [depth + 1], wps->wphdr.block_samples * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
term_bits [term + 3] = bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (depth + 1 < nterms && branches--) {
|
||||||
|
uint32_t local_best_bits = input_bits;
|
||||||
|
int best_term = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < 22; ++i)
|
||||||
|
if (term_bits [i] && term_bits [i] < local_best_bits) {
|
||||||
|
local_best_bits = term_bits [i];
|
||||||
|
term_bits [i] = 0;
|
||||||
|
best_term = i - 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!best_term)
|
||||||
|
break;
|
||||||
|
|
||||||
|
dps [depth].term = best_term;
|
||||||
|
dps [depth].delta = delta;
|
||||||
|
decorr_mono_buffer (samples, outsamples, wps->wphdr.block_samples, &dps [depth]);
|
||||||
|
|
||||||
|
// if (log2buffer (outsamples, wps->wphdr.block_samples * 2) != local_best_bits)
|
||||||
|
// error_line ("data doesn't match!");
|
||||||
|
|
||||||
|
recurse_mono (wpc, sampleptrs, dps, depth + 1, nterms, delta, local_best_bits, best_bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delta_mono (WavpackContext *wpc, int32_t *sampleptrs[], struct decorr_pass dps[],
|
||||||
|
int nterms, uint32_t *best_bits)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
int lower = FALSE, delta, d;
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
if (wps->decorr_passes [0].term)
|
||||||
|
delta = wps->decorr_passes [0].delta;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (d = delta - 1; d >= 0; --d) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!d && (wps->wphdr.flags & HYBRID_FLAG))
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && wps->decorr_passes [i].term; ++i) {
|
||||||
|
dps [i].term = wps->decorr_passes [i].term;
|
||||||
|
dps [i].delta = d;
|
||||||
|
decorr_mono_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
lower = TRUE;
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (d = delta + 1; !lower && d <= 7; ++d) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && wps->decorr_passes [i].term; ++i) {
|
||||||
|
dps [i].term = wps->decorr_passes [i].term;
|
||||||
|
dps [i].delta = d;
|
||||||
|
decorr_mono_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort_mono (WavpackContext *wpc, int32_t *sampleptrs[], struct decorr_pass dps[],
|
||||||
|
int nterms, uint32_t *best_bits)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
int reversed = TRUE;
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
while (reversed) {
|
||||||
|
int ri, i;
|
||||||
|
|
||||||
|
memcpy (dps, wps->decorr_passes, sizeof (wps->decorr_passes));
|
||||||
|
reversed = FALSE;
|
||||||
|
|
||||||
|
for (ri = 0; ri < nterms && wps->decorr_passes [ri].term; ++ri) {
|
||||||
|
|
||||||
|
if (ri + 1 >= nterms || !wps->decorr_passes [ri+1].term)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (wps->decorr_passes [ri].term == wps->decorr_passes [ri+1].term) {
|
||||||
|
decorr_mono_buffer (sampleptrs [ri], sampleptrs [ri+1], wps->wphdr.block_samples, &dps [ri]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dps [ri] = wps->decorr_passes [ri+1];
|
||||||
|
dps [ri+1] = wps->decorr_passes [ri];
|
||||||
|
|
||||||
|
for (i = ri; i < nterms && wps->decorr_passes [i].term; ++i)
|
||||||
|
decorr_mono_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
reversed = TRUE;
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dps [ri] = wps->decorr_passes [ri];
|
||||||
|
dps [ri+1] = wps->decorr_passes [ri+1];
|
||||||
|
decorr_mono_buffer (sampleptrs [ri], sampleptrs [ri+1], wps->wphdr.block_samples, &dps [ri]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXTRA_ADVANCED (EXTRA_BRANCHES | EXTRA_SORT_FIRST | EXTRA_SORT_LAST | EXTRA_TRY_DELTAS)
|
||||||
|
|
||||||
|
void analyze_mono (WavpackContext *wpc, int32_t *samples)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
uint32_t bits, best_bits, default_bits, cnt;
|
||||||
|
#else
|
||||||
|
uint32_t bits, best_bits, cnt;
|
||||||
|
#endif
|
||||||
|
const char *decorr_terms = default_terms, *tp;
|
||||||
|
int32_t *sampleptrs [MAX_NTERMS+2], *lptr;
|
||||||
|
struct decorr_pass dps [MAX_NTERMS];
|
||||||
|
int nterms, i;
|
||||||
|
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
cnt = wps->wphdr.block_samples;
|
||||||
|
lptr = samples;
|
||||||
|
|
||||||
|
while (cnt--)
|
||||||
|
if (*lptr++)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (cnt == (uint32_t) -1) {
|
||||||
|
scan_word (wps, samples, wps->wphdr.block_samples, -1);
|
||||||
|
wps->num_terms = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpc->config.flags & CONFIG_HIGH_FLAG)
|
||||||
|
decorr_terms = high_terms;
|
||||||
|
else if (wpc->config.flags & CONFIG_FAST_FLAG)
|
||||||
|
decorr_terms = fast_terms;
|
||||||
|
|
||||||
|
for (nterms = 0, tp = decorr_terms; *tp; tp++)
|
||||||
|
if (*tp > 0)
|
||||||
|
++nterms;
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_TERMS)
|
||||||
|
if ((nterms += (wpc->config.extra_flags & EXTRA_TERMS) >> 10) > MAX_NTERMS)
|
||||||
|
nterms = MAX_NTERMS;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms + 2; ++i)
|
||||||
|
sampleptrs [i] = malloc (wps->wphdr.block_samples * 4);
|
||||||
|
|
||||||
|
memcpy (sampleptrs [nterms + 1], samples, wps->wphdr.block_samples * 4);
|
||||||
|
best_bits = log2buffer (sampleptrs [nterms + 1], wps->wphdr.block_samples);
|
||||||
|
memcpy (sampleptrs [0], samples, wps->wphdr.block_samples * 4);
|
||||||
|
CLEAR (dps);
|
||||||
|
|
||||||
|
for (tp = decorr_terms, i = 0; *tp; tp++)
|
||||||
|
if (*tp > 0) {
|
||||||
|
dps [i].term = *tp;
|
||||||
|
dps [i].delta = 2;
|
||||||
|
decorr_mono_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
default_bits = bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
#else
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bits < best_bits) {
|
||||||
|
best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wps->wphdr.flags & HYBRID_FLAG) && (wpc->config.extra_flags & EXTRA_ADVANCED)) {
|
||||||
|
int shaping_weight, new = wps->wphdr.flags & NEW_SHAPING;
|
||||||
|
int32_t *rptr = sampleptrs [nterms + 1], error = 0, temp;
|
||||||
|
|
||||||
|
scan_word (wps, rptr, wps->wphdr.block_samples, -1);
|
||||||
|
cnt = wps->wphdr.block_samples;
|
||||||
|
lptr = sampleptrs [0];
|
||||||
|
|
||||||
|
if (wps->wphdr.flags & HYBRID_SHAPE) {
|
||||||
|
while (cnt--) {
|
||||||
|
shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16;
|
||||||
|
temp = -apply_weight (shaping_weight, error);
|
||||||
|
|
||||||
|
if (new && shaping_weight < 0 && temp) {
|
||||||
|
if (temp == error)
|
||||||
|
temp = (temp < 0) ? temp + 1 : temp - 1;
|
||||||
|
|
||||||
|
lptr [0] += (error = nosend_word (wps, rptr [0], 0) - rptr [0] + temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lptr [0] += (error = nosend_word (wps, rptr [0], 0) - rptr [0]) + temp;
|
||||||
|
|
||||||
|
lptr++;
|
||||||
|
rptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wps->dc.shaping_acc [0] -= wps->dc.shaping_delta [0] * wps->wphdr.block_samples;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (cnt--) {
|
||||||
|
lptr [0] += nosend_word (wps, rptr [0], 0) - rptr [0];
|
||||||
|
lptr++;
|
||||||
|
rptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (dps, wps->decorr_passes, sizeof (dps));
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && dps [i].term; ++i)
|
||||||
|
decorr_mono_buffer (sampleptrs [i], sampleptrs [i + 1], wps->wphdr.block_samples, dps + i);
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
best_bits = default_bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
#else
|
||||||
|
best_bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_BRANCHES)
|
||||||
|
recurse_mono (wpc, sampleptrs, dps, 0, nterms, (int) floor (wps->delta_decay + 0.5),
|
||||||
|
log2buffer (sampleptrs [0], wps->wphdr.block_samples), &best_bits);
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_SORT_FIRST)
|
||||||
|
sort_mono (wpc, sampleptrs, dps, nterms, &best_bits);
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_TRY_DELTAS) {
|
||||||
|
delta_mono (wpc, sampleptrs, dps, nterms, &best_bits);
|
||||||
|
|
||||||
|
if ((wpc->config.extra_flags & EXTRA_ADJUST_DELTAS) && wps->decorr_passes [0].term)
|
||||||
|
wps->delta_decay = (wps->delta_decay * 2.0 + wps->decorr_passes [0].delta) / 3.0;
|
||||||
|
else
|
||||||
|
wps->delta_decay = 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_SORT_LAST)
|
||||||
|
sort_mono (wpc, sampleptrs, dps, nterms, &best_bits);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
memcpy (dps, wps->decorr_passes, sizeof (dps));
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && dps [i].term; ++i)
|
||||||
|
decorr_mono_pass (sampleptrs [i], sampleptrs [i + 1], wps->wphdr.block_samples, dps + i, 1);
|
||||||
|
|
||||||
|
if (log2buffer (sampleptrs [i], wps->wphdr.block_samples) != best_bits)
|
||||||
|
error_line ("(1) samples do not match!");
|
||||||
|
|
||||||
|
if (log2buffer (sampleptrs [nterms + 1], wps->wphdr.block_samples) != best_bits)
|
||||||
|
error_line ("(2) samples do not match!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scan_word (wps, sampleptrs [nterms + 1], wps->wphdr.block_samples, -1);
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
if (wpc->config.extra_flags & EXTRA_DUMP_TERMS) {
|
||||||
|
char string [256], substring [20];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf (string, "M: delta = %.4f%%, terms =",
|
||||||
|
((double) best_bits - default_bits) / 256.0 / wps->wphdr.block_samples / 32.0 * 100.0);
|
||||||
|
|
||||||
|
for (i = 0; i < nterms; ++i) {
|
||||||
|
if (wps->decorr_passes [i].term) {
|
||||||
|
if (i && wps->decorr_passes [i-1].delta == wps->decorr_passes [i].delta)
|
||||||
|
sprintf (substring, " %d", wps->decorr_passes [i].term);
|
||||||
|
else
|
||||||
|
sprintf (substring, " %d->%d", wps->decorr_passes [i].term,
|
||||||
|
wps->decorr_passes [i].delta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf (substring, " *");
|
||||||
|
|
||||||
|
strcat (string, substring);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_line (string);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < nterms; ++i)
|
||||||
|
if (!wps->decorr_passes [i].term)
|
||||||
|
break;
|
||||||
|
|
||||||
|
wps->num_terms = i;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms + 2; ++i)
|
||||||
|
free (sampleptrs [i]);
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
error_line ("weight range = %ld (%d) to %ld (%d)", min_weight, min_term, max_weight, max_term);
|
||||||
|
#endif
|
||||||
|
}
|
792
Libraries/WavPack/Files/extra2.c
Normal file
792
Libraries/WavPack/Files/extra2.c
Normal file
|
@ -0,0 +1,792 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// extra2.c
|
||||||
|
|
||||||
|
// This module handles the "extra" mode for stereo files.
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// #define EXTRA_DUMP
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
#define malloc malloc_db
|
||||||
|
#define realloc realloc_db
|
||||||
|
#define free free_db
|
||||||
|
void *malloc_db (uint32_t size);
|
||||||
|
void *realloc_db (void *ptr, uint32_t size);
|
||||||
|
void free_db (void *ptr);
|
||||||
|
int32_t dump_alloc (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const char default_terms [], high_terms [], fast_terms [];
|
||||||
|
|
||||||
|
// #define MINMAX_WEIGHTS
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
static int32_t min_weight, max_weight;
|
||||||
|
static int min_term, max_term;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void decorr_stereo_pass (int32_t *in_samples, int32_t *out_samples, int32_t num_samples, struct decorr_pass *dpp, int dir)
|
||||||
|
{
|
||||||
|
int m = 0;
|
||||||
|
|
||||||
|
dpp->sum_A = dpp->sum_B = 0;
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
dpp->min = dpp->max = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dir < 0) {
|
||||||
|
out_samples += (num_samples - 1) * 2;
|
||||||
|
in_samples += (num_samples - 1) * 2;
|
||||||
|
dir = -2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dir = 2;
|
||||||
|
|
||||||
|
if (dpp->term == 17) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int32_t left, right;
|
||||||
|
int32_t sam_A, sam_B;
|
||||||
|
|
||||||
|
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||||
|
dpp->samples_A [1] = dpp->samples_A [0];
|
||||||
|
dpp->samples_A [0] = left = in_samples [0];
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
out_samples [0] = left;
|
||||||
|
|
||||||
|
sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1];
|
||||||
|
dpp->samples_B [1] = dpp->samples_B [0];
|
||||||
|
dpp->samples_B [0] = right = in_samples [1];
|
||||||
|
right -= apply_weight (dpp->weight_B, sam_B);
|
||||||
|
update_weight (dpp->weight_B, dpp->delta, sam_B, right);
|
||||||
|
dpp->sum_B += dpp->weight_B;
|
||||||
|
out_samples [1] = right;
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_B > dpp->max) dpp->max = dpp->weight_B;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
if (dpp->weight_B < dpp->min) dpp->min = dpp->weight_B;
|
||||||
|
#endif
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpp->term == 18) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int32_t left, right;
|
||||||
|
int32_t sam_A, sam_B;
|
||||||
|
|
||||||
|
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||||
|
dpp->samples_A [1] = dpp->samples_A [0];
|
||||||
|
dpp->samples_A [0] = left = in_samples [0];
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
out_samples [0] = left;
|
||||||
|
|
||||||
|
sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
|
||||||
|
dpp->samples_B [1] = dpp->samples_B [0];
|
||||||
|
dpp->samples_B [0] = right = in_samples [1];
|
||||||
|
right -= apply_weight (dpp->weight_B, sam_B);
|
||||||
|
update_weight (dpp->weight_B, dpp->delta, sam_B, right);
|
||||||
|
dpp->sum_B += dpp->weight_B;
|
||||||
|
out_samples [1] = right;
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_B > dpp->max) dpp->max = dpp->weight_B;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
if (dpp->weight_B < dpp->min) dpp->min = dpp->weight_B;
|
||||||
|
#endif
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpp->term > 0) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int k = (m + dpp->term) & (MAX_TERM - 1);
|
||||||
|
int32_t left, right;
|
||||||
|
int32_t sam_A, sam_B;
|
||||||
|
|
||||||
|
sam_A = dpp->samples_A [m];
|
||||||
|
dpp->samples_A [k] = left = in_samples [0];
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
out_samples [0] = left;
|
||||||
|
|
||||||
|
sam_B = dpp->samples_B [m];
|
||||||
|
dpp->samples_B [k] = right = in_samples [1];
|
||||||
|
right -= apply_weight (dpp->weight_B, sam_B);
|
||||||
|
update_weight (dpp->weight_B, dpp->delta, sam_B, right);
|
||||||
|
dpp->sum_B += dpp->weight_B;
|
||||||
|
out_samples [1] = right;
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_B > dpp->max) dpp->max = dpp->weight_B;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
if (dpp->weight_B < dpp->min) dpp->min = dpp->weight_B;
|
||||||
|
#endif
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
m = (m + 1) & (MAX_TERM - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpp->term == -1) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int32_t left = in_samples [0];
|
||||||
|
int32_t right = in_samples [1];
|
||||||
|
int32_t sam_A = dpp->samples_A [0], sam_B = left;
|
||||||
|
|
||||||
|
dpp->samples_A [0] = right;
|
||||||
|
right -= apply_weight (dpp->weight_B, sam_B);
|
||||||
|
update_weight_clip (dpp->weight_B, dpp->delta, sam_B, right);
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight_clip (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
dpp->sum_B += dpp->weight_B;
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_B > dpp->max) dpp->max = dpp->weight_B;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
if (dpp->weight_B < dpp->min) dpp->min = dpp->weight_B;
|
||||||
|
#endif
|
||||||
|
out_samples [0] = left;
|
||||||
|
out_samples [1] = right;
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpp->term == -2) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int32_t left = in_samples [0];
|
||||||
|
int32_t right = in_samples [1];
|
||||||
|
int32_t sam_B = dpp->samples_B [0], sam_A = right;
|
||||||
|
|
||||||
|
dpp->samples_B [0] = left;
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight_clip (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
right -= apply_weight (dpp->weight_B, sam_B);
|
||||||
|
update_weight_clip (dpp->weight_B, dpp->delta, sam_B, right);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
dpp->sum_B += dpp->weight_B;
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_B > dpp->max) dpp->max = dpp->weight_B;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
if (dpp->weight_B < dpp->min) dpp->min = dpp->weight_B;
|
||||||
|
#endif
|
||||||
|
out_samples [0] = left;
|
||||||
|
out_samples [1] = right;
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpp->term == -3) {
|
||||||
|
while (num_samples--) {
|
||||||
|
int32_t left = in_samples [0];
|
||||||
|
int32_t right = in_samples [1];
|
||||||
|
int32_t sam_A = dpp->samples_A [0], sam_B = dpp->samples_B [0];
|
||||||
|
|
||||||
|
dpp->samples_A [0] = right;
|
||||||
|
dpp->samples_B [0] = left;
|
||||||
|
left -= apply_weight (dpp->weight_A, sam_A);
|
||||||
|
update_weight_clip (dpp->weight_A, dpp->delta, sam_A, left);
|
||||||
|
right -= apply_weight (dpp->weight_B, sam_B);
|
||||||
|
update_weight_clip (dpp->weight_B, dpp->delta, sam_B, right);
|
||||||
|
dpp->sum_A += dpp->weight_A;
|
||||||
|
dpp->sum_B += dpp->weight_B;
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->weight_A > dpp->max) dpp->max = dpp->weight_A;
|
||||||
|
if (dpp->weight_B > dpp->max) dpp->max = dpp->weight_B;
|
||||||
|
if (dpp->weight_A < dpp->min) dpp->min = dpp->weight_A;
|
||||||
|
if (dpp->weight_B < dpp->min) dpp->min = dpp->weight_B;
|
||||||
|
#endif
|
||||||
|
out_samples [0] = left;
|
||||||
|
out_samples [1] = right;
|
||||||
|
in_samples += dir;
|
||||||
|
out_samples += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
if (dpp->term != 0) {
|
||||||
|
if (dpp->max > max_weight) { max_weight = dpp->max; max_term = dpp->term; }
|
||||||
|
if (dpp->min < min_weight) { min_weight = dpp->min; min_term = dpp->term; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m && dpp->term > 0 && dpp->term <= MAX_TERM) {
|
||||||
|
int32_t temp_A [MAX_TERM], temp_B [MAX_TERM];
|
||||||
|
int k;
|
||||||
|
|
||||||
|
memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A));
|
||||||
|
memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B));
|
||||||
|
|
||||||
|
for (k = 0; k < MAX_TERM; k++) {
|
||||||
|
dpp->samples_A [k] = temp_A [m];
|
||||||
|
dpp->samples_B [k] = temp_B [m];
|
||||||
|
m = (m + 1) & (MAX_TERM - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reverse_decorr (struct decorr_pass *dpp)
|
||||||
|
{
|
||||||
|
if (dpp->term > MAX_TERM) {
|
||||||
|
int32_t sam_A, sam_B;
|
||||||
|
|
||||||
|
if (dpp->term & 1) {
|
||||||
|
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||||
|
sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||||
|
sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dpp->samples_A [1] = dpp->samples_A [0];
|
||||||
|
dpp->samples_B [1] = dpp->samples_B [0];
|
||||||
|
dpp->samples_A [0] = sam_A;
|
||||||
|
dpp->samples_B [0] = sam_B;
|
||||||
|
|
||||||
|
if (dpp->term & 1) {
|
||||||
|
sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
|
||||||
|
sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
|
||||||
|
sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dpp->samples_A [1] = sam_A;
|
||||||
|
dpp->samples_B [1] = sam_B;
|
||||||
|
}
|
||||||
|
else if (dpp->term > 1) {
|
||||||
|
int i = 0, j = dpp->term - 1, cnt = dpp->term / 2;
|
||||||
|
|
||||||
|
while (cnt--) {
|
||||||
|
i &= (MAX_TERM - 1);
|
||||||
|
j &= (MAX_TERM - 1);
|
||||||
|
dpp->samples_A [i] ^= dpp->samples_A [j];
|
||||||
|
dpp->samples_A [j] ^= dpp->samples_A [i];
|
||||||
|
dpp->samples_A [i] ^= dpp->samples_A [j];
|
||||||
|
dpp->samples_B [i] ^= dpp->samples_B [j];
|
||||||
|
dpp->samples_B [j] ^= dpp->samples_B [i];
|
||||||
|
dpp->samples_B [i++] ^= dpp->samples_B [j--];
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLEAR (dpp->samples_A);
|
||||||
|
// CLEAR (dpp->samples_B);
|
||||||
|
}
|
||||||
|
else if (dpp->term == -1) {
|
||||||
|
}
|
||||||
|
else if (dpp->term == -2) {
|
||||||
|
}
|
||||||
|
else if (dpp->term == -3) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void decorr_stereo_buffer (int32_t *samples, int32_t *outsamples, int32_t num_samples, struct decorr_pass *dpp)
|
||||||
|
{
|
||||||
|
int delta = dpp->delta, pre_delta;
|
||||||
|
int term = dpp->term;
|
||||||
|
struct decorr_pass dp;
|
||||||
|
|
||||||
|
if (delta == 7)
|
||||||
|
pre_delta = 7;
|
||||||
|
else if (delta < 2)
|
||||||
|
pre_delta = 3;
|
||||||
|
else
|
||||||
|
pre_delta = delta + 1;
|
||||||
|
|
||||||
|
CLEAR (dp);
|
||||||
|
dp.term = term;
|
||||||
|
dp.delta = pre_delta;
|
||||||
|
decorr_stereo_pass (samples, outsamples, num_samples > 2048 ? 2048 : num_samples, &dp, -1);
|
||||||
|
dp.delta = delta;
|
||||||
|
reverse_decorr (&dp);
|
||||||
|
memcpy (dpp->samples_A, dp.samples_A, sizeof (dp.samples_A));
|
||||||
|
memcpy (dpp->samples_B, dp.samples_B, sizeof (dp.samples_B));
|
||||||
|
dpp->weight_A = dp.weight_A;
|
||||||
|
dpp->weight_B = dp.weight_B;
|
||||||
|
|
||||||
|
if (delta == 0) {
|
||||||
|
dp.delta = 1;
|
||||||
|
decorr_stereo_pass (samples, outsamples, num_samples, &dp, 1);
|
||||||
|
dp.delta = 0;
|
||||||
|
memcpy (dp.samples_A, dpp->samples_A, sizeof (dp.samples_A));
|
||||||
|
memcpy (dp.samples_B, dpp->samples_B, sizeof (dp.samples_B));
|
||||||
|
dpp->weight_A = dp.weight_A = dp.sum_A / num_samples;
|
||||||
|
dpp->weight_B = dp.weight_B = dp.sum_B / num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (memcmp (dpp, &dp, sizeof (dp)))
|
||||||
|
// error_line ("decorr_passes don't match, delta = %d", delta);
|
||||||
|
|
||||||
|
decorr_stereo_pass (samples, outsamples, num_samples, &dp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recurse_stereo (WavpackContext *wpc, int32_t *sampleptrs[], struct decorr_pass dps[],
|
||||||
|
int depth, int nterms, int delta, uint32_t input_bits, uint32_t *best_bits)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
int term, branches = ((wpc->config.extra_flags & EXTRA_BRANCHES) >> 6) - depth;
|
||||||
|
int32_t *samples, *outsamples;
|
||||||
|
uint32_t term_bits [22], bits;
|
||||||
|
|
||||||
|
if (branches < 1 || depth + 1 == nterms)
|
||||||
|
branches = 1;
|
||||||
|
|
||||||
|
CLEAR (term_bits);
|
||||||
|
samples = sampleptrs [depth];
|
||||||
|
outsamples = sampleptrs [depth + 1];
|
||||||
|
|
||||||
|
for (term = -3; term <= 18; ++term) {
|
||||||
|
if (!term)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (term == 17 && branches == 1 && depth + 1 < nterms)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (term == -1 || term == -2)
|
||||||
|
if (!(wps->wphdr.flags & CROSS_DECORR))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (term >= 9 && term <= 16)
|
||||||
|
if (term > MAX_TERM || !(wpc->config.flags & CONFIG_HIGH_FLAG) || (wpc->config.extra_flags & EXTRA_SKIP_8TO16))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((wpc->config.flags & CONFIG_FAST_FLAG) && (term >= 5 && term <= 16))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dps [depth].term = term;
|
||||||
|
dps [depth].delta = delta;
|
||||||
|
decorr_stereo_buffer (samples, outsamples, wps->wphdr.block_samples, &dps [depth]);
|
||||||
|
bits = log2buffer (outsamples, wps->wphdr.block_samples * 2);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * (depth + 1));
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [depth + 1], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
term_bits [term + 3] = bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (depth + 1 < nterms && branches--) {
|
||||||
|
uint32_t local_best_bits = input_bits;
|
||||||
|
int best_term = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < 22; ++i)
|
||||||
|
if (term_bits [i] && term_bits [i] < local_best_bits) {
|
||||||
|
local_best_bits = term_bits [i];
|
||||||
|
term_bits [i] = 0;
|
||||||
|
best_term = i - 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!best_term)
|
||||||
|
break;
|
||||||
|
|
||||||
|
dps [depth].term = best_term;
|
||||||
|
dps [depth].delta = delta;
|
||||||
|
decorr_stereo_buffer (samples, outsamples, wps->wphdr.block_samples, &dps [depth]);
|
||||||
|
|
||||||
|
// if (log2buffer (outsamples, wps->wphdr.block_samples * 2) != local_best_bits)
|
||||||
|
// error_line ("data doesn't match!");
|
||||||
|
|
||||||
|
recurse_stereo (wpc, sampleptrs, dps, depth + 1, nterms, delta, local_best_bits, best_bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delta_stereo (WavpackContext *wpc, int32_t *sampleptrs[], struct decorr_pass dps[],
|
||||||
|
int nterms, uint32_t *best_bits)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
int lower = FALSE;
|
||||||
|
int delta, d;
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
if (wps->decorr_passes [0].term)
|
||||||
|
delta = wps->decorr_passes [0].delta;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (d = delta - 1; d >= 0; --d) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!d && (wps->wphdr.flags & HYBRID_FLAG))
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && wps->decorr_passes [i].term; ++i) {
|
||||||
|
dps [i].term = wps->decorr_passes [i].term;
|
||||||
|
dps [i].delta = d;
|
||||||
|
decorr_stereo_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
lower = TRUE;
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (d = delta + 1; !lower && d <= 7; ++d) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && wps->decorr_passes [i].term; ++i) {
|
||||||
|
dps [i].term = wps->decorr_passes [i].term;
|
||||||
|
dps [i].delta = d;
|
||||||
|
decorr_stereo_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort_stereo (WavpackContext *wpc, int32_t *sampleptrs[], struct decorr_pass dps[],
|
||||||
|
int nterms, uint32_t *best_bits)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
int reversed = TRUE;
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
while (reversed) {
|
||||||
|
int ri, i;
|
||||||
|
|
||||||
|
memcpy (dps, wps->decorr_passes, sizeof (wps->decorr_passes));
|
||||||
|
reversed = FALSE;
|
||||||
|
|
||||||
|
for (ri = 0; ri < nterms && wps->decorr_passes [ri].term; ++ri) {
|
||||||
|
|
||||||
|
if (ri + 1 >= nterms || !wps->decorr_passes [ri+1].term)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (wps->decorr_passes [ri].term == wps->decorr_passes [ri+1].term) {
|
||||||
|
decorr_stereo_buffer (sampleptrs [ri], sampleptrs [ri+1], wps->wphdr.block_samples, &dps [ri]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dps [ri] = wps->decorr_passes [ri+1];
|
||||||
|
dps [ri+1] = wps->decorr_passes [ri];
|
||||||
|
|
||||||
|
for (i = ri; i < nterms && wps->decorr_passes [i].term; ++i)
|
||||||
|
decorr_stereo_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
|
||||||
|
if (bits < *best_bits) {
|
||||||
|
reversed = TRUE;
|
||||||
|
*best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dps [ri] = wps->decorr_passes [ri];
|
||||||
|
dps [ri+1] = wps->decorr_passes [ri+1];
|
||||||
|
decorr_stereo_buffer (sampleptrs [ri], sampleptrs [ri+1], wps->wphdr.block_samples, &dps [ri]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXTRA_ADVANCED (EXTRA_BRANCHES | EXTRA_SORT_FIRST | EXTRA_SORT_LAST | EXTRA_TRY_DELTAS)
|
||||||
|
|
||||||
|
void analyze_stereo (WavpackContext *wpc, int32_t *samples)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
uint32_t bits, best_bits, default_bits, cnt;
|
||||||
|
#else
|
||||||
|
uint32_t bits, best_bits, cnt;
|
||||||
|
#endif
|
||||||
|
const char *decorr_terms = default_terms, *tp;
|
||||||
|
int32_t *sampleptrs [MAX_NTERMS+2], *lptr;
|
||||||
|
struct decorr_pass dps [MAX_NTERMS];
|
||||||
|
int nterms, i;
|
||||||
|
|
||||||
|
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
cnt = wps->wphdr.block_samples * 2;
|
||||||
|
lptr = samples;
|
||||||
|
|
||||||
|
while (cnt--)
|
||||||
|
if (*lptr++)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (cnt == (uint32_t) -1) {
|
||||||
|
scan_word (wps, samples, wps->wphdr.block_samples, -1);
|
||||||
|
wps->num_terms = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpc->config.flags & CONFIG_HIGH_FLAG)
|
||||||
|
decorr_terms = high_terms;
|
||||||
|
else if (wpc->config.flags & CONFIG_FAST_FLAG)
|
||||||
|
decorr_terms = fast_terms;
|
||||||
|
|
||||||
|
nterms = strlen (decorr_terms);
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_TERMS)
|
||||||
|
if ((nterms += (wpc->config.extra_flags & EXTRA_TERMS) >> 10) > MAX_NTERMS)
|
||||||
|
nterms = MAX_NTERMS;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms + 2; ++i)
|
||||||
|
sampleptrs [i] = malloc (wps->wphdr.block_samples * 8);
|
||||||
|
|
||||||
|
memcpy (sampleptrs [nterms + 1], samples, wps->wphdr.block_samples * 8);
|
||||||
|
best_bits = log2buffer (sampleptrs [nterms + 1], wps->wphdr.block_samples * 2);
|
||||||
|
|
||||||
|
if ((wpc->config.extra_flags & EXTRA_STEREO_MODES) || !(wps->wphdr.flags & JOINT_STEREO)) {
|
||||||
|
memcpy (sampleptrs [0], samples, wps->wphdr.block_samples * 8);
|
||||||
|
|
||||||
|
CLEAR (dps);
|
||||||
|
|
||||||
|
for (tp = decorr_terms, i = 0; *tp;) {
|
||||||
|
if (*tp > 0 || (wps->wphdr.flags & CROSS_DECORR))
|
||||||
|
dps [i].term = *tp++;
|
||||||
|
else {
|
||||||
|
dps [i].term = -3;
|
||||||
|
tp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dps [i].delta = 2;
|
||||||
|
decorr_stereo_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
default_bits = bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
#else
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wps->wphdr.flags &= ~JOINT_STEREO;
|
||||||
|
|
||||||
|
if (bits < best_bits) {
|
||||||
|
best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wpc->config.extra_flags & EXTRA_STEREO_MODES) || (wps->wphdr.flags & JOINT_STEREO)) {
|
||||||
|
memcpy (sampleptrs [0], samples, wps->wphdr.block_samples * 8);
|
||||||
|
cnt = wps->wphdr.block_samples;
|
||||||
|
lptr = sampleptrs [0];
|
||||||
|
|
||||||
|
while (cnt--) {
|
||||||
|
lptr [1] += ((lptr [0] -= lptr [1]) >> 1);
|
||||||
|
lptr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLEAR (dps);
|
||||||
|
|
||||||
|
for (tp = decorr_terms, i = 0; *tp;) {
|
||||||
|
if (*tp > 0 || (wps->wphdr.flags & CROSS_DECORR))
|
||||||
|
dps [i].term = *tp++;
|
||||||
|
else {
|
||||||
|
dps [i].term = -3;
|
||||||
|
tp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dps [i].delta = 2;
|
||||||
|
decorr_stereo_buffer (sampleptrs [i], sampleptrs [i+1], wps->wphdr.block_samples, &dps [i]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
default_bits = bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
#else
|
||||||
|
bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wps->wphdr.flags |= JOINT_STEREO;
|
||||||
|
|
||||||
|
if (bits < best_bits) {
|
||||||
|
best_bits = bits;
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy (sampleptrs [0], samples, wps->wphdr.block_samples * 8);
|
||||||
|
wps->wphdr.flags &= ~JOINT_STEREO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wps->wphdr.flags & HYBRID_FLAG) && (wpc->config.extra_flags & EXTRA_ADVANCED)) {
|
||||||
|
int shaping_weight, new = wps->wphdr.flags & NEW_SHAPING;
|
||||||
|
int32_t *rptr = sampleptrs [nterms + 1], error [2], temp;
|
||||||
|
|
||||||
|
scan_word (wps, rptr, wps->wphdr.block_samples, -1);
|
||||||
|
cnt = wps->wphdr.block_samples;
|
||||||
|
lptr = sampleptrs [0];
|
||||||
|
CLEAR (error);
|
||||||
|
|
||||||
|
if (wps->wphdr.flags & HYBRID_SHAPE) {
|
||||||
|
while (cnt--) {
|
||||||
|
shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16;
|
||||||
|
temp = -apply_weight (shaping_weight, error [0]);
|
||||||
|
|
||||||
|
if (new && shaping_weight < 0 && temp) {
|
||||||
|
if (temp == error [0])
|
||||||
|
temp = (temp < 0) ? temp + 1 : temp - 1;
|
||||||
|
|
||||||
|
lptr [0] += (error [0] = nosend_word (wps, rptr [0], 0) - rptr [0] + temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lptr [0] += (error [0] = nosend_word (wps, rptr [0], 0) - rptr [0]) + temp;
|
||||||
|
|
||||||
|
shaping_weight = (wps->dc.shaping_acc [1] += wps->dc.shaping_delta [1]) >> 16;
|
||||||
|
temp = -apply_weight (shaping_weight, error [1]);
|
||||||
|
|
||||||
|
if (new && shaping_weight < 0 && temp) {
|
||||||
|
if (temp == error [1])
|
||||||
|
temp = (temp < 0) ? temp + 1 : temp - 1;
|
||||||
|
|
||||||
|
lptr [1] += (error [1] = nosend_word (wps, rptr [1], 1) - rptr [1] + temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lptr [1] += (error [1] = nosend_word (wps, rptr [1], 1) - rptr [1]) + temp;
|
||||||
|
|
||||||
|
lptr += 2;
|
||||||
|
rptr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
wps->dc.shaping_acc [0] -= wps->dc.shaping_delta [0] * wps->wphdr.block_samples;
|
||||||
|
wps->dc.shaping_acc [1] -= wps->dc.shaping_delta [1] * wps->wphdr.block_samples;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (cnt--) {
|
||||||
|
lptr [0] += nosend_word (wps, rptr [0], 0) - rptr [0];
|
||||||
|
lptr [1] += nosend_word (wps, rptr [1], 1) - rptr [1];
|
||||||
|
lptr += 2;
|
||||||
|
rptr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (dps, wps->decorr_passes, sizeof (dps));
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && dps [i].term; ++i)
|
||||||
|
decorr_stereo_buffer (sampleptrs [i], sampleptrs [i + 1], wps->wphdr.block_samples, dps + i);
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
best_bits = default_bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
#else
|
||||||
|
best_bits = log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CLEAR (wps->decorr_passes);
|
||||||
|
memcpy (wps->decorr_passes, dps, sizeof (dps [0]) * i);
|
||||||
|
memcpy (sampleptrs [nterms + 1], sampleptrs [i], wps->wphdr.block_samples * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_BRANCHES)
|
||||||
|
recurse_stereo (wpc, sampleptrs, dps, 0, nterms, (int) floor (wps->delta_decay + 0.5),
|
||||||
|
log2buffer (sampleptrs [0], wps->wphdr.block_samples * 2), &best_bits);
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_SORT_FIRST)
|
||||||
|
sort_stereo (wpc, sampleptrs, dps, nterms, &best_bits);
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_TRY_DELTAS) {
|
||||||
|
delta_stereo (wpc, sampleptrs, dps, nterms, &best_bits);
|
||||||
|
|
||||||
|
if ((wpc->config.extra_flags & EXTRA_ADJUST_DELTAS) && wps->decorr_passes [0].term)
|
||||||
|
wps->delta_decay = (wps->delta_decay * 2.0 + wps->decorr_passes [0].delta) / 3.0;
|
||||||
|
else
|
||||||
|
wps->delta_decay = 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpc->config.extra_flags & EXTRA_SORT_LAST)
|
||||||
|
sort_stereo (wpc, sampleptrs, dps, nterms, &best_bits);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
memcpy (dps, wps->decorr_passes, sizeof (dps));
|
||||||
|
|
||||||
|
for (i = 0; i < nterms && dps [i].term; ++i)
|
||||||
|
decorr_stereo_pass (sampleptrs [i], sampleptrs [i + 1], wps->wphdr.block_samples, dps + i, 1);
|
||||||
|
|
||||||
|
if (log2buffer (sampleptrs [i], wps->wphdr.block_samples * 2) != best_bits)
|
||||||
|
error_line ("(1) samples do not match!");
|
||||||
|
|
||||||
|
if (log2buffer (sampleptrs [nterms + 1], wps->wphdr.block_samples * 2) != best_bits)
|
||||||
|
error_line ("(2) samples do not match!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scan_word (wps, sampleptrs [nterms + 1], wps->wphdr.block_samples, -1);
|
||||||
|
|
||||||
|
#ifdef EXTRA_DUMP
|
||||||
|
if (1) {
|
||||||
|
char string [256], substring [20];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf (string, "%s: delta = %.4f%%, terms =",
|
||||||
|
(wps->wphdr.flags & JOINT_STEREO) ? "JS" : "TS",
|
||||||
|
((double) best_bits - default_bits) / 256.0 / wps->wphdr.block_samples / 32.0 * 100.0);
|
||||||
|
|
||||||
|
for (i = 0; i < nterms; ++i) {
|
||||||
|
if (wps->decorr_passes [i].term) {
|
||||||
|
if (i && wps->decorr_passes [i-1].delta == wps->decorr_passes [i].delta)
|
||||||
|
sprintf (substring, " %d", wps->decorr_passes [i].term);
|
||||||
|
else
|
||||||
|
sprintf (substring, " %d->%d", wps->decorr_passes [i].term,
|
||||||
|
wps->decorr_passes [i].delta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf (substring, " *");
|
||||||
|
|
||||||
|
strcat (string, substring);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_line (string);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < nterms; ++i)
|
||||||
|
if (!wps->decorr_passes [i].term)
|
||||||
|
break;
|
||||||
|
|
||||||
|
wps->num_terms = i;
|
||||||
|
|
||||||
|
for (i = 0; i < nterms + 2; ++i)
|
||||||
|
free (sampleptrs [i]);
|
||||||
|
|
||||||
|
#ifdef MINMAX_WEIGHTS
|
||||||
|
error_line ("weight range = %ld (%d) to %ld (%d)", min_weight, min_term, max_weight, max_term);
|
||||||
|
#endif
|
||||||
|
}
|
371
Libraries/WavPack/Files/float.c
Normal file
371
Libraries/WavPack/Files/float.c
Normal file
|
@ -0,0 +1,371 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// float.c
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
#define malloc malloc_db
|
||||||
|
#define realloc realloc_db
|
||||||
|
#define free free_db
|
||||||
|
void *malloc_db (uint32_t size);
|
||||||
|
void *realloc_db (void *ptr, uint32_t size);
|
||||||
|
void free_db (void *ptr);
|
||||||
|
int32_t dump_alloc (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK
|
||||||
|
|
||||||
|
void write_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
|
{
|
||||||
|
char *byteptr;
|
||||||
|
|
||||||
|
byteptr = wpmd->data = malloc (4);
|
||||||
|
wpmd->id = ID_FLOAT_INFO;
|
||||||
|
*byteptr++ = wps->float_flags;
|
||||||
|
*byteptr++ = wps->float_shift;
|
||||||
|
*byteptr++ = wps->float_max_exp;
|
||||||
|
*byteptr++ = wps->float_norm_exp;
|
||||||
|
wpmd->byte_length = byteptr - (char *) wpmd->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values)
|
||||||
|
{
|
||||||
|
int32_t shifted_ones = 0, shifted_zeros = 0, shifted_both = 0;
|
||||||
|
int32_t false_zeros = 0, neg_zeros = 0;
|
||||||
|
uint32_t ordata = 0, crc = 0xffffffff;
|
||||||
|
int max_exp = 0, shift_count;
|
||||||
|
int32_t count, value;
|
||||||
|
f32 *dp;
|
||||||
|
|
||||||
|
wps->float_shift = wps->float_flags = 0;
|
||||||
|
|
||||||
|
for (dp = values, count = num_values; count--; dp++) {
|
||||||
|
crc = crc * 27 + dp->mantissa * 9 + dp->exponent * 3 + dp->sign;
|
||||||
|
|
||||||
|
if (dp->exponent > max_exp && dp->exponent < 255)
|
||||||
|
max_exp = dp->exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
wps->crc_x = crc;
|
||||||
|
|
||||||
|
for (dp = values, count = num_values; count--; dp++) {
|
||||||
|
if (dp->exponent == 255) {
|
||||||
|
wps->float_flags |= FLOAT_EXCEPTIONS;
|
||||||
|
value = 0x1000000;
|
||||||
|
shift_count = 0;
|
||||||
|
}
|
||||||
|
else if (dp->exponent) {
|
||||||
|
shift_count = max_exp - dp->exponent;
|
||||||
|
value = 0x800000 + dp->mantissa;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
shift_count = max_exp ? max_exp - 1 : 0;
|
||||||
|
value = dp->mantissa;
|
||||||
|
|
||||||
|
// if (dp->mantissa)
|
||||||
|
// denormals++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift_count < 25)
|
||||||
|
value >>= shift_count;
|
||||||
|
else
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
if (dp->exponent || dp->mantissa)
|
||||||
|
++false_zeros;
|
||||||
|
else if (dp->sign)
|
||||||
|
++neg_zeros;
|
||||||
|
}
|
||||||
|
else if (shift_count) {
|
||||||
|
int32_t mask = (1 << shift_count) - 1;
|
||||||
|
|
||||||
|
if (!(dp->mantissa & mask))
|
||||||
|
shifted_zeros++;
|
||||||
|
else if ((dp->mantissa & mask) == mask)
|
||||||
|
shifted_ones++;
|
||||||
|
else
|
||||||
|
shifted_both++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ordata |= value;
|
||||||
|
* (int32_t *) dp = (dp->sign) ? -value : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
wps->float_max_exp = max_exp;
|
||||||
|
|
||||||
|
if (shifted_both)
|
||||||
|
wps->float_flags |= FLOAT_SHIFT_SENT;
|
||||||
|
else if (shifted_ones && !shifted_zeros)
|
||||||
|
wps->float_flags |= FLOAT_SHIFT_ONES;
|
||||||
|
else if (shifted_ones && shifted_zeros)
|
||||||
|
wps->float_flags |= FLOAT_SHIFT_SAME;
|
||||||
|
else if (ordata && !(ordata & 1)) {
|
||||||
|
while (!(ordata & 1)) {
|
||||||
|
wps->float_shift++;
|
||||||
|
ordata >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (dp = values, count = num_values; count--; dp++)
|
||||||
|
* (int32_t *) dp >>= wps->float_shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
wps->wphdr.flags &= ~MAG_MASK;
|
||||||
|
|
||||||
|
while (ordata) {
|
||||||
|
wps->wphdr.flags += 1 << MAG_LSB;
|
||||||
|
ordata >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false_zeros || neg_zeros)
|
||||||
|
wps->float_flags |= FLOAT_ZEROS_SENT;
|
||||||
|
|
||||||
|
if (neg_zeros)
|
||||||
|
wps->float_flags |= FLOAT_NEG_ZEROS;
|
||||||
|
|
||||||
|
// error_line ("samples = %d, max exp = %d, pre-shift = %d, denormals = %d",
|
||||||
|
// num_values, max_exp, wps->float_shift, denormals);
|
||||||
|
// if (wps->float_flags & FLOAT_EXCEPTIONS)
|
||||||
|
// error_line ("exceptions!");
|
||||||
|
// error_line ("shifted ones/zeros/both = %d/%d/%d, true/neg/false zeros = %d/%d/%d",
|
||||||
|
// shifted_ones, shifted_zeros, shifted_both, true_zeros, neg_zeros, false_zeros);
|
||||||
|
|
||||||
|
return wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values)
|
||||||
|
{
|
||||||
|
int max_exp = wps->float_max_exp;
|
||||||
|
int32_t count, value, shift_count;
|
||||||
|
f32 *dp;
|
||||||
|
|
||||||
|
for (dp = values, count = num_values; count--; dp++) {
|
||||||
|
if (dp->exponent == 255) {
|
||||||
|
if (dp->mantissa) {
|
||||||
|
putbit_1 (&wps->wvxbits);
|
||||||
|
putbits (dp->mantissa, 23, &wps->wvxbits);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
putbit_0 (&wps->wvxbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = 0x1000000;
|
||||||
|
shift_count = 0;
|
||||||
|
}
|
||||||
|
else if (dp->exponent) {
|
||||||
|
shift_count = max_exp - dp->exponent;
|
||||||
|
value = 0x800000 + dp->mantissa;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
shift_count = max_exp ? max_exp - 1 : 0;
|
||||||
|
value = dp->mantissa;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift_count < 25)
|
||||||
|
value >>= shift_count;
|
||||||
|
else
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
if (wps->float_flags & FLOAT_ZEROS_SENT) {
|
||||||
|
if (dp->exponent || dp->mantissa) {
|
||||||
|
putbit_1 (&wps->wvxbits);
|
||||||
|
putbits (dp->mantissa, 23, &wps->wvxbits);
|
||||||
|
|
||||||
|
if (max_exp >= 25) {
|
||||||
|
putbits (dp->exponent, 8, &wps->wvxbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
putbit (dp->sign, &wps->wvxbits);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
putbit_0 (&wps->wvxbits);
|
||||||
|
|
||||||
|
if (wps->float_flags & FLOAT_NEG_ZEROS)
|
||||||
|
putbit (dp->sign, &wps->wvxbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (shift_count) {
|
||||||
|
if (wps->float_flags & FLOAT_SHIFT_SENT) {
|
||||||
|
int32_t data = dp->mantissa & ((1 << shift_count) - 1);
|
||||||
|
putbits (data, shift_count, &wps->wvxbits);
|
||||||
|
}
|
||||||
|
else if (wps->float_flags & FLOAT_SHIFT_SAME) {
|
||||||
|
putbit (dp->mantissa & 1, &wps->wvxbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(UNPACK) || defined(INFO_ONLY)
|
||||||
|
|
||||||
|
int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
|
{
|
||||||
|
int bytecnt = wpmd->byte_length;
|
||||||
|
char *byteptr = wpmd->data;
|
||||||
|
|
||||||
|
if (bytecnt != 4)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
wps->float_flags = *byteptr++;
|
||||||
|
wps->float_shift = *byteptr++;
|
||||||
|
wps->float_max_exp = *byteptr++;
|
||||||
|
wps->float_norm_exp = *byteptr;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UNPACK
|
||||||
|
|
||||||
|
static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values);
|
||||||
|
|
||||||
|
void float_values (WavpackStream *wps, int32_t *values, int32_t num_values)
|
||||||
|
{
|
||||||
|
uint32_t crc = wps->crc_x;
|
||||||
|
|
||||||
|
if (!bs_is_open (&wps->wvxbits)) {
|
||||||
|
float_values_nowvx (wps, values, num_values);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (num_values--) {
|
||||||
|
int shift_count = 0, exp = wps->float_max_exp;
|
||||||
|
f32 outval = { 0, 0, 0 };
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
if (*values == 0) {
|
||||||
|
if (wps->float_flags & FLOAT_ZEROS_SENT) {
|
||||||
|
if (getbit (&wps->wvxbits)) {
|
||||||
|
getbits (&temp, 23, &wps->wvxbits);
|
||||||
|
outval.mantissa = temp;
|
||||||
|
|
||||||
|
if (exp >= 25) {
|
||||||
|
getbits (&temp, 8, &wps->wvxbits);
|
||||||
|
outval.exponent = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
outval.sign = getbit (&wps->wvxbits);
|
||||||
|
}
|
||||||
|
else if (wps->float_flags & FLOAT_NEG_ZEROS)
|
||||||
|
outval.sign = getbit (&wps->wvxbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*values <<= wps->float_shift;
|
||||||
|
|
||||||
|
if (*values < 0) {
|
||||||
|
*values = -*values;
|
||||||
|
outval.sign = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*values == 0x1000000) {
|
||||||
|
if (getbit (&wps->wvxbits)) {
|
||||||
|
getbits (&temp, 23, &wps->wvxbits);
|
||||||
|
outval.mantissa = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
outval.exponent = 255;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (exp)
|
||||||
|
while (!(*values & 0x800000) && --exp) {
|
||||||
|
shift_count++;
|
||||||
|
*values <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift_count) {
|
||||||
|
if ((wps->float_flags & FLOAT_SHIFT_ONES) ||
|
||||||
|
((wps->float_flags & FLOAT_SHIFT_SAME) && getbit (&wps->wvxbits)))
|
||||||
|
*values |= ((1 << shift_count) - 1);
|
||||||
|
else if (wps->float_flags & FLOAT_SHIFT_SENT) {
|
||||||
|
getbits (&temp, shift_count, &wps->wvxbits);
|
||||||
|
*values |= temp & ((1 << shift_count) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outval.mantissa = *values;
|
||||||
|
outval.exponent = exp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crc = crc * 27 + outval.mantissa * 9 + outval.exponent * 3 + outval.sign;
|
||||||
|
* (f32 *) values++ = outval;
|
||||||
|
}
|
||||||
|
|
||||||
|
wps->crc_x = crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values)
|
||||||
|
{
|
||||||
|
while (num_values--) {
|
||||||
|
int shift_count = 0, exp = wps->float_max_exp;
|
||||||
|
f32 outval = { 0, 0, 0 };
|
||||||
|
|
||||||
|
if (*values) {
|
||||||
|
*values <<= wps->float_shift;
|
||||||
|
|
||||||
|
if (*values < 0) {
|
||||||
|
*values = -*values;
|
||||||
|
outval.sign = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*values >= 0x1000000) {
|
||||||
|
while (*values & 0xf000000) {
|
||||||
|
*values >>= 1;
|
||||||
|
++exp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exp) {
|
||||||
|
while (!(*values & 0x800000) && --exp) {
|
||||||
|
shift_count++;
|
||||||
|
*values <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES))
|
||||||
|
*values |= ((1 << shift_count) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
outval.mantissa = *values;
|
||||||
|
outval.exponent = exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
* (f32 *) values++ = outval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void float_normalize (int32_t *values, int32_t num_values, int delta_exp)
|
||||||
|
{
|
||||||
|
f32 *fvalues = (f32 *) values, fzero = { 0, 0, 0 };
|
||||||
|
int exp;
|
||||||
|
|
||||||
|
if (!delta_exp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (num_values--) {
|
||||||
|
if ((exp = fvalues->exponent) == 0 || exp + delta_exp <= 0)
|
||||||
|
*fvalues = fzero;
|
||||||
|
else if (exp == 255 || (exp += delta_exp) >= 255) {
|
||||||
|
fvalues->exponent = 255;
|
||||||
|
fvalues->mantissa = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fvalues->exponent = exp;
|
||||||
|
|
||||||
|
fvalues++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
96
Libraries/WavPack/Files/format.txt
Normal file
96
Libraries/WavPack/Files/format.txt
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
WavPack 4.0 File / Block Format
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
A WavPack 4.0 file consists of a series of WavPack audio blocks. It may also
|
||||||
|
contain tags and other information, but these must be outside the blocks
|
||||||
|
(either before, in-between, or after) and are ignored for the purpose of
|
||||||
|
unpacking audio data. The WavPack blocks are easy to identify by their
|
||||||
|
unique header data, and by looking in the header it is very easy to
|
||||||
|
determine the total size of the block, both in physical bytes and compressed
|
||||||
|
samples. There are no seek tables.
|
||||||
|
|
||||||
|
The blocks (or frames, if you prefer) are completely independent in that they
|
||||||
|
can be decoded to mono or stereo audio all by themselves. A single function
|
||||||
|
is provided to convert a whole block into its corresponding audio data.
|
||||||
|
Similarly, a function is provided to convert a block of audio samples into
|
||||||
|
a finished WavPack block. These all work in memory; disk I/O is handled
|
||||||
|
outside. It is also possible to decode or encode blocks in smaller increments
|
||||||
|
if it is important to distribute CPU load more evenly over time. The blocks may
|
||||||
|
also be decoded without reading the whole block into memory, although this
|
||||||
|
would only be important for hardware decoding.
|
||||||
|
|
||||||
|
The blocks may contain any number of samples, either stereo or mono. Obviously,
|
||||||
|
putting more samples in each block is more efficient, but they are reasonably
|
||||||
|
efficient down to even a thousand samples. I have set the max size to 1 MB for
|
||||||
|
the whole block, but this is arbitrary. The blocks may be lossless or lossy
|
||||||
|
(currently the lossy modes are basically CBR, but I am planning a quality
|
||||||
|
based VBR version also).
|
||||||
|
|
||||||
|
For multichannel audio, the data is divided into some number of stereo and mono
|
||||||
|
streams and multiplexed into separate blocks. Because blocks are independent
|
||||||
|
there can be a mix of sampling rates, but all the streams must be sliced at
|
||||||
|
the same point in time which is a multiple of all the sampling rates. The
|
||||||
|
metadata contains source information (like front, center, rear, etc.).
|
||||||
|
|
||||||
|
Correction files (.wvc) have an identical structure to the main file (.wv) and
|
||||||
|
there is a one-to-one correspondence between main file blocks that contain
|
||||||
|
audio and their correction file match (blocks that do not contain audio do
|
||||||
|
not exist in the correction file). The only difference in the headers of
|
||||||
|
main blocks and correction blocks is the CRC value, although it is easy to
|
||||||
|
tell the blocks apart by looking at the metadata ids.
|
||||||
|
|
||||||
|
Here is the 32-byte header at the front of every block:
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ckID [4]; // "wvpk"
|
||||||
|
long ckSize; // size of entire frame (minus 8, of course)
|
||||||
|
short version; // 0x403 for now
|
||||||
|
uchar track_no; // track number (0 if not used, like now)
|
||||||
|
uchar index_no; // track sub-index (0 if not used, like now)
|
||||||
|
ulong total_samples; // for entire file (-1 if unknown)
|
||||||
|
ulong block_index; // index of first sample in block (to file begin)
|
||||||
|
ulong block_samples; // # samples in this block
|
||||||
|
ulong flags; // various flags for id and decoding
|
||||||
|
ulong crc; // crc for actual decoded data
|
||||||
|
} WavpackHeader;
|
||||||
|
|
||||||
|
The "flags" field contains information for decoding the block along with some
|
||||||
|
general information including sample size and format, hybrid/lossless,
|
||||||
|
mono/stereo and sampling rate. This structure is stored "little-endian".
|
||||||
|
|
||||||
|
Following the 32-byte header to the end of the block are a series of "metadata"
|
||||||
|
sub-blocks. These may from 2 bytes long to the size of the entire block and are
|
||||||
|
extremely easy to parse (even without knowing what they mean). Currently these
|
||||||
|
mostly contain extra information needed to decode the audio, but may also
|
||||||
|
contain user information. The only non-audio information I currently have
|
||||||
|
implemented is a copy of the original wave RIFF header (or trailer if present),
|
||||||
|
and the MD5 checksums, but there is plenty of flexibility here. For example,
|
||||||
|
these metadata blocks could store cuesheets, artist/title information,
|
||||||
|
replaygain values, even pictures or lyrics. The final metadata sub-blocks are
|
||||||
|
the actual audio bitstreams, which have ids for standard audio (wvbits),
|
||||||
|
correction data (wvcbits), and a special extension for large integer and
|
||||||
|
floating-point data (wvxbits).
|
||||||
|
|
||||||
|
The format of the metadata is:
|
||||||
|
|
||||||
|
uchar id; // mask meaning
|
||||||
|
// ---- -------
|
||||||
|
// 0x1f metadata function
|
||||||
|
// 0x20 decoder need not understand metadata
|
||||||
|
// 0x40 actual data byte length is 1 less
|
||||||
|
// 0x80 large block (> 255 words)
|
||||||
|
|
||||||
|
uchar word_size; // small block: data size in words (padded)
|
||||||
|
or...
|
||||||
|
uchar word_size [3]; // large block: data size in words (padded,
|
||||||
|
little-endian)
|
||||||
|
|
||||||
|
ushort data [word_size]; // data, padded to an even # of bytes
|
323
Libraries/WavPack/Files/install-sh
Executable file
323
Libraries/WavPack/Files/install-sh
Executable file
|
@ -0,0 +1,323 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
|
scriptversion=2005-02-02.21
|
||||||
|
|
||||||
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
|
# following copyright and license.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1994 X Consortium
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||||
|
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# Except as contained in this notice, the name of the X Consortium shall not
|
||||||
|
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||||
|
# ings in this Software without prior written authorization from the X Consor-
|
||||||
|
# tium.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FSF changes to this file are in the public domain.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# `make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
|
|
||||||
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
|
doit="${DOITPROG-}"
|
||||||
|
|
||||||
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
|
|
||||||
|
mvprog="${MVPROG-mv}"
|
||||||
|
cpprog="${CPPROG-cp}"
|
||||||
|
chmodprog="${CHMODPROG-chmod}"
|
||||||
|
chownprog="${CHOWNPROG-chown}"
|
||||||
|
chgrpprog="${CHGRPPROG-chgrp}"
|
||||||
|
stripprog="${STRIPPROG-strip}"
|
||||||
|
rmprog="${RMPROG-rm}"
|
||||||
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
|
chmodcmd="$chmodprog 0755"
|
||||||
|
chowncmd=
|
||||||
|
chgrpcmd=
|
||||||
|
stripcmd=
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
mvcmd="$mvprog"
|
||||||
|
src=
|
||||||
|
dst=
|
||||||
|
dir_arg=
|
||||||
|
dstarg=
|
||||||
|
no_target_directory=
|
||||||
|
|
||||||
|
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||||
|
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||||
|
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||||
|
or: $0 [OPTION]... -d DIRECTORIES...
|
||||||
|
|
||||||
|
In the 1st form, copy SRCFILE to DSTFILE.
|
||||||
|
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||||
|
In the 4th, create DIRECTORIES.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-c (ignored)
|
||||||
|
-d create directories instead of installing files.
|
||||||
|
-g GROUP $chgrpprog installed files to GROUP.
|
||||||
|
-m MODE $chmodprog installed files to MODE.
|
||||||
|
-o USER $chownprog installed files to USER.
|
||||||
|
-s $stripprog installed files.
|
||||||
|
-t DIRECTORY install into DIRECTORY.
|
||||||
|
-T report an error if DSTFILE is a directory.
|
||||||
|
--help display this help and exit.
|
||||||
|
--version display version info and exit.
|
||||||
|
|
||||||
|
Environment variables override the default commands:
|
||||||
|
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||||
|
"
|
||||||
|
|
||||||
|
while test -n "$1"; do
|
||||||
|
case $1 in
|
||||||
|
-c) shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-d) dir_arg=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
--help) echo "$usage"; exit $?;;
|
||||||
|
|
||||||
|
-m) chmodcmd="$chmodprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-s) stripcmd=$stripprog
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-t) dstarg=$2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-T) no_target_directory=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
--version) echo "$0 $scriptversion"; exit $?;;
|
||||||
|
|
||||||
|
*) # When -d is used, all remaining arguments are directories to create.
|
||||||
|
# When -t is used, the destination is already specified.
|
||||||
|
test -n "$dir_arg$dstarg" && break
|
||||||
|
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$dstarg"; then
|
||||||
|
# $@ is not empty: it contains at least $arg.
|
||||||
|
set fnord "$@" "$dstarg"
|
||||||
|
shift # fnord
|
||||||
|
fi
|
||||||
|
shift # arg
|
||||||
|
dstarg=$arg
|
||||||
|
done
|
||||||
|
break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$1"; then
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
echo "$0: no input file specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# It's OK to call `install-sh -d' without argument.
|
||||||
|
# This can happen when creating conditional directories.
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for src
|
||||||
|
do
|
||||||
|
# Protect names starting with `-'.
|
||||||
|
case $src in
|
||||||
|
-*) src=./$src ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
dst=$src
|
||||||
|
src=
|
||||||
|
|
||||||
|
if test -d "$dst"; then
|
||||||
|
mkdircmd=:
|
||||||
|
chmodcmd=
|
||||||
|
else
|
||||||
|
mkdircmd=$mkdirprog
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
if test ! -f "$src" && test ! -d "$src"; then
|
||||||
|
echo "$0: $src does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dstarg"; then
|
||||||
|
echo "$0: no destination specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
dst=$dstarg
|
||||||
|
# Protect names starting with `-'.
|
||||||
|
case $dst in
|
||||||
|
-*) dst=./$dst ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; won't work
|
||||||
|
# if double slashes aren't ignored.
|
||||||
|
if test -d "$dst"; then
|
||||||
|
if test -n "$no_target_directory"; then
|
||||||
|
echo "$0: $dstarg: Is a directory" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
dst=$dst/`basename "$src"`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This sed command emulates the dirname command.
|
||||||
|
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
|
||||||
|
|
||||||
|
# Make sure that the destination directory exists.
|
||||||
|
|
||||||
|
# Skip lots of stat calls in the usual case.
|
||||||
|
if test ! -d "$dstdir"; then
|
||||||
|
defaultIFS='
|
||||||
|
'
|
||||||
|
IFS="${IFS-$defaultIFS}"
|
||||||
|
|
||||||
|
oIFS=$IFS
|
||||||
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
|
IFS='%'
|
||||||
|
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
|
shift
|
||||||
|
IFS=$oIFS
|
||||||
|
|
||||||
|
pathcomp=
|
||||||
|
|
||||||
|
while test $# -ne 0 ; do
|
||||||
|
pathcomp=$pathcomp$1
|
||||||
|
shift
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
$mkdirprog "$pathcomp"
|
||||||
|
# mkdir can fail with a `File exist' error in case several
|
||||||
|
# install-sh are creating the directory concurrently. This
|
||||||
|
# is OK.
|
||||||
|
test -d "$pathcomp" || exit
|
||||||
|
fi
|
||||||
|
pathcomp=$pathcomp/
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
$doit $mkdircmd "$dst" \
|
||||||
|
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||||
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||||
|
|
||||||
|
else
|
||||||
|
dstfile=`basename "$dst"`
|
||||||
|
|
||||||
|
# Make a couple of temp file names in the proper directory.
|
||||||
|
dsttmp=$dstdir/_inst.$$_
|
||||||
|
rmtmp=$dstdir/_rm.$$_
|
||||||
|
|
||||||
|
# Trap to clean up those temp files at exit.
|
||||||
|
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||||
|
trap '(exit $?); exit' 1 2 13 15
|
||||||
|
|
||||||
|
# Copy the file name to the temp name.
|
||||||
|
$doit $cpprog "$src" "$dsttmp" &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits.
|
||||||
|
#
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||||
|
#
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|
|| {
|
||||||
|
# The rename failed, perhaps because mv can't rename something else
|
||||||
|
# to itself, or perhaps because mv is so ancient that it does not
|
||||||
|
# support -f.
|
||||||
|
|
||||||
|
# Now remove or move aside any old file at destination location.
|
||||||
|
# We try this two ways since rm can't unlink itself on some
|
||||||
|
# systems and the destination file might be busy for other
|
||||||
|
# reasons. In this case, the final cleanup might fail but the new
|
||||||
|
# file should still install successfully.
|
||||||
|
{
|
||||||
|
if test -f "$dstdir/$dstfile"; then
|
||||||
|
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||||
|
|| {
|
||||||
|
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||||
|
(exit 1); exit 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
} &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fi || { (exit 1); exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||||
|
{
|
||||||
|
(exit 0); exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
25
Libraries/WavPack/Files/license.txt
Normal file
25
Libraries/WavPack/Files/license.txt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 1998 - 2005 Conifer Software
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of Conifer Software nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
263
Libraries/WavPack/Files/md5.c
Normal file
263
Libraries/WavPack/Files/md5.c
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
/*
|
||||||
|
* This code implements the MD5 message-digest algorithm.
|
||||||
|
* The algorithm is due to Ron Rivest. This code was
|
||||||
|
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||||
|
* This code is in the public domain; do with it what you wish.
|
||||||
|
*
|
||||||
|
* Equivalent code is available from RSA Data Security, Inc.
|
||||||
|
* This code has been tested against that, and is equivalent,
|
||||||
|
* except that you don't need to include two pages of legalese
|
||||||
|
* with every copy.
|
||||||
|
*
|
||||||
|
* To compute the message digest of a chunk of bytes, declare an
|
||||||
|
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||||
|
* needed on buffers full of bytes, and then call MD5Final, which
|
||||||
|
* will fill a supplied 16-byte array with the digest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Brutally hacked by John Walker back from ANSI C to K&R (no
|
||||||
|
prototypes) to maintain the tradition that Netfone will compile
|
||||||
|
with Sun's original "cc". */
|
||||||
|
|
||||||
|
#include <memory.h> /* for memcpy() */
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
#ifdef sgi
|
||||||
|
#define HIGHFIRST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef sun
|
||||||
|
#define HIGHFIRST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HIGHFIRST
|
||||||
|
#define byteReverse(buf, len) /* Nothing */
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Note: this code is harmless on little-endian machines.
|
||||||
|
*/
|
||||||
|
void byteReverse(buf, longs)
|
||||||
|
unsigned char *buf; unsigned longs;
|
||||||
|
{
|
||||||
|
uint32 t;
|
||||||
|
do {
|
||||||
|
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||||
|
((unsigned) buf[1] << 8 | buf[0]);
|
||||||
|
*(uint32 *) buf = t;
|
||||||
|
buf += 4;
|
||||||
|
} while (--longs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||||
|
* initialization constants.
|
||||||
|
*/
|
||||||
|
void MD5Init(ctx)
|
||||||
|
struct MD5Context *ctx;
|
||||||
|
{
|
||||||
|
ctx->buf[0] = 0x67452301;
|
||||||
|
ctx->buf[1] = 0xefcdab89;
|
||||||
|
ctx->buf[2] = 0x98badcfe;
|
||||||
|
ctx->buf[3] = 0x10325476;
|
||||||
|
|
||||||
|
ctx->bits[0] = 0;
|
||||||
|
ctx->bits[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update context to reflect the concatenation of another buffer full
|
||||||
|
* of bytes.
|
||||||
|
*/
|
||||||
|
void MD5Update(ctx, buf, len)
|
||||||
|
struct MD5Context *ctx; unsigned char *buf; unsigned len;
|
||||||
|
{
|
||||||
|
uint32 t;
|
||||||
|
|
||||||
|
/* Update bitcount */
|
||||||
|
|
||||||
|
t = ctx->bits[0];
|
||||||
|
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
|
||||||
|
ctx->bits[1]++; /* Carry from low to high */
|
||||||
|
ctx->bits[1] += len >> 29;
|
||||||
|
|
||||||
|
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||||
|
|
||||||
|
/* Handle any leading odd-sized chunks */
|
||||||
|
|
||||||
|
if (t) {
|
||||||
|
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||||
|
|
||||||
|
t = 64 - t;
|
||||||
|
if (len < t) {
|
||||||
|
memcpy(p, buf, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(p, buf, t);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||||
|
buf += t;
|
||||||
|
len -= t;
|
||||||
|
}
|
||||||
|
/* Process data in 64-byte chunks */
|
||||||
|
|
||||||
|
while (len >= 64) {
|
||||||
|
memcpy(ctx->in, buf, 64);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||||
|
buf += 64;
|
||||||
|
len -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle any remaining bytes of data. */
|
||||||
|
|
||||||
|
memcpy(ctx->in, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||||
|
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||||
|
*/
|
||||||
|
void MD5Final(digest, ctx)
|
||||||
|
unsigned char digest[16]; struct MD5Context *ctx;
|
||||||
|
{
|
||||||
|
unsigned count;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||||
|
|
||||||
|
/* Set the first char of padding to 0x80. This is safe since there is
|
||||||
|
always at least one byte free */
|
||||||
|
p = ctx->in + count;
|
||||||
|
*p++ = 0x80;
|
||||||
|
|
||||||
|
/* Bytes of padding needed to make 64 bytes */
|
||||||
|
count = 64 - 1 - count;
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64 */
|
||||||
|
if (count < 8) {
|
||||||
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
|
memset(p, 0, count);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||||
|
|
||||||
|
/* Now fill the next block with 56 bytes */
|
||||||
|
memset(ctx->in, 0, 56);
|
||||||
|
} else {
|
||||||
|
/* Pad block to 56 bytes */
|
||||||
|
memset(p, 0, count - 8);
|
||||||
|
}
|
||||||
|
byteReverse(ctx->in, 14);
|
||||||
|
|
||||||
|
/* Append length in bits and transform */
|
||||||
|
((uint32 *) ctx->in)[14] = ctx->bits[0];
|
||||||
|
((uint32 *) ctx->in)[15] = ctx->bits[1];
|
||||||
|
|
||||||
|
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||||
|
byteReverse((unsigned char *) ctx->buf, 4);
|
||||||
|
memcpy(digest, ctx->buf, 16);
|
||||||
|
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The four core functions - F1 is optimized somewhat */
|
||||||
|
|
||||||
|
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||||
|
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||||
|
#define F2(x, y, z) F1(z, x, y)
|
||||||
|
#define F3(x, y, z) (x ^ y ^ z)
|
||||||
|
#define F4(x, y, z) (y ^ (x | ~z))
|
||||||
|
|
||||||
|
/* This is the central step in the MD5 algorithm. */
|
||||||
|
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||||
|
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||||
|
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||||
|
* the data and converts bytes into longwords for this routine.
|
||||||
|
*/
|
||||||
|
void MD5Transform(buf, in)
|
||||||
|
uint32 buf[4]; uint32 in[16];
|
||||||
|
{
|
||||||
|
register uint32 a, b, c, d;
|
||||||
|
|
||||||
|
a = buf[0];
|
||||||
|
b = buf[1];
|
||||||
|
c = buf[2];
|
||||||
|
d = buf[3];
|
||||||
|
|
||||||
|
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||||
|
|
||||||
|
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||||
|
|
||||||
|
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||||
|
|
||||||
|
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||||
|
|
||||||
|
buf[0] += a;
|
||||||
|
buf[1] += b;
|
||||||
|
buf[2] += c;
|
||||||
|
buf[3] += d;
|
||||||
|
}
|
26
Libraries/WavPack/Files/md5.h
Normal file
26
Libraries/WavPack/Files/md5.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef MD5_H
|
||||||
|
#define MD5_H
|
||||||
|
|
||||||
|
#if defined (__alpha__) || defined (__x86_64__)
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
#else
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct MD5Context {
|
||||||
|
uint32 buf[4];
|
||||||
|
uint32 bits[2];
|
||||||
|
unsigned char in[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void MD5Init();
|
||||||
|
extern void MD5Update();
|
||||||
|
extern void MD5Final();
|
||||||
|
extern void MD5Transform();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||||
|
*/
|
||||||
|
typedef struct MD5Context MD5_CTX;
|
||||||
|
|
||||||
|
#endif /* !MD5_H */
|
310
Libraries/WavPack/Files/metadata.c
Normal file
310
Libraries/WavPack/Files/metadata.c
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// metadata.c
|
||||||
|
|
||||||
|
// This module handles the metadata structure introduced in WavPack 4.0
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
#define malloc malloc_db
|
||||||
|
#define realloc realloc_db
|
||||||
|
#define free free_db
|
||||||
|
void *malloc_db (uint32_t size);
|
||||||
|
void *realloc_db (void *ptr, uint32_t size);
|
||||||
|
void free_db (void *ptr);
|
||||||
|
int32_t dump_alloc (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(UNPACK) || defined(INFO_ONLY)
|
||||||
|
|
||||||
|
int read_metadata_buff (WavpackMetadata *wpmd, uchar *blockbuff, uchar **buffptr)
|
||||||
|
{
|
||||||
|
WavpackHeader *wphdr = (WavpackHeader *) blockbuff;
|
||||||
|
uchar *buffend = blockbuff + wphdr->ckSize + 8;
|
||||||
|
|
||||||
|
if (buffend - *buffptr < 2)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
wpmd->id = *(*buffptr)++;
|
||||||
|
wpmd->byte_length = *(*buffptr)++ << 1;
|
||||||
|
|
||||||
|
if (wpmd->id & ID_LARGE) {
|
||||||
|
wpmd->id &= ~ID_LARGE;
|
||||||
|
|
||||||
|
if (buffend - *buffptr < 2)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
wpmd->byte_length += *(*buffptr)++ << 9;
|
||||||
|
wpmd->byte_length += *(*buffptr)++ << 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpmd->id & ID_ODD_SIZE) {
|
||||||
|
wpmd->id &= ~ID_ODD_SIZE;
|
||||||
|
wpmd->byte_length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpmd->byte_length) {
|
||||||
|
if (buffend - *buffptr < wpmd->byte_length + (wpmd->byte_length & 1)) {
|
||||||
|
wpmd->data = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpmd->data = *buffptr;
|
||||||
|
(*buffptr) += wpmd->byte_length + (wpmd->byte_length & 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wpmd->data = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
|
||||||
|
{
|
||||||
|
WavpackStream *wps = wpc->streams [wpc->current_stream];
|
||||||
|
|
||||||
|
switch (wpmd->id) {
|
||||||
|
case ID_DUMMY:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case ID_DECORR_TERMS:
|
||||||
|
return read_decorr_terms (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_DECORR_WEIGHTS:
|
||||||
|
return read_decorr_weights (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_DECORR_SAMPLES:
|
||||||
|
return read_decorr_samples (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_ENTROPY_VARS:
|
||||||
|
return read_entropy_vars (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_HYBRID_PROFILE:
|
||||||
|
return read_hybrid_profile (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_SHAPING_WEIGHTS:
|
||||||
|
return read_shaping_info (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_FLOAT_INFO:
|
||||||
|
return read_float_info (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_INT32_INFO:
|
||||||
|
return read_int32_info (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_CHANNEL_INFO:
|
||||||
|
return read_channel_info (wpc, wpmd);
|
||||||
|
|
||||||
|
case ID_CONFIG_BLOCK:
|
||||||
|
return read_config_info (wpc, wpmd);
|
||||||
|
|
||||||
|
case ID_WV_BITSTREAM:
|
||||||
|
return init_wv_bitstream (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_WVC_BITSTREAM:
|
||||||
|
return init_wvc_bitstream (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_WVX_BITSTREAM:
|
||||||
|
return init_wvx_bitstream (wps, wpmd);
|
||||||
|
|
||||||
|
case ID_RIFF_HEADER: case ID_RIFF_TRAILER:
|
||||||
|
return read_wrapper_data (wpc, wpmd);
|
||||||
|
|
||||||
|
case ID_MD5_CHECKSUM:
|
||||||
|
if (wpmd->byte_length == 16) {
|
||||||
|
memcpy (wpc->config.md5_checksum, wpmd->data, 16);
|
||||||
|
wpc->config.flags |= CONFIG_MD5_CHECKSUM;
|
||||||
|
wpc->config.md5_read = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK
|
||||||
|
|
||||||
|
int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end)
|
||||||
|
{
|
||||||
|
uint32_t mdsize = wpmd->byte_length + (wpmd->byte_length & 1);
|
||||||
|
WavpackHeader *wphdr = (WavpackHeader *) buffer_start;
|
||||||
|
|
||||||
|
if (wpmd->byte_length & 1)
|
||||||
|
((char *) wpmd->data) [wpmd->byte_length] = 0;
|
||||||
|
|
||||||
|
mdsize += (wpmd->byte_length > 510) ? 4 : 2;
|
||||||
|
buffer_start += wphdr->ckSize + 8;
|
||||||
|
|
||||||
|
if (buffer_start + mdsize >= buffer_end)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0);
|
||||||
|
buffer_start [1] = (wpmd->byte_length + 1) >> 1;
|
||||||
|
|
||||||
|
if (wpmd->byte_length > 510) {
|
||||||
|
buffer_start [0] |= ID_LARGE;
|
||||||
|
buffer_start [2] = (wpmd->byte_length + 1) >> 9;
|
||||||
|
buffer_start [3] = (wpmd->byte_length + 1) >> 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpmd->data && wpmd->byte_length) {
|
||||||
|
if (wpmd->byte_length > 510) {
|
||||||
|
buffer_start [0] |= ID_LARGE;
|
||||||
|
buffer_start [2] = (wpmd->byte_length + 1) >> 9;
|
||||||
|
buffer_start [3] = (wpmd->byte_length + 1) >> 17;
|
||||||
|
memcpy (buffer_start + 4, wpmd->data, mdsize - 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy (buffer_start + 2, wpmd->data, mdsize - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
wphdr->ckSize += mdsize;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_to_metadata (WavpackContext *wpc, void *data, uint32_t bcount, uchar id)
|
||||||
|
{
|
||||||
|
WavpackMetadata *mdp;
|
||||||
|
uchar *src = data;
|
||||||
|
|
||||||
|
while (bcount) {
|
||||||
|
if (wpc->metacount) {
|
||||||
|
uint32_t bc = bcount;
|
||||||
|
|
||||||
|
mdp = wpc->metadata + wpc->metacount - 1;
|
||||||
|
|
||||||
|
if (mdp->id == id) {
|
||||||
|
if (wpc->metabytes + bcount > 1000000)
|
||||||
|
bc = 1000000 - wpc->metabytes;
|
||||||
|
|
||||||
|
mdp->data = realloc (mdp->data, mdp->byte_length + bc);
|
||||||
|
memcpy ((char *) mdp->data + mdp->byte_length, src, bc);
|
||||||
|
mdp->byte_length += bc;
|
||||||
|
wpc->metabytes += bc;
|
||||||
|
bcount -= bc;
|
||||||
|
src += bc;
|
||||||
|
|
||||||
|
if (wpc->metabytes >= 1000000 && !write_metadata_block (wpc))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bcount) {
|
||||||
|
wpc->metadata = realloc (wpc->metadata, (wpc->metacount + 1) * sizeof (WavpackMetadata));
|
||||||
|
mdp = wpc->metadata + wpc->metacount++;
|
||||||
|
mdp->byte_length = 0;
|
||||||
|
mdp->data = NULL;
|
||||||
|
mdp->id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *write_metadata (WavpackMetadata *wpmd, char *outdata)
|
||||||
|
{
|
||||||
|
uchar id = wpmd->id, wordlen [3];
|
||||||
|
|
||||||
|
wordlen [0] = (wpmd->byte_length + 1) >> 1;
|
||||||
|
wordlen [1] = (wpmd->byte_length + 1) >> 9;
|
||||||
|
wordlen [2] = (wpmd->byte_length + 1) >> 17;
|
||||||
|
|
||||||
|
if (wpmd->byte_length & 1) {
|
||||||
|
// ((char *) wpmd->data) [wpmd->byte_length] = 0;
|
||||||
|
id |= ID_ODD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wordlen [1] || wordlen [2])
|
||||||
|
id |= ID_LARGE;
|
||||||
|
|
||||||
|
*outdata++ = id;
|
||||||
|
*outdata++ = wordlen [0];
|
||||||
|
|
||||||
|
if (id & ID_LARGE) {
|
||||||
|
*outdata++ = wordlen [1];
|
||||||
|
*outdata++ = wordlen [2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpmd->data && wpmd->byte_length) {
|
||||||
|
memcpy (outdata, wpmd->data, wpmd->byte_length);
|
||||||
|
outdata += wpmd->byte_length;
|
||||||
|
|
||||||
|
if (wpmd->byte_length & 1)
|
||||||
|
*outdata++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_metadata_block (WavpackContext *wpc)
|
||||||
|
{
|
||||||
|
char *block_buff, *block_ptr;
|
||||||
|
WavpackHeader *wphdr;
|
||||||
|
|
||||||
|
if (wpc->metacount) {
|
||||||
|
int metacount = wpc->metacount, block_size = sizeof (WavpackHeader);
|
||||||
|
WavpackMetadata *wpmdp = wpc->metadata;
|
||||||
|
|
||||||
|
while (metacount--) {
|
||||||
|
block_size += wpmdp->byte_length + (wpmdp->byte_length & 1);
|
||||||
|
block_size += (wpmdp->byte_length > 510) ? 4 : 2;
|
||||||
|
wpmdp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wphdr = (WavpackHeader *) (block_buff = malloc (block_size));
|
||||||
|
|
||||||
|
CLEAR (*wphdr);
|
||||||
|
memcpy (wphdr->ckID, "wvpk", 4);
|
||||||
|
wphdr->total_samples = wpc->total_samples;
|
||||||
|
wphdr->version = 0x403;
|
||||||
|
wphdr->ckSize = block_size - 8;
|
||||||
|
wphdr->block_samples = 0;
|
||||||
|
|
||||||
|
block_ptr = (char *)(wphdr + 1);
|
||||||
|
|
||||||
|
wpmdp = wpc->metadata;
|
||||||
|
|
||||||
|
while (wpc->metacount) {
|
||||||
|
block_ptr = write_metadata (wpmdp, block_ptr);
|
||||||
|
wpc->metabytes -= wpmdp->byte_length;
|
||||||
|
free_metadata (wpmdp++);
|
||||||
|
wpc->metacount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (wpc->metadata);
|
||||||
|
wpc->metadata = NULL;
|
||||||
|
native_to_little_endian ((WavpackHeader *) block_buff, WavpackHeaderFormat);
|
||||||
|
|
||||||
|
if (!wpc->blockout (wpc->wv_out, block_buff, block_size)) {
|
||||||
|
free (block_buff);
|
||||||
|
strcpy (wpc->error_message, "can't write WavPack data, disk probably full!");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (block_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void free_metadata (WavpackMetadata *wpmd)
|
||||||
|
{
|
||||||
|
if (wpmd->data) {
|
||||||
|
free (wpmd->data);
|
||||||
|
wpmd->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
357
Libraries/WavPack/Files/missing
Executable file
357
Libraries/WavPack/Files/missing
Executable file
|
@ -0,0 +1,357 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Common stub for a few missing GNU programs while installing.
|
||||||
|
|
||||||
|
scriptversion=2005-02-08.22
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
run=:
|
||||||
|
|
||||||
|
# In the cases where this matters, `missing' is being run in the
|
||||||
|
# srcdir already.
|
||||||
|
if test -f configure.ac; then
|
||||||
|
configure_ac=configure.ac
|
||||||
|
else
|
||||||
|
configure_ac=configure.in
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg="missing on your system"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
--run)
|
||||||
|
# Try to run requested program, and just exit if it succeeds.
|
||||||
|
run=
|
||||||
|
shift
|
||||||
|
"$@" && exit 0
|
||||||
|
# Exit code 63 means version mismatch. This often happens
|
||||||
|
# when the user try to use an ancient version of a tool on
|
||||||
|
# a file that requires a minimum version. In this case we
|
||||||
|
# we should proceed has if the program had been absent, or
|
||||||
|
# if --run hadn't been passed.
|
||||||
|
if test $? = 63; then
|
||||||
|
run=:
|
||||||
|
msg="probably too old"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
-h|--h|--he|--hel|--help)
|
||||||
|
echo "\
|
||||||
|
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||||
|
|
||||||
|
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||||
|
error status if there is no known handling for PROGRAM.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help display this help and exit
|
||||||
|
-v, --version output version information and exit
|
||||||
|
--run try to run the given command, and emulate it if it fails
|
||||||
|
|
||||||
|
Supported PROGRAM values:
|
||||||
|
aclocal touch file \`aclocal.m4'
|
||||||
|
autoconf touch file \`configure'
|
||||||
|
autoheader touch file \`config.h.in'
|
||||||
|
automake touch all \`Makefile.in' files
|
||||||
|
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||||
|
flex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
help2man touch the output file
|
||||||
|
lex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
makeinfo touch the output file
|
||||||
|
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||||
|
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||||
|
|
||||||
|
Send bug reports to <bug-automake@gnu.org>."
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||||
|
echo "missing $scriptversion (GNU Automake)"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo 1>&2 "$0: Unknown \`$1' option"
|
||||||
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Now exit if we have it, but it failed. Also exit now if we
|
||||||
|
# don't have it and --version was passed (most likely to detect
|
||||||
|
# the program).
|
||||||
|
case "$1" in
|
||||||
|
lex|yacc)
|
||||||
|
# Not GNU programs, they don't have --version.
|
||||||
|
;;
|
||||||
|
|
||||||
|
tar)
|
||||||
|
if test -n "$run"; then
|
||||||
|
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||||
|
exit 1
|
||||||
|
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||||
|
# Could not run --version or --help. This is probably someone
|
||||||
|
# running `$TOOL --version' or `$TOOL --help' to check whether
|
||||||
|
# $TOOL exists and not knowing $TOOL uses missing.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If it does not exist, or fails to run (possibly an outdated version),
|
||||||
|
# try to emulate it.
|
||||||
|
case "$1" in
|
||||||
|
aclocal*)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||||
|
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||||
|
any GNU archive site."
|
||||||
|
touch aclocal.m4
|
||||||
|
;;
|
||||||
|
|
||||||
|
autoconf)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`${configure_ac}'. You might want to install the
|
||||||
|
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||||
|
archive site."
|
||||||
|
touch configure
|
||||||
|
;;
|
||||||
|
|
||||||
|
autoheader)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||||
|
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||||
|
from any GNU archive site."
|
||||||
|
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||||
|
test -z "$files" && files="config.h"
|
||||||
|
touch_files=
|
||||||
|
for f in $files; do
|
||||||
|
case "$f" in
|
||||||
|
*:*) touch_files="$touch_files "`echo "$f" |
|
||||||
|
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||||
|
*) touch_files="$touch_files $f.in";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
touch $touch_files
|
||||||
|
;;
|
||||||
|
|
||||||
|
automake*)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||||
|
You might want to install the \`Automake' and \`Perl' packages.
|
||||||
|
Grab them from any GNU archive site."
|
||||||
|
find . -type f -name Makefile.am -print |
|
||||||
|
sed 's/\.am$/.in/' |
|
||||||
|
while read f; do touch "$f"; done
|
||||||
|
;;
|
||||||
|
|
||||||
|
autom4te)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is needed, but is $msg.
|
||||||
|
You might have modified some files without having the
|
||||||
|
proper tools for further handling them.
|
||||||
|
You can get \`$1' as part of \`Autoconf' from any GNU
|
||||||
|
archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
|
||||||
|
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
|
||||||
|
if test -f "$file"; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo "#! /bin/sh"
|
||||||
|
echo "# Created by GNU Automake missing as a replacement of"
|
||||||
|
echo "# $ $@"
|
||||||
|
echo "exit 0"
|
||||||
|
chmod +x $file
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
bison|yacc)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' $msg. You should only need it if
|
||||||
|
you modified a \`.y' file. You may need the \`Bison' package
|
||||||
|
in order for those modifications to take effect. You can get
|
||||||
|
\`Bison' from any GNU archive site."
|
||||||
|
rm -f y.tab.c y.tab.h
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
eval LASTARG="\${$#}"
|
||||||
|
case "$LASTARG" in
|
||||||
|
*.y)
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" y.tab.c
|
||||||
|
fi
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" y.tab.h
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ ! -f y.tab.h ]; then
|
||||||
|
echo >y.tab.h
|
||||||
|
fi
|
||||||
|
if [ ! -f y.tab.c ]; then
|
||||||
|
echo 'main() { return 0; }' >y.tab.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
lex|flex)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified a \`.l' file. You may need the \`Flex' package
|
||||||
|
in order for those modifications to take effect. You can get
|
||||||
|
\`Flex' from any GNU archive site."
|
||||||
|
rm -f lex.yy.c
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
eval LASTARG="\${$#}"
|
||||||
|
case "$LASTARG" in
|
||||||
|
*.l)
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" lex.yy.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ ! -f lex.yy.c ]; then
|
||||||
|
echo 'main() { return 0; }' >lex.yy.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
help2man)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified a dependency of a manual page. You may need the
|
||||||
|
\`Help2man' package in order for those modifications to take
|
||||||
|
effect. You can get \`Help2man' from any GNU archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||||
|
fi
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo ".ab help2man is required to generate this page"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
makeinfo)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||||
|
indirectly affecting the aspect of the manual. The spurious
|
||||||
|
call might also be the consequence of using a buggy \`make' (AIX,
|
||||||
|
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||||
|
the \`GNU make' package. Grab either from any GNU archive site."
|
||||||
|
# The file to touch is that specified with -o ...
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
# ... or it is the one specified with @setfilename ...
|
||||||
|
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||||
|
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
|
||||||
|
# ... or it is derived from the source name (dir/f.texi becomes f.info)
|
||||||
|
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
|
||||||
|
fi
|
||||||
|
touch $file
|
||||||
|
;;
|
||||||
|
|
||||||
|
tar)
|
||||||
|
shift
|
||||||
|
|
||||||
|
# We have already tried tar in the generic part.
|
||||||
|
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||||
|
# messages.
|
||||||
|
if (gnutar --version > /dev/null 2>&1); then
|
||||||
|
gnutar "$@" && exit 0
|
||||||
|
fi
|
||||||
|
if (gtar --version > /dev/null 2>&1); then
|
||||||
|
gtar "$@" && exit 0
|
||||||
|
fi
|
||||||
|
firstarg="$1"
|
||||||
|
if shift; then
|
||||||
|
case "$firstarg" in
|
||||||
|
*o*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/o//`
|
||||||
|
tar "$firstarg" "$@" && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$firstarg" in
|
||||||
|
*h*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/h//`
|
||||||
|
tar "$firstarg" "$@" && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||||
|
You may want to install GNU tar or Free paxutils, or check the
|
||||||
|
command line arguments."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is needed, and is $msg.
|
||||||
|
You might have modified some files without having the
|
||||||
|
proper tools for further handling them. Check the \`README' file,
|
||||||
|
it often tells you about the needed prerequisites for installing
|
||||||
|
this package. You may also peek at any GNU archive site, in case
|
||||||
|
some other package would contain this missing \`$1' program."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
1413
Libraries/WavPack/Files/pack.c
Normal file
1413
Libraries/WavPack/Files/pack.c
Normal file
File diff suppressed because it is too large
Load diff
1453
Libraries/WavPack/Files/unpack.c
Normal file
1453
Libraries/WavPack/Files/unpack.c
Normal file
File diff suppressed because it is too large
Load diff
2010
Libraries/WavPack/Files/unpack3.c
Normal file
2010
Libraries/WavPack/Files/unpack3.c
Normal file
File diff suppressed because it is too large
Load diff
113
Libraries/WavPack/Files/unpack3.h
Normal file
113
Libraries/WavPack/Files/unpack3.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// wavpack3.h
|
||||||
|
|
||||||
|
// This header file contains all the additional definitions required for
|
||||||
|
// decoding old (versions 1, 2 & 3) WavPack files.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ushort FormatTag, NumChannels;
|
||||||
|
uint32_t SampleRate, BytesPerSecond;
|
||||||
|
ushort BlockAlign, BitsPerSample;
|
||||||
|
} WaveHeader3;
|
||||||
|
|
||||||
|
#define WaveHeader3Format "SSLLSS"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ckID [4];
|
||||||
|
int32_t ckSize;
|
||||||
|
short version;
|
||||||
|
short bits; // added for version 2.00
|
||||||
|
short flags, shift; // added for version 3.00
|
||||||
|
int32_t total_samples, crc, crc2;
|
||||||
|
char extension [4], extra_bc, extras [3];
|
||||||
|
} WavpackHeader3;
|
||||||
|
|
||||||
|
#define WavpackHeader3Format "4LSSSSLLL4L"
|
||||||
|
|
||||||
|
// these flags added for version 3
|
||||||
|
|
||||||
|
#undef MONO_FLAG // these definitions changed for WavPack 4.0
|
||||||
|
#undef CROSS_DECORR
|
||||||
|
#undef JOINT_STEREO
|
||||||
|
|
||||||
|
#define MONO_FLAG 1 // not stereo
|
||||||
|
#define FAST_FLAG 2 // non-adaptive predictor and stereo mode
|
||||||
|
#define RAW_FLAG 4 // raw mode (no .wav header)
|
||||||
|
#define CALC_NOISE 8 // calc noise in lossy mode (no longer stored)
|
||||||
|
#define HIGH_FLAG 0x10 // high quality mode (all modes)
|
||||||
|
#define BYTES_3 0x20 // files have 3-byte samples
|
||||||
|
#define OVER_20 0x40 // samples are over 20 bits
|
||||||
|
#define WVC_FLAG 0x80 // create/use .wvc (no longer stored)
|
||||||
|
#define LOSSY_SHAPE 0x100 // noise shape (lossy mode only)
|
||||||
|
#define VERY_FAST_FLAG 0x200 // double fast (no longer stored)
|
||||||
|
#define NEW_HIGH_FLAG 0x400 // new high quality mode (lossless only)
|
||||||
|
#define CANCEL_EXTREME 0x800 // cancel EXTREME_DECORR
|
||||||
|
#define CROSS_DECORR 0x1000 // decorrelate chans (with EXTREME_DECORR flag)
|
||||||
|
#define NEW_DECORR_FLAG 0x2000 // new high-mode decorrelator
|
||||||
|
#define JOINT_STEREO 0x4000 // joint stereo (lossy and high lossless)
|
||||||
|
#define EXTREME_DECORR 0x8000 // extra decorrelation (+ enables other flags)
|
||||||
|
|
||||||
|
#define STORED_FLAGS 0xfd77 // these are only flags that affect unpacking
|
||||||
|
#define NOT_STORED_FLAGS (~STORED_FLAGS & 0xffff)
|
||||||
|
|
||||||
|
// BitStream stuff (bits.c)
|
||||||
|
|
||||||
|
typedef struct bs3 {
|
||||||
|
void (*wrap)(struct bs3 *bs);
|
||||||
|
uchar *buf, *end, *ptr;
|
||||||
|
uint32_t bufsiz, fpos, sr;
|
||||||
|
stream_reader *reader;
|
||||||
|
int error, bc;
|
||||||
|
void *id;
|
||||||
|
} Bitstream3;
|
||||||
|
|
||||||
|
#define K_DEPTH 3
|
||||||
|
#define MAX_NTERMS3 18
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WavpackHeader3 wphdr;
|
||||||
|
Bitstream3 wvbits, wvcbits;
|
||||||
|
uint32_t sample_index;
|
||||||
|
int num_terms;
|
||||||
|
|
||||||
|
#ifdef SEEKING
|
||||||
|
struct index_point {
|
||||||
|
char saved;
|
||||||
|
uint32_t sample_index;
|
||||||
|
} index_points [256];
|
||||||
|
|
||||||
|
uchar *unpack_data;
|
||||||
|
uint32_t unpack_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int32_t sum_level, left_level, right_level, diff_level;
|
||||||
|
int last_extra_bits, extra_bits_count, m;
|
||||||
|
int32_t error [2], crc;
|
||||||
|
int32_t sample [2] [2];
|
||||||
|
int weight [2] [1];
|
||||||
|
} dc;
|
||||||
|
|
||||||
|
struct decorr_pass decorr_passes [MAX_NTERMS3];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint index [2], k_value [2], ave_k [2];
|
||||||
|
uint32_t zeros_acc, ave_level [K_DEPTH] [2];
|
||||||
|
} w1;
|
||||||
|
|
||||||
|
struct { int last_dbits [2], last_delta_sign [2], bit_limit; } w2;
|
||||||
|
|
||||||
|
struct { int ave_dbits [2], bit_limit; } w3;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t fast_level [2], slow_level [2];
|
||||||
|
int bits_acc [2], bitrate;
|
||||||
|
} w4;
|
||||||
|
} WavpackStream3;
|
640
Libraries/WavPack/Files/utils.c
Normal file
640
Libraries/WavPack/Files/utils.c
Normal file
|
@ -0,0 +1,640 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// utils.c
|
||||||
|
|
||||||
|
// This module provides general purpose utilities for the WavPack command-line
|
||||||
|
// utilities and the self-extraction module.
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#include <glob.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <locale.h>
|
||||||
|
#include <iconv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
int copy_timestamp (const char *src_filename, const char *dst_filename)
|
||||||
|
{
|
||||||
|
FILETIME last_modified;
|
||||||
|
HANDLE src, dst;
|
||||||
|
int res = TRUE;
|
||||||
|
|
||||||
|
if (*src_filename == '-' || *dst_filename == '-')
|
||||||
|
return res;
|
||||||
|
|
||||||
|
src = CreateFile (src_filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
|
|
||||||
|
dst = CreateFile (dst_filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
|
|
||||||
|
if (src == INVALID_HANDLE_VALUE || dst == INVALID_HANDLE_VALUE ||
|
||||||
|
!GetFileTime (src, NULL, NULL, &last_modified) ||
|
||||||
|
!SetFileTime (dst, NULL, NULL, &last_modified))
|
||||||
|
res = FALSE;
|
||||||
|
|
||||||
|
if (src != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle (src);
|
||||||
|
|
||||||
|
if (dst != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle (dst);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function parses a filename (with or without full path) and returns //
|
||||||
|
// a pointer to the extension (including the "."). If no extension is found //
|
||||||
|
// then NULL is returned. Extensions with more than 3 letters don't count. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
|
||||||
|
static int is_second_byte (char *filespec, char *pos);
|
||||||
|
|
||||||
|
char *filespec_ext (char *filespec)
|
||||||
|
{
|
||||||
|
char *cp = filespec + strlen (filespec);
|
||||||
|
LANGID langid = GetSystemDefaultLangID ();
|
||||||
|
|
||||||
|
while (--cp >= filespec) {
|
||||||
|
|
||||||
|
if (langid == 0x411 && is_second_byte (filespec, cp))
|
||||||
|
--cp;
|
||||||
|
|
||||||
|
if (*cp == '\\' || *cp == ':')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (*cp == '.') {
|
||||||
|
if (strlen (cp) > 1 && strlen (cp) <= 4)
|
||||||
|
return cp;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
char *filespec_ext (char *filespec)
|
||||||
|
{
|
||||||
|
char *cp = filespec + strlen (filespec);
|
||||||
|
|
||||||
|
while (--cp >= filespec) {
|
||||||
|
|
||||||
|
if (*cp == '\\' || *cp == ':')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (*cp == '.') {
|
||||||
|
if (strlen (cp) > 1 && strlen (cp) <= 4)
|
||||||
|
return cp;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function determines if the specified filespec is a valid pathname. //
|
||||||
|
// If not, NULL is returned. If it is in the format of a pathname, then the //
|
||||||
|
// original pointer is returned. If the format is ambiguous, then a lookup //
|
||||||
|
// is performed to determine if it is in fact a valid path, and if so a "\" //
|
||||||
|
// is appended so that the pathname can be used and the original pointer is //
|
||||||
|
// returned. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && !defined(WIN32)
|
||||||
|
|
||||||
|
char *filespec_path (char *filespec)
|
||||||
|
{
|
||||||
|
char *cp = filespec + strlen (filespec);
|
||||||
|
glob_t globs;
|
||||||
|
struct stat fstats;
|
||||||
|
|
||||||
|
if (cp == filespec || filespec_wild (filespec))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (*--cp == '\\' || *cp == ':')
|
||||||
|
return filespec;
|
||||||
|
|
||||||
|
if (*cp == '.' && cp == filespec)
|
||||||
|
return strcat (filespec, "\\");
|
||||||
|
|
||||||
|
if (glob (filespec, GLOB_MARK|GLOB_NOSORT, NULL, &globs) == 0 &&
|
||||||
|
globs.gl_pathc > 0)
|
||||||
|
{
|
||||||
|
/* test if the file is a directory */
|
||||||
|
if (stat(globs.gl_pathv[0], &fstats) == 0 && (fstats.st_mode & S_IFDIR)) {
|
||||||
|
globfree(&globs);
|
||||||
|
filespec[0] = '\0';
|
||||||
|
return strcat (filespec, globs.gl_pathv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globfree(&globs);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
char *filespec_path (char *filespec)
|
||||||
|
{
|
||||||
|
char *cp = filespec + strlen (filespec);
|
||||||
|
LANGID langid = GetSystemDefaultLangID ();
|
||||||
|
struct _finddata_t finddata;
|
||||||
|
int32_t file;
|
||||||
|
|
||||||
|
if (cp == filespec || filespec_wild (filespec))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
--cp;
|
||||||
|
|
||||||
|
if (langid == 0x411 && is_second_byte (filespec, cp))
|
||||||
|
--cp;
|
||||||
|
|
||||||
|
if (*cp == '\\' || *cp == ':')
|
||||||
|
return filespec;
|
||||||
|
|
||||||
|
if (*cp == '.' && cp == filespec)
|
||||||
|
return strcat (filespec, "\\");
|
||||||
|
|
||||||
|
if ((file = _findfirst (filespec, &finddata)) != -1L &&
|
||||||
|
(finddata.attrib & _A_SUBDIR)) {
|
||||||
|
_findclose (file);
|
||||||
|
return strcat (filespec, "\\");
|
||||||
|
}
|
||||||
|
if (file != -1L)
|
||||||
|
_findclose(file);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function returns non-NULL if the specified filename spec has any //
|
||||||
|
// wildcard characters. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char *filespec_wild (char *filespec)
|
||||||
|
{
|
||||||
|
return strpbrk (filespec, "*?");
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function parses a filename (with or without full path) and returns //
|
||||||
|
// a pointer to the actual filename, or NULL if no filename can be found. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
|
||||||
|
char *filespec_name (char *filespec)
|
||||||
|
{
|
||||||
|
char *cp = filespec + strlen (filespec);
|
||||||
|
LANGID langid = GetSystemDefaultLangID ();
|
||||||
|
|
||||||
|
while (--cp >= filespec) {
|
||||||
|
if (langid == 0x411 && is_second_byte (filespec, cp))
|
||||||
|
--cp;
|
||||||
|
|
||||||
|
if (*cp == '\\' || *cp == ':')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen (cp + 1))
|
||||||
|
return cp + 1;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
char *filespec_name (char *filespec)
|
||||||
|
{
|
||||||
|
char *cp = filespec + strlen (filespec);
|
||||||
|
|
||||||
|
while (--cp >= filespec)
|
||||||
|
if (*cp == '\\' || *cp == ':')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (strlen (cp + 1))
|
||||||
|
return cp + 1;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function returns TRUE if "pos" is pointing to the second byte of a //
|
||||||
|
// double-byte character in the string "filespec" which is assumed to be //
|
||||||
|
// shift-JIS. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
|
||||||
|
static int is_second_byte (char *filespec, char *pos)
|
||||||
|
{
|
||||||
|
uchar *cp = pos;
|
||||||
|
|
||||||
|
while (cp > filespec && ((cp [-1] >= 0x81 && cp [-1] <= 0x9f) ||
|
||||||
|
(cp [-1] >= 0xe0 && cp [-1] <= 0xfc)))
|
||||||
|
cp--;
|
||||||
|
|
||||||
|
return ((int) pos - (int) cp) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function allows the user to type 'y', 'n', or 'a' (with Enter) in //
|
||||||
|
// response to a system query. The return value is the key typed as //
|
||||||
|
// lowercase (regardless of the typed case). //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static int waiting_input;
|
||||||
|
|
||||||
|
char yna (void)
|
||||||
|
{
|
||||||
|
char choice = 0;
|
||||||
|
int key;
|
||||||
|
|
||||||
|
waiting_input = 1;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
#if defined(WIN32)
|
||||||
|
key = getch ();
|
||||||
|
#else
|
||||||
|
key = fgetc(stdin);
|
||||||
|
#endif
|
||||||
|
if (key == 3) {
|
||||||
|
fprintf (stderr, "^C\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
else if (key == '\r' || key == '\n') {
|
||||||
|
if (choice) {
|
||||||
|
fprintf (stderr, "\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (stderr, "%c", 7);
|
||||||
|
}
|
||||||
|
else if (key == 'Y' || key == 'y') {
|
||||||
|
fprintf (stderr, "%c\b", key);
|
||||||
|
choice = 'y';
|
||||||
|
}
|
||||||
|
else if (key == 'N' || key == 'n') {
|
||||||
|
fprintf (stderr, "%c\b", key);
|
||||||
|
choice = 'n';
|
||||||
|
}
|
||||||
|
else if (key == 'A' || key == 'a') {
|
||||||
|
fprintf (stderr, "%c\b", key);
|
||||||
|
choice = 'a';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (stderr, "%c", 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
waiting_input = 0;
|
||||||
|
|
||||||
|
return choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Display the specified message on the console through stderr. Note that //
|
||||||
|
// the cursor may start anywhere in the line and all text already on the //
|
||||||
|
// line is erased. A terminating newline is not needed and function works //
|
||||||
|
// with printf strings and args. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void error_line (char *error, ...)
|
||||||
|
{
|
||||||
|
char error_msg [512];
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
error_msg [0] = '\r';
|
||||||
|
va_start (argptr, error);
|
||||||
|
vsprintf (error_msg + 1, error, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
fputs (error_msg, stderr);
|
||||||
|
finish_line ();
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
FILE *error_log = fopen ("c:\\wavpack.log", "a+");
|
||||||
|
|
||||||
|
if (error_log) {
|
||||||
|
fputs (error_msg + 1, error_log);
|
||||||
|
fputc ('\n', error_log);
|
||||||
|
fclose (error_log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to intercept ^C or ^Break typed at the console. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if defined(WIN32)
|
||||||
|
static int break_flag;
|
||||||
|
|
||||||
|
BOOL WINAPI ctrl_handler (DWORD ctrl)
|
||||||
|
{
|
||||||
|
if (ctrl == CTRL_C_EVENT) {
|
||||||
|
break_flag = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl == CTRL_BREAK_EVENT) {
|
||||||
|
|
||||||
|
if (waiting_input) {
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
fprintf (stderr, "^C\n");
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break_flag = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to initialize console for intercepting ^C and ^Break. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setup_break (void)
|
||||||
|
{
|
||||||
|
HANDLE hConIn = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
|
|
||||||
|
SetConsoleMode (hConIn, ENABLE_PROCESSED_INPUT);
|
||||||
|
FlushConsoleInputBuffer (hConIn);
|
||||||
|
SetConsoleCtrlHandler (ctrl_handler, TRUE);
|
||||||
|
break_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to determine whether ^C or ^Break has been issued by user. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int check_break (void)
|
||||||
|
{
|
||||||
|
return break_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to clear the stderr console to the end of the current line (and //
|
||||||
|
// go to the beginning next line). //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void finish_line (void)
|
||||||
|
{
|
||||||
|
HANDLE hConIn = GetStdHandle (STD_ERROR_HANDLE);
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO coninfo;
|
||||||
|
|
||||||
|
if (hConIn && GetConsoleScreenBufferInfo (hConIn, &coninfo)) {
|
||||||
|
char spaces = coninfo.dwSize.X - coninfo.dwCursorPosition.X;
|
||||||
|
|
||||||
|
while (spaces--)
|
||||||
|
fputc (' ', stderr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fputc ('\n', stderr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to clear the stderr console to the end of the current line (and //
|
||||||
|
// go to the beginning next line). //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void finish_line (void)
|
||||||
|
{
|
||||||
|
/* char spaces = 1;
|
||||||
|
|
||||||
|
while (spaces--)
|
||||||
|
putc (' ', stderr);
|
||||||
|
else*/
|
||||||
|
fputc ('\n', stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to initialize console for intercepting ^C and ^Break. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setup_break (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function to determine whether ^C or ^Break has been issued by user. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int check_break (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////// File I/O Wrapper ////////////////////////////////
|
||||||
|
|
||||||
|
int DoReadFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, uint32_t *lpNumberOfBytesRead)
|
||||||
|
{
|
||||||
|
uint32_t bcount;
|
||||||
|
|
||||||
|
*lpNumberOfBytesRead = 0;
|
||||||
|
|
||||||
|
while (nNumberOfBytesToRead) {
|
||||||
|
bcount = fread ((uchar *) lpBuffer + *lpNumberOfBytesRead, 1, nNumberOfBytesToRead, hFile);
|
||||||
|
|
||||||
|
if (bcount) {
|
||||||
|
*lpNumberOfBytesRead += bcount;
|
||||||
|
nNumberOfBytesToRead -= bcount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ferror (hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoWriteFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToWrite, uint32_t *lpNumberOfBytesWritten)
|
||||||
|
{
|
||||||
|
uint32_t bcount;
|
||||||
|
|
||||||
|
*lpNumberOfBytesWritten = 0;
|
||||||
|
|
||||||
|
while (nNumberOfBytesToWrite) {
|
||||||
|
bcount = fwrite ((uchar *) lpBuffer + *lpNumberOfBytesWritten, 1, nNumberOfBytesToWrite, hFile);
|
||||||
|
|
||||||
|
if (bcount) {
|
||||||
|
*lpNumberOfBytesWritten += bcount;
|
||||||
|
nNumberOfBytesToWrite -= bcount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ferror (hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DoGetFileSize (FILE *hFile)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
if (!hFile || fstat (fileno (hFile), &statbuf) || !(statbuf.st_mode & S_IFREG))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return statbuf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DoGetFilePosition (FILE *hFile)
|
||||||
|
{
|
||||||
|
return ftell (hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoSetFilePositionAbsolute (FILE *hFile, uint32_t pos)
|
||||||
|
{
|
||||||
|
return fseek (hFile, pos, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoSetFilePositionRelative (FILE *hFile, int32_t pos, int mode)
|
||||||
|
{
|
||||||
|
return fseek (hFile, pos, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ungetc() is not available, a seek of -1 is fine also because we do not
|
||||||
|
// change the byte read.
|
||||||
|
|
||||||
|
int DoUngetc (int c, FILE *hFile)
|
||||||
|
{
|
||||||
|
return ungetc (c, hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoCloseHandle (FILE *hFile)
|
||||||
|
{
|
||||||
|
return hFile ? !fclose (hFile) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoTruncateFile (FILE *hFile)
|
||||||
|
{
|
||||||
|
if (hFile) {
|
||||||
|
fflush (hFile);
|
||||||
|
#if defined(WIN32)
|
||||||
|
return !chsize (fileno (hFile), 0);
|
||||||
|
#else
|
||||||
|
return !ftruncate(fileno (hFile), 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DoDeleteFile (char *filename)
|
||||||
|
{
|
||||||
|
return !remove (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the Unicode wide-format string into a UTF-8 string using no more
|
||||||
|
// than the specified buffer length. The wide-format string must be NULL
|
||||||
|
// terminated and the resulting string will be NULL terminated. The actual
|
||||||
|
// number of characters converted (not counting terminator) is returned, which
|
||||||
|
// may be less than the number of characters in the wide string if the buffer
|
||||||
|
// length is exceeded.
|
||||||
|
|
||||||
|
static int WideCharToUTF8 (const ushort *Wide, uchar *pUTF8, int len)
|
||||||
|
{
|
||||||
|
const ushort *pWide = Wide;
|
||||||
|
int outndx = 0;
|
||||||
|
|
||||||
|
while (*pWide) {
|
||||||
|
if (*pWide < 0x80 && outndx + 1 < len)
|
||||||
|
pUTF8 [outndx++] = (uchar) *pWide++;
|
||||||
|
else if (*pWide < 0x800 && outndx + 2 < len) {
|
||||||
|
pUTF8 [outndx++] = (uchar) (0xc0 | ((*pWide >> 6) & 0x1f));
|
||||||
|
pUTF8 [outndx++] = (uchar) (0x80 | (*pWide++ & 0x3f));
|
||||||
|
}
|
||||||
|
else if (outndx + 3 < len) {
|
||||||
|
pUTF8 [outndx++] = (uchar) (0xe0 | ((*pWide >> 12) & 0xf));
|
||||||
|
pUTF8 [outndx++] = (uchar) (0x80 | ((*pWide >> 6) & 0x3f));
|
||||||
|
pUTF8 [outndx++] = (uchar) (0x80 | (*pWide++ & 0x3f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pUTF8 [outndx] = 0;
|
||||||
|
return pWide - Wide;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a Ansi string into its Unicode UTF-8 format equivalent. The
|
||||||
|
// conversion is done in-place so the maximum length of the string buffer must
|
||||||
|
// be specified because the string may become longer or shorter. If the
|
||||||
|
// resulting string will not fit in the specified buffer size then it is
|
||||||
|
// truncated.
|
||||||
|
|
||||||
|
void AnsiToUTF8 (char *string, int len)
|
||||||
|
{
|
||||||
|
int max_chars = strlen (string);
|
||||||
|
#if defined(WIN32)
|
||||||
|
ushort *temp = (ushort *) malloc ((max_chars + 1) * 2);
|
||||||
|
|
||||||
|
MultiByteToWideChar (CP_ACP, 0, string, -1, temp, max_chars + 1);
|
||||||
|
WideCharToUTF8 (temp, (uchar *) string, len);
|
||||||
|
#else
|
||||||
|
char *temp = malloc (len);
|
||||||
|
// memset(temp, 0, len);
|
||||||
|
char *outp = temp;
|
||||||
|
const char *inp = string;
|
||||||
|
size_t insize = max_chars;
|
||||||
|
size_t outsize = len - 1;
|
||||||
|
int err = 0;
|
||||||
|
char *old_locale;
|
||||||
|
|
||||||
|
memset(temp, 0, len);
|
||||||
|
old_locale = setlocale (LC_CTYPE, "");
|
||||||
|
iconv_t converter = iconv_open ("UTF-8", "");
|
||||||
|
err = iconv (converter, &inp, &insize, &outp, &outsize);
|
||||||
|
iconv_close (converter);
|
||||||
|
setlocale (LC_CTYPE, old_locale);
|
||||||
|
|
||||||
|
if (err == -1) {
|
||||||
|
free(temp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove (string, temp, len);
|
||||||
|
#endif
|
||||||
|
free (temp);
|
||||||
|
}
|
1448
Libraries/WavPack/Files/wavpack.c
Normal file
1448
Libraries/WavPack/Files/wavpack.c
Normal file
File diff suppressed because it is too large
Load diff
656
Libraries/WavPack/Files/wavpack.h
Normal file
656
Libraries/WavPack/Files/wavpack.h
Normal file
|
@ -0,0 +1,656 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// wavpack.h
|
||||||
|
|
||||||
|
#ifndef WAVPACK_H
|
||||||
|
#define WAVPACK_H
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#define FASTCALL __fastcall
|
||||||
|
#else
|
||||||
|
#define FASTCALL
|
||||||
|
#define SetConsoleTitle(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
// This header file contains all the definitions required by WavPack.
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||||
|
#include <stdlib.h>
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef __int64 int64_t;
|
||||||
|
typedef __int32 int32_t;
|
||||||
|
typedef __int16 int16_t;
|
||||||
|
typedef __int8 int8_t;
|
||||||
|
typedef float float32_t;
|
||||||
|
#else
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) || defined(WIN32)
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifdef MAX_PATH
|
||||||
|
#define PATH_MAX MAX_PATH
|
||||||
|
#elif defined (MAXPATHLEN)
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
|
#else
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This structure is used to access the individual fields of 32-bit ieee
|
||||||
|
// floating point numbers. This will not be compatible with compilers that
|
||||||
|
// allocate bit fields from the most significant bits, although I'm not sure
|
||||||
|
// how common that is.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned mantissa : 23;
|
||||||
|
unsigned exponent : 8;
|
||||||
|
unsigned sign : 1;
|
||||||
|
} f32;
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#undef VERSION_OS
|
||||||
|
#define VERSION_OS "Win32"
|
||||||
|
#endif
|
||||||
|
#define VERSION_STR "4.2 "
|
||||||
|
#define DATE_STR "2005-04-02"
|
||||||
|
|
||||||
|
// ID3v1 and APEv2 TAG formats (may occur at the end of WavPack files)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uchar tag_id [3], title [30], artist [30], album [30];
|
||||||
|
uchar year [4], comment [30], genre;
|
||||||
|
} ID3_Tag;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ID [8];
|
||||||
|
int32_t version, length, item_count, flags;
|
||||||
|
char res [8];
|
||||||
|
} APE_Tag_Hdr;
|
||||||
|
|
||||||
|
#define APE_Tag_Hdr_Format "8LLLL"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ID3_Tag id3_tag;
|
||||||
|
APE_Tag_Hdr ape_tag_hdr;
|
||||||
|
char *ape_tag_data;
|
||||||
|
} M_Tag;
|
||||||
|
|
||||||
|
// RIFF / wav header formats (these occur at the beginning of both wav files
|
||||||
|
// and pre-4.0 WavPack files that are not in the "raw" mode)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ckID [4];
|
||||||
|
uint32_t ckSize;
|
||||||
|
char formType [4];
|
||||||
|
} RiffChunkHeader;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ckID [4];
|
||||||
|
uint32_t ckSize;
|
||||||
|
} ChunkHeader;
|
||||||
|
|
||||||
|
#define ChunkHeaderFormat "4L"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ushort FormatTag, NumChannels;
|
||||||
|
uint32_t SampleRate, BytesPerSecond;
|
||||||
|
ushort BlockAlign, BitsPerSample;
|
||||||
|
ushort cbSize, ValidBitsPerSample;
|
||||||
|
int32_t ChannelMask;
|
||||||
|
ushort SubFormat;
|
||||||
|
char GUID [14];
|
||||||
|
} WaveHeader;
|
||||||
|
|
||||||
|
#define WaveHeaderFormat "SSLLSSSSLS"
|
||||||
|
|
||||||
|
////////////////////////////// WavPack Header /////////////////////////////////
|
||||||
|
|
||||||
|
// Note that this is the ONLY structure that is written to (or read from)
|
||||||
|
// WavPack 4.0 files, and is the preamble to every block in both the .wv
|
||||||
|
// and .wvc files.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ckID [4];
|
||||||
|
uint32_t ckSize;
|
||||||
|
short version;
|
||||||
|
uchar track_no, index_no;
|
||||||
|
uint32_t total_samples, block_index, block_samples, flags, crc;
|
||||||
|
} WavpackHeader;
|
||||||
|
|
||||||
|
#define WavpackHeaderFormat "4LS2LLLLL"
|
||||||
|
|
||||||
|
// or-values for "flags"
|
||||||
|
|
||||||
|
#define BYTES_STORED 3 // 1-4 bytes/sample
|
||||||
|
#define MONO_FLAG 4 // not stereo
|
||||||
|
#define HYBRID_FLAG 8 // hybrid mode
|
||||||
|
#define JOINT_STEREO 0x10 // joint stereo
|
||||||
|
#define CROSS_DECORR 0x20 // no-delay cross decorrelation
|
||||||
|
#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||||
|
#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
|
||||||
|
|
||||||
|
#define INT32_DATA 0x100 // special extended int handling
|
||||||
|
#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
|
||||||
|
#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
|
||||||
|
|
||||||
|
#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
|
||||||
|
#define FINAL_BLOCK 0x1000 // final block of multichannel segment
|
||||||
|
|
||||||
|
#define SHIFT_LSB 13
|
||||||
|
#define SHIFT_MASK (0x1fL << SHIFT_LSB)
|
||||||
|
|
||||||
|
#define MAG_LSB 18
|
||||||
|
#define MAG_MASK (0x1fL << MAG_LSB)
|
||||||
|
|
||||||
|
#define SRATE_LSB 23
|
||||||
|
#define SRATE_MASK (0xfL << SRATE_LSB)
|
||||||
|
|
||||||
|
#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
|
||||||
|
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
|
||||||
|
#define UNKNOWN_FLAGS 0xC0000000 // also reserved, but refuse decode if
|
||||||
|
// encountered
|
||||||
|
|
||||||
|
//////////////////////////// WavPack Metadata /////////////////////////////////
|
||||||
|
|
||||||
|
// This is an internal representation of metadata.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t byte_length;
|
||||||
|
void *data;
|
||||||
|
uchar id;
|
||||||
|
} WavpackMetadata;
|
||||||
|
|
||||||
|
#define ID_OPTIONAL_DATA 0x20
|
||||||
|
#define ID_ODD_SIZE 0x40
|
||||||
|
#define ID_LARGE 0x80
|
||||||
|
|
||||||
|
#define ID_DUMMY 0x0
|
||||||
|
#define ID_ENCODER_INFO 0x1
|
||||||
|
#define ID_DECORR_TERMS 0x2
|
||||||
|
#define ID_DECORR_WEIGHTS 0x3
|
||||||
|
#define ID_DECORR_SAMPLES 0x4
|
||||||
|
#define ID_ENTROPY_VARS 0x5
|
||||||
|
#define ID_HYBRID_PROFILE 0x6
|
||||||
|
#define ID_SHAPING_WEIGHTS 0x7
|
||||||
|
#define ID_FLOAT_INFO 0x8
|
||||||
|
#define ID_INT32_INFO 0x9
|
||||||
|
#define ID_WV_BITSTREAM 0xa
|
||||||
|
#define ID_WVC_BITSTREAM 0xb
|
||||||
|
#define ID_WVX_BITSTREAM 0xc
|
||||||
|
#define ID_CHANNEL_INFO 0xd
|
||||||
|
|
||||||
|
#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
|
||||||
|
#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
|
||||||
|
#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3)
|
||||||
|
#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4)
|
||||||
|
#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
|
||||||
|
#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
|
||||||
|
|
||||||
|
///////////////////////// WavPack Configuration ///////////////////////////////
|
||||||
|
|
||||||
|
// This internal structure is used during encode to provide configuration to
|
||||||
|
// the encoding engine and during decoding to provide fle information back to
|
||||||
|
// the higher level functions. Not all fields are used in both modes.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float bitrate, shaping_weight;
|
||||||
|
int bits_per_sample, bytes_per_sample;
|
||||||
|
int qmode, flags, xmode, num_channels, float_norm_exp;
|
||||||
|
int32_t block_samples, extra_flags, sample_rate, channel_mask;
|
||||||
|
uchar md5_checksum [16], md5_read;
|
||||||
|
int num_tag_strings;
|
||||||
|
char **tag_strings;
|
||||||
|
} WavpackConfig;
|
||||||
|
|
||||||
|
#define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample
|
||||||
|
#define CONFIG_MONO_FLAG 4 // not stereo
|
||||||
|
#define CONFIG_HYBRID_FLAG 8 // hybrid mode
|
||||||
|
#define CONFIG_JOINT_STEREO 0x10 // joint stereo
|
||||||
|
#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation
|
||||||
|
#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||||
|
#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data
|
||||||
|
|
||||||
|
#define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats
|
||||||
|
#define CONFIG_FAST_FLAG 0x200 // fast mode
|
||||||
|
#define CONFIG_VERY_FAST_FLAG 0x400 // double fast
|
||||||
|
#define CONFIG_HIGH_FLAG 0x800 // high quality mode
|
||||||
|
#define CONFIG_VERY_HIGH_FLAG 0x1000 // double high (not used yet)
|
||||||
|
#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
|
||||||
|
#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping
|
||||||
|
#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
|
||||||
|
#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
|
||||||
|
#define CONFIG_COPY_TIME 0x20000 // copy file-time from source
|
||||||
|
#define CONFIG_CREATE_EXE 0x40000 // create executable
|
||||||
|
#define CONFIG_CREATE_WVC 0x80000 // create correction file
|
||||||
|
#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression
|
||||||
|
#define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode
|
||||||
|
#define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet)
|
||||||
|
#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
|
||||||
|
#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information)
|
||||||
|
#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
|
||||||
|
#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
|
||||||
|
#define CONFIG_MD5_CHECKSUM 0x8000000 // compute & store MD5 signature
|
||||||
|
#define CONFIG_QUIET_MODE 0x10000000 // don't report progress %
|
||||||
|
#define CONFIG_IGNORE_LENGTH 0x20000000 // ignore length in wav header
|
||||||
|
|
||||||
|
#define EXTRA_SCAN_ONLY 1
|
||||||
|
#define EXTRA_STEREO_MODES 2
|
||||||
|
//#define EXTRA_CHECK_TERMS 4
|
||||||
|
#define EXTRA_TRY_DELTAS 8
|
||||||
|
#define EXTRA_ADJUST_DELTAS 16
|
||||||
|
#define EXTRA_SORT_FIRST 32
|
||||||
|
#define EXTRA_BRANCHES 0x1c0
|
||||||
|
#define EXTRA_SKIP_8TO16 512
|
||||||
|
#define EXTRA_TERMS 0x3c00
|
||||||
|
#define EXTRA_DUMP_TERMS 16384
|
||||||
|
#define EXTRA_SORT_LAST 32768
|
||||||
|
|
||||||
|
//////////////////////////////// WavPack Stream ///////////////////////////////
|
||||||
|
|
||||||
|
// This internal structure contains everything required to handle a WavPack
|
||||||
|
// "stream", which is defined as a stereo or mono stream of audio samples. For
|
||||||
|
// multichannel audio several of these would be required. Each stream contains
|
||||||
|
// pointers to hold a complete allocated block of WavPack data, although it's
|
||||||
|
// possible to decode WavPack blocks without buffering an entire block.
|
||||||
|
|
||||||
|
typedef struct bs {
|
||||||
|
uchar *buf, *end, *ptr;
|
||||||
|
void (*wrap)(struct bs *bs);
|
||||||
|
int error, bc;
|
||||||
|
uint32_t sr;
|
||||||
|
} Bitstream;
|
||||||
|
|
||||||
|
#define MAX_STREAMS 8
|
||||||
|
#define MAX_NTERMS 16
|
||||||
|
#define MAX_TERM 8
|
||||||
|
|
||||||
|
struct decorr_pass {
|
||||||
|
int term, delta, weight_A, weight_B;
|
||||||
|
int32_t samples_A [MAX_TERM], samples_B [MAX_TERM];
|
||||||
|
int32_t aweight_A, aweight_B;
|
||||||
|
#ifdef PACK
|
||||||
|
int32_t sum_A, sum_B, min, max;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WavpackHeader wphdr;
|
||||||
|
|
||||||
|
uchar *blockbuff, *blockend;
|
||||||
|
uchar *block2buff, *block2end;
|
||||||
|
int32_t *sample_buffer;
|
||||||
|
|
||||||
|
uint32_t sample_index, crc, crc_x, crc_wvx;
|
||||||
|
Bitstream wvbits, wvcbits, wvxbits;
|
||||||
|
int bits, num_terms, mute_error;
|
||||||
|
float delta_decay;
|
||||||
|
|
||||||
|
uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups;
|
||||||
|
uchar float_flags, float_shift, float_max_exp, float_norm_exp;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int32_t shaping_acc [2], shaping_delta [2], error [2];
|
||||||
|
double noise_sum, noise_ave, noise_max;
|
||||||
|
} dc;
|
||||||
|
|
||||||
|
struct decorr_pass decorr_passes [MAX_NTERMS];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t bitrate_delta [2], bitrate_acc [2];
|
||||||
|
uint32_t median [3] [2], slow_level [2], error_limit [2];
|
||||||
|
uint32_t pend_data, holding_one, zeros_acc;
|
||||||
|
int holding_zero, pend_count;
|
||||||
|
} w;
|
||||||
|
} WavpackStream;
|
||||||
|
|
||||||
|
// flags for float_flags:
|
||||||
|
|
||||||
|
#define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1'
|
||||||
|
#define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same
|
||||||
|
#define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally
|
||||||
|
#define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros
|
||||||
|
#define FLOAT_NEG_ZEROS 0x10 // contains negative zeros
|
||||||
|
#define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.)
|
||||||
|
|
||||||
|
/////////////////////////////// WavPack Context ///////////////////////////////
|
||||||
|
|
||||||
|
// This internal structure holds everything required to encode or decode WavPack
|
||||||
|
// files. It is recommended that direct access to this structure be minimized
|
||||||
|
// and the provided utilities used instead.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
|
||||||
|
uint32_t (*get_pos)(void *id);
|
||||||
|
int (*set_pos_abs)(void *id, uint32_t pos);
|
||||||
|
int (*set_pos_rel)(void *id, int32_t delta, int mode);
|
||||||
|
int (*push_back_byte)(void *id, int c);
|
||||||
|
uint32_t (*get_length)(void *id);
|
||||||
|
int (*can_seek)(void *id);
|
||||||
|
} stream_reader;
|
||||||
|
|
||||||
|
typedef int (*blockout)(void *id, void *data, int32_t bcount);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WavpackConfig config;
|
||||||
|
|
||||||
|
WavpackMetadata *metadata;
|
||||||
|
uint32_t metabytes;
|
||||||
|
int metacount;
|
||||||
|
|
||||||
|
uchar *wrapper_data;
|
||||||
|
uint32_t wrapper_bytes;
|
||||||
|
|
||||||
|
blockout blockout;
|
||||||
|
void *wv_out, *wvc_out;
|
||||||
|
|
||||||
|
stream_reader *reader;
|
||||||
|
void *wv_in, *wvc_in;
|
||||||
|
|
||||||
|
uint32_t filelen, file2len, filepos, file2pos, total_samples, crc_errors, first_flags;
|
||||||
|
int wvc_flag, open_flags, norm_offset, reduced_channels, lossy_blocks, close_files;
|
||||||
|
int block_samples, max_samples, acc_samples;
|
||||||
|
M_Tag m_tag;
|
||||||
|
|
||||||
|
int current_stream, num_streams;
|
||||||
|
WavpackStream *streams [8];
|
||||||
|
void *stream3;
|
||||||
|
|
||||||
|
char error_message [80];
|
||||||
|
} WavpackContext;
|
||||||
|
|
||||||
|
//////////////////////// function prototypes and macros //////////////////////
|
||||||
|
|
||||||
|
#define CLEAR(destin) memset (&destin, 0, sizeof (destin));
|
||||||
|
|
||||||
|
// these macros implement the weight application and update operations
|
||||||
|
// that are at the heart of the decorrelation loops
|
||||||
|
|
||||||
|
#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
|
||||||
|
|
||||||
|
#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
|
||||||
|
(((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
|
||||||
|
|
||||||
|
#if 1 // PERFCOND
|
||||||
|
#define apply_weight(weight, sample) (sample != (short) sample ? \
|
||||||
|
apply_weight_f (weight, sample) : apply_weight_i (weight, sample))
|
||||||
|
#else
|
||||||
|
#define apply_weight(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1 // PERFCOND
|
||||||
|
#define update_weight(weight, delta, source, result) \
|
||||||
|
if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta;
|
||||||
|
#else
|
||||||
|
#define update_weight(weight, delta, source, result) \
|
||||||
|
if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define update_weight_d1(weight, delta, source, result) \
|
||||||
|
if (source && result) weight -= (((source ^ result) >> 30) & 2) - 1;
|
||||||
|
|
||||||
|
#define update_weight_d2(weight, delta, source, result) \
|
||||||
|
if (source && result) weight -= (((source ^ result) >> 29) & 4) - 2;
|
||||||
|
|
||||||
|
#define update_weight_clip(weight, delta, source, result) \
|
||||||
|
if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \
|
||||||
|
weight = weight < 0 ? -1024 : 1024;
|
||||||
|
|
||||||
|
#define update_weight_clip_d1(weight, delta, source, result) \
|
||||||
|
if (source && result && abs (weight -= (((source ^ result) >> 30) & 2) - 1) > 1024) \
|
||||||
|
weight = weight < 0 ? -1024 : 1024;
|
||||||
|
|
||||||
|
#define update_weight_clip_d2(weight, delta, source, result) \
|
||||||
|
if (source && result && abs (weight -= (((source ^ result) >> 29) & 4) - 2) > 1024) \
|
||||||
|
weight = weight < 0 ? -1024 : 1024;
|
||||||
|
|
||||||
|
// bits.c
|
||||||
|
|
||||||
|
void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end);
|
||||||
|
void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end);
|
||||||
|
uint32_t bs_close_read (Bitstream *bs);
|
||||||
|
uint32_t bs_close_write (Bitstream *bs);
|
||||||
|
|
||||||
|
int DoReadFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, uint32_t *lpNumberOfBytesRead);
|
||||||
|
int DoWriteFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToWrite, uint32_t *lpNumberOfBytesWritten);
|
||||||
|
uint32_t DoGetFileSize (FILE *hFile), DoGetFilePosition (FILE *hFile);
|
||||||
|
int DoSetFilePositionRelative (FILE *hFile, int32_t pos, int mode);
|
||||||
|
int DoSetFilePositionAbsolute (FILE *hFile, uint32_t pos);
|
||||||
|
int DoUngetc (int c, FILE *hFile), DoDeleteFile (char *filename);
|
||||||
|
int DoCloseHandle (FILE *hFile), DoTruncateFile (FILE *hFile);
|
||||||
|
|
||||||
|
#define bs_is_open(bs) ((bs)->ptr != NULL)
|
||||||
|
|
||||||
|
#define getbit(bs) ( \
|
||||||
|
(((bs)->bc) ? \
|
||||||
|
((bs)->bc--, (bs)->sr & 1) : \
|
||||||
|
(((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = 7, ((bs)->sr = *((bs)->ptr)) & 1) \
|
||||||
|
) ? \
|
||||||
|
((bs)->sr >>= 1, 1) : \
|
||||||
|
((bs)->sr >>= 1, 0) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define getbits(value, nbits, bs) { \
|
||||||
|
while ((nbits) > (bs)->bc) { \
|
||||||
|
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||||
|
(bs)->sr |= (int32_t)*((bs)->ptr) << (bs)->bc; \
|
||||||
|
(bs)->bc += 8; \
|
||||||
|
} \
|
||||||
|
*(value) = (bs)->sr; \
|
||||||
|
(bs)->sr >>= (nbits); \
|
||||||
|
(bs)->bc -= (nbits); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define putbit(bit, bs) { if (bit) (bs)->sr |= (1 << (bs)->bc); \
|
||||||
|
if (++((bs)->bc) == 8) { \
|
||||||
|
*((bs)->ptr) = (bs)->sr; \
|
||||||
|
(bs)->sr = (bs)->bc = 0; \
|
||||||
|
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||||
|
}}
|
||||||
|
|
||||||
|
#define putbit_0(bs) { \
|
||||||
|
if (++((bs)->bc) == 8) { \
|
||||||
|
*((bs)->ptr) = (bs)->sr; \
|
||||||
|
(bs)->sr = (bs)->bc = 0; \
|
||||||
|
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||||
|
}}
|
||||||
|
|
||||||
|
#define putbit_1(bs) { (bs)->sr |= (1 << (bs)->bc); \
|
||||||
|
if (++((bs)->bc) == 8) { \
|
||||||
|
*((bs)->ptr) = (bs)->sr; \
|
||||||
|
(bs)->sr = (bs)->bc = 0; \
|
||||||
|
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||||
|
}}
|
||||||
|
|
||||||
|
#define putbits(value, nbits, bs) { \
|
||||||
|
(bs)->sr |= (int32_t)(value) << (bs)->bc; \
|
||||||
|
if (((bs)->bc += (nbits)) >= 8) \
|
||||||
|
do { \
|
||||||
|
*((bs)->ptr) = (bs)->sr; \
|
||||||
|
(bs)->sr >>= 8; \
|
||||||
|
if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
|
||||||
|
} while (((bs)->bc -= 8) >= 8); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void little_endian_to_native (void *data, char *format);
|
||||||
|
void native_to_little_endian (void *data, char *format);
|
||||||
|
|
||||||
|
// pack.c
|
||||||
|
|
||||||
|
void pack_init (WavpackContext *wpc);
|
||||||
|
int pack_block (WavpackContext *wpc, int32_t *buffer);
|
||||||
|
double pack_noise (WavpackContext *wpc, double *peak);
|
||||||
|
|
||||||
|
// unpack.c
|
||||||
|
|
||||||
|
int unpack_init (WavpackContext *wpc);
|
||||||
|
int init_wv_bitstream (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int init_wvc_bitstream (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int init_wvx_bitstream (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||||
|
int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||||
|
int read_wrapper_data (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||||
|
int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count);
|
||||||
|
int check_crc_error (WavpackContext *wpc);
|
||||||
|
|
||||||
|
// unpack3.c
|
||||||
|
|
||||||
|
WavpackContext *open_file3 (WavpackContext *wpc, char *error);
|
||||||
|
int32_t unpack_samples3 (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count);
|
||||||
|
int seek_sample3 (WavpackContext *wpc, uint32_t desired_index);
|
||||||
|
uint32_t get_sample_index3 (WavpackContext *wpc);
|
||||||
|
void free_stream3 (WavpackContext *wpc);
|
||||||
|
int get_version3 (WavpackContext *wpc);
|
||||||
|
|
||||||
|
// utils.c
|
||||||
|
|
||||||
|
int copy_timestamp (const char *src_filename, const char *dst_filename);
|
||||||
|
char *filespec_ext (char *filespec), *filespec_path (char *filespec);
|
||||||
|
char *filespec_name (char *filespec), *filespec_wild (char *filespec);
|
||||||
|
void error_line (char *error, ...), finish_line (void);
|
||||||
|
void setup_break (void);
|
||||||
|
int check_break (void);
|
||||||
|
char yna (void);
|
||||||
|
void AnsiToUTF8 (char *string, int len);
|
||||||
|
|
||||||
|
#define FN_FIT(fn) ((strlen (fn) > 30) ? filespec_name (fn) : fn)
|
||||||
|
|
||||||
|
// metadata.c stuff
|
||||||
|
|
||||||
|
int read_metadata_buff (WavpackMetadata *wpmd, uchar *blockbuff, uchar **buffptr);
|
||||||
|
int write_metadata_block (WavpackContext *wpc);
|
||||||
|
int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end);
|
||||||
|
int add_to_metadata (WavpackContext *wpc, void *data, uint32_t bcount, uchar id);
|
||||||
|
int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd);
|
||||||
|
void free_metadata (WavpackMetadata *wpmd);
|
||||||
|
|
||||||
|
// words.c stuff
|
||||||
|
|
||||||
|
void init_words (WavpackStream *wps);
|
||||||
|
void word_set_bitrate (WavpackStream *wps);
|
||||||
|
void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
void write_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int32_t FASTCALL send_word (WavpackStream *wps, int32_t value, int chan);
|
||||||
|
void FASTCALL send_word_lossless (WavpackStream *wps, int32_t value, int chan);
|
||||||
|
int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction);
|
||||||
|
int32_t FASTCALL get_word_lossless (WavpackStream *wps, int chan);
|
||||||
|
void flush_word (WavpackStream *wps);
|
||||||
|
int32_t nosend_word (WavpackStream *wps, int32_t value, int chan);
|
||||||
|
void scan_word (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int dir);
|
||||||
|
|
||||||
|
int log2s (int32_t value);
|
||||||
|
int32_t exp2s (int log);
|
||||||
|
uint32_t log2buffer (int32_t *samples, uint32_t num_samples);
|
||||||
|
|
||||||
|
char store_weight (int weight);
|
||||||
|
int restore_weight (char weight);
|
||||||
|
|
||||||
|
#define WORD_EOF (1L << 31)
|
||||||
|
|
||||||
|
// float.c
|
||||||
|
|
||||||
|
void write_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values);
|
||||||
|
void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values);
|
||||||
|
int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
|
||||||
|
void float_values (WavpackStream *wps, int32_t *values, int32_t num_values);
|
||||||
|
void float_normalize (int32_t *values, int32_t num_values, int delta_exp);
|
||||||
|
|
||||||
|
// analyze?.c
|
||||||
|
|
||||||
|
void analyze_stereo (WavpackContext *wpc, int32_t *samples);
|
||||||
|
void analyze_mono (WavpackContext *wpc, int32_t *samples);
|
||||||
|
|
||||||
|
// wputils.c
|
||||||
|
|
||||||
|
WavpackContext *WavpackOpenFileInputEx (stream_reader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
|
||||||
|
WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset);
|
||||||
|
|
||||||
|
#define OPEN_WVC 0x1 // open/read "correction" file
|
||||||
|
#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file)
|
||||||
|
#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF)
|
||||||
|
#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix)
|
||||||
|
#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0
|
||||||
|
#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks
|
||||||
|
// w/o regard to header file position info
|
||||||
|
|
||||||
|
int WavpackGetMode (WavpackContext *wpc);
|
||||||
|
|
||||||
|
#define MODE_WVC 0x1
|
||||||
|
#define MODE_LOSSLESS 0x2
|
||||||
|
#define MODE_HYBRID 0x4
|
||||||
|
#define MODE_FLOAT 0x8
|
||||||
|
#define MODE_VALID_TAG 0x10
|
||||||
|
#define MODE_HIGH 0x20
|
||||||
|
#define MODE_FAST 0x40
|
||||||
|
#define MODE_EXTRA 0x80
|
||||||
|
#define MODE_APETAG 0x100
|
||||||
|
#define MODE_SFX 0x200
|
||||||
|
|
||||||
|
int WavpackGetVersion (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
|
||||||
|
uint32_t WavpackGetNumSamples (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
|
||||||
|
int WavpackGetNumErrors (WavpackContext *wpc);
|
||||||
|
int WavpackLossyBlocks (WavpackContext *wpc);
|
||||||
|
int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
|
||||||
|
WavpackContext *WavpackCloseFile (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackGetSampleRate (WavpackContext *wpc);
|
||||||
|
int WavpackGetBitsPerSample (WavpackContext *wpc);
|
||||||
|
int WavpackGetBytesPerSample (WavpackContext *wpc);
|
||||||
|
int WavpackGetNumChannels (WavpackContext *wpc);
|
||||||
|
int WavpackGetReducedChannels (WavpackContext *wpc);
|
||||||
|
int WavpackGetMD5Sum (WavpackContext *wpc, uchar data [16]);
|
||||||
|
uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
|
||||||
|
uchar *WavpackGetWrapperData (WavpackContext *wpc);
|
||||||
|
void WavpackFreeWrapper (WavpackContext *wpc);
|
||||||
|
double WavpackGetProgress (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackGetFileSize (WavpackContext *wpc);
|
||||||
|
double WavpackGetRatio (WavpackContext *wpc);
|
||||||
|
double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
|
||||||
|
double WavpackGetInstantBitrate (WavpackContext *wpc);
|
||||||
|
int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size);
|
||||||
|
int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value);
|
||||||
|
int WavpackWriteTag (WavpackContext *wpc);
|
||||||
|
|
||||||
|
WavpackContext *WavpackOpenFileOutput (blockout blockout, void *wv_id, void *wvc_id);
|
||||||
|
int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
|
||||||
|
int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
|
||||||
|
int WavpackStoreMD5Sum (WavpackContext *wpc, uchar data [16]);
|
||||||
|
int WavpackPackInit (WavpackContext *wpc);
|
||||||
|
int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
|
||||||
|
int WavpackFlushSamples (WavpackContext *wpc);
|
||||||
|
void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
|
||||||
|
void *WavpackGetWrapperLocation (void *first_block);
|
||||||
|
|
||||||
|
#endif
|
11
Libraries/WavPack/Files/wavpack.pc.in
Normal file
11
Libraries/WavPack/Files/wavpack.pc.in
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
libdir=${prefix}/lib
|
||||||
|
includedir=${prefix}/include
|
||||||
|
|
||||||
|
Name: wavpack
|
||||||
|
Description: wavpack library
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Requires:
|
||||||
|
Conflicts:
|
||||||
|
Libs: -L${libdir} -lwavpack @ICONV@
|
||||||
|
Cflags: -I${includedir} -DPACK -DUNPACK -DUSE_FSTREAMS -DTAGS -DSEEKING -DVER3
|
1437
Libraries/WavPack/Files/words.c
Normal file
1437
Libraries/WavPack/Files/words.c
Normal file
File diff suppressed because it is too large
Load diff
2107
Libraries/WavPack/Files/wputils.c
Normal file
2107
Libraries/WavPack/Files/wputils.c
Normal file
File diff suppressed because it is too large
Load diff
163
Libraries/WavPack/Files/wputils.h
Normal file
163
Libraries/WavPack/Files/wputils.h
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// wputils.h
|
||||||
|
|
||||||
|
#ifndef WPUTILS_H
|
||||||
|
#define WPUTILS_H
|
||||||
|
|
||||||
|
// This header file contains all the definitions required to use the
|
||||||
|
// functions in "wputils.c" to read and write WavPack files and streams.
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||||
|
#include <stdlib.h>
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef __int64 int64_t;
|
||||||
|
typedef __int32 int32_t;
|
||||||
|
typedef __int16 int16_t;
|
||||||
|
typedef __int8 int8_t;
|
||||||
|
typedef float float32_t;
|
||||||
|
#else
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) || defined(WIN32)
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////////////////// WavPack Configuration ///////////////////////////////
|
||||||
|
|
||||||
|
// This external structure is used during encode to provide configuration to
|
||||||
|
// the encoding engine and during decoding to provide fle information back to
|
||||||
|
// the higher level functions. Not all fields are used in both modes.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float bitrate, shaping_weight;
|
||||||
|
int bits_per_sample, bytes_per_sample;
|
||||||
|
int qmode, flags, xmode, num_channels, float_norm_exp;
|
||||||
|
int32_t block_samples, extra_flags, sample_rate, channel_mask;
|
||||||
|
uchar md5_checksum [16], md5_read;
|
||||||
|
int num_tag_strings;
|
||||||
|
char **tag_strings;
|
||||||
|
} WavpackConfig;
|
||||||
|
|
||||||
|
#define CONFIG_HYBRID_FLAG 8 // hybrid mode
|
||||||
|
#define CONFIG_JOINT_STEREO 0x10 // joint stereo
|
||||||
|
#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||||
|
#define CONFIG_FAST_FLAG 0x200 // fast mode
|
||||||
|
#define CONFIG_HIGH_FLAG 0x800 // high quality mode
|
||||||
|
#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
|
||||||
|
#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
|
||||||
|
#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
|
||||||
|
#define CONFIG_CREATE_WVC 0x80000 // create correction file
|
||||||
|
#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression
|
||||||
|
#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
|
||||||
|
#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
|
||||||
|
#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
|
||||||
|
|
||||||
|
////////////// Callbacks used for reading & writing WavPack streams //////////
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
|
||||||
|
uint32_t (*get_pos)(void *id);
|
||||||
|
int (*set_pos_abs)(void *id, uint32_t pos);
|
||||||
|
int (*set_pos_rel)(void *id, int32_t delta, int mode);
|
||||||
|
int (*push_back_byte)(void *id, int c);
|
||||||
|
uint32_t (*get_length)(void *id);
|
||||||
|
int (*can_seek)(void *id);
|
||||||
|
} stream_reader;
|
||||||
|
|
||||||
|
typedef int (*blockout)(void *id, void *data, int32_t bcount);
|
||||||
|
|
||||||
|
//////////////////////// function prototypes and macros //////////////////////
|
||||||
|
|
||||||
|
typedef void WavpackContext;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WavpackContext *WavpackOpenFileInputEx (stream_reader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
|
||||||
|
WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset);
|
||||||
|
|
||||||
|
#define OPEN_WVC 0x1 // open/read "correction" file
|
||||||
|
#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file)
|
||||||
|
#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF)
|
||||||
|
#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix)
|
||||||
|
#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0
|
||||||
|
#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks
|
||||||
|
// w/o regard to header file position info
|
||||||
|
|
||||||
|
int WavpackGetMode (WavpackContext *wpc);
|
||||||
|
|
||||||
|
#define MODE_WVC 0x1
|
||||||
|
#define MODE_LOSSLESS 0x2
|
||||||
|
#define MODE_HYBRID 0x4
|
||||||
|
#define MODE_FLOAT 0x8
|
||||||
|
#define MODE_VALID_TAG 0x10
|
||||||
|
#define MODE_HIGH 0x20
|
||||||
|
#define MODE_FAST 0x40
|
||||||
|
#define MODE_EXTRA 0x80
|
||||||
|
#define MODE_APETAG 0x100
|
||||||
|
#define MODE_SFX 0x200
|
||||||
|
|
||||||
|
int WavpackGetVersion (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
|
||||||
|
uint32_t WavpackGetNumSamples (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
|
||||||
|
int WavpackGetNumErrors (WavpackContext *wpc);
|
||||||
|
int WavpackLossyBlocks (WavpackContext *wpc);
|
||||||
|
int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
|
||||||
|
WavpackContext *WavpackCloseFile (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackGetSampleRate (WavpackContext *wpc);
|
||||||
|
int WavpackGetBitsPerSample (WavpackContext *wpc);
|
||||||
|
int WavpackGetBytesPerSample (WavpackContext *wpc);
|
||||||
|
int WavpackGetNumChannels (WavpackContext *wpc);
|
||||||
|
int WavpackGetReducedChannels (WavpackContext *wpc);
|
||||||
|
int WavpackGetFloatNormExp (WavpackContext *wpc);
|
||||||
|
int WavpackGetMD5Sum (WavpackContext *wpc, uchar data [16]);
|
||||||
|
uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
|
||||||
|
uchar *WavpackGetWrapperData (WavpackContext *wpc);
|
||||||
|
void WavpackFreeWrapper (WavpackContext *wpc);
|
||||||
|
double WavpackGetProgress (WavpackContext *wpc);
|
||||||
|
uint32_t WavpackGetFileSize (WavpackContext *wpc);
|
||||||
|
double WavpackGetRatio (WavpackContext *wpc);
|
||||||
|
double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
|
||||||
|
double WavpackGetInstantBitrate (WavpackContext *wpc);
|
||||||
|
int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size);
|
||||||
|
int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value);
|
||||||
|
int WavpackWriteTag (WavpackContext *wpc);
|
||||||
|
|
||||||
|
|
||||||
|
WavpackContext *WavpackOpenFileOutput (blockout blockout, void *wv_id, void *wvc_id);
|
||||||
|
int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
|
||||||
|
int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
|
||||||
|
int WavpackStoreMD5Sum (WavpackContext *wpc, uchar data [16]);
|
||||||
|
int WavpackPackInit (WavpackContext *wpc);
|
||||||
|
int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
|
||||||
|
int WavpackFlushSamples (WavpackContext *wpc);
|
||||||
|
void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
|
||||||
|
void *WavpackGetWrapperLocation (void *first_block);
|
||||||
|
|
||||||
|
// this function is not actually in wputils.c, but is generally useful
|
||||||
|
|
||||||
|
void float_normalize (int32_t *values, int32_t num_values, int delta_exp);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
926
Libraries/WavPack/Files/wvunpack.c
Normal file
926
Libraries/WavPack/Files/wvunpack.c
Normal file
|
@ -0,0 +1,926 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// **** WAVPACK **** //
|
||||||
|
// Hybrid Lossless Wavefile Compressor //
|
||||||
|
// Copyright (c) 1998 - 2005 Conifer Software. //
|
||||||
|
// All Rights Reserved. //
|
||||||
|
// Distributed under the BSD Software License (see license.txt) //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// wvunpack.c
|
||||||
|
|
||||||
|
// This is the main module for the WavPack command-line decompressor.
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
#else
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if defined (__GNUC__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <glob.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#include <dir.h>
|
||||||
|
#elif defined(__GNUC__) && !defined(WIN32)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#else
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "wavpack.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
#define malloc malloc_db
|
||||||
|
#define realloc realloc_db
|
||||||
|
#define free free_db
|
||||||
|
void *malloc_db (uint32_t size);
|
||||||
|
void *realloc_db (void *ptr, uint32_t size);
|
||||||
|
void free_db (void *ptr);
|
||||||
|
int32_t dump_alloc (void);
|
||||||
|
static char *strdup (const char *s)
|
||||||
|
{ char *d = malloc (strlen (s) + 1); return strcpy (d, s); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////////////////////// local variable storage //////////////////////////
|
||||||
|
|
||||||
|
static const char *sign_on = "\n"
|
||||||
|
" WVUNPACK Hybrid Lossless Wavefile Decompressor %s Version %s %s\n"
|
||||||
|
" Copyright (c) 1998 - 2005 Conifer Software. All Rights Reserved.\n\n";
|
||||||
|
|
||||||
|
static const char *usage =
|
||||||
|
" Usage: WVUNPACK [-options] [@]infile[.wv]|- [[@]outfile[.wav]|outpath|-]\n"
|
||||||
|
" (infile may contain wildcards: ?,*)\n\n"
|
||||||
|
" Options: -d = delete source file if successful (use with caution!)\n"
|
||||||
|
" -i = ignore .wvc file (forces hybrid lossy decompression)\n"
|
||||||
|
" -m = calculate and display MD5 signature; verify if lossless\n"
|
||||||
|
" -q = quiet (keep console output to a minimum)\n"
|
||||||
|
" -r = force raw audio decode (skip RIFF headers & trailers)\n"
|
||||||
|
" -s = display summary information only to stdout (no decode)\n"
|
||||||
|
#if defined (WIN32)
|
||||||
|
" -t = copy input file's time stamp to output file(s)\n"
|
||||||
|
#endif
|
||||||
|
" -v = verify source data only (no output file created)\n"
|
||||||
|
" -y = yes to overwrite warning (use with caution!)\n\n"
|
||||||
|
" Web: Visit www.wavpack.com for latest version and info\n";
|
||||||
|
|
||||||
|
static char overwrite_all = 0, delete_source = 0, raw_decode = 0, summary = 0,
|
||||||
|
ignore_wvc = 0, quiet_mode = 0, calc_md5 = 0, copy_time = 0;
|
||||||
|
|
||||||
|
static int num_files, file_index, outbuf_k;
|
||||||
|
|
||||||
|
/////////////////////////// local function declarations ///////////////////////
|
||||||
|
|
||||||
|
static int unpack_file (char *infilename, char *outfilename);
|
||||||
|
static void display_progress (double file_progress);
|
||||||
|
|
||||||
|
#define NO_ERROR 0L
|
||||||
|
#define SOFT_ERROR 1
|
||||||
|
#define HARD_ERROR 2
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The "main" function for the command-line WavPack decompressor. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int main (argc, argv) int argc; char **argv;
|
||||||
|
{
|
||||||
|
int verify_only = 0, usage_error = 0, filelist = 0, add_extension = 0;
|
||||||
|
char *infilename = NULL, *outfilename = NULL;
|
||||||
|
char outpath, **matches = NULL;
|
||||||
|
int result, i;
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
struct ffblk ffblk;
|
||||||
|
#elif defined(WIN32)
|
||||||
|
struct _finddata_t _finddata_t;
|
||||||
|
#else
|
||||||
|
glob_t globs;
|
||||||
|
struct stat fstats;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// loop through command-line arguments
|
||||||
|
|
||||||
|
while (--argc) {
|
||||||
|
#if defined (WIN32)
|
||||||
|
if ((**++argv == '-' || **argv == '/') && (*argv)[1])
|
||||||
|
#else
|
||||||
|
if ((**++argv == '-') && (*argv)[1])
|
||||||
|
#endif
|
||||||
|
while (*++*argv)
|
||||||
|
switch (**argv) {
|
||||||
|
case 'Y': case 'y':
|
||||||
|
overwrite_all = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D': case 'd':
|
||||||
|
delete_source = 1;
|
||||||
|
break;
|
||||||
|
#if defined (WIN32)
|
||||||
|
case 'T': case 't':
|
||||||
|
copy_time = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 'V': case 'v':
|
||||||
|
verify_only = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S': case 's':
|
||||||
|
summary = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'K': case 'k':
|
||||||
|
outbuf_k = strtol (++*argv, argv, 10);
|
||||||
|
--*argv;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M': case 'm':
|
||||||
|
calc_md5 = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'R': case 'r':
|
||||||
|
raw_decode = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Q': case 'q':
|
||||||
|
quiet_mode = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'I': case 'i':
|
||||||
|
ignore_wvc = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error_line ("illegal option: %c !", **argv);
|
||||||
|
usage_error = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!infilename) {
|
||||||
|
infilename = malloc (strlen (*argv) + PATH_MAX);
|
||||||
|
strcpy (infilename, *argv);
|
||||||
|
}
|
||||||
|
else if (!outfilename) {
|
||||||
|
outfilename = malloc (strlen (*argv) + PATH_MAX);
|
||||||
|
strcpy (outfilename, *argv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error_line ("extra unknown argument: %s !", *argv);
|
||||||
|
usage_error = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for various command-line argument problems
|
||||||
|
|
||||||
|
if (verify_only && delete_source) {
|
||||||
|
error_line ("can't delete in verify mode!");
|
||||||
|
delete_source = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verify_only && outfilename) {
|
||||||
|
error_line ("outfile specification and verify mode are incompatible!");
|
||||||
|
usage_error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!quiet_mode && !usage_error)
|
||||||
|
fprintf (stderr, sign_on, VERSION_OS, VERSION_STR, DATE_STR);
|
||||||
|
|
||||||
|
if (!infilename) {
|
||||||
|
printf ("%s", usage);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usage_error) {
|
||||||
|
free (infilename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_break ();
|
||||||
|
|
||||||
|
// If the infile specification begins with a '@', then it actually points
|
||||||
|
// to a file that contains the names of the files to be converted. This
|
||||||
|
// was included for use by Wim Speekenbrink's frontends, but could be used
|
||||||
|
// for other purposes.
|
||||||
|
|
||||||
|
if (infilename [0] == '@') {
|
||||||
|
FILE *list = fopen (infilename+1, "rt");
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (list == NULL) {
|
||||||
|
error_line ("file %s not found!", infilename+1);
|
||||||
|
free(infilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((c = getc (list)) != EOF) {
|
||||||
|
|
||||||
|
while (c == '\n')
|
||||||
|
c = getc (list);
|
||||||
|
|
||||||
|
if (c != EOF) {
|
||||||
|
char *fname = malloc (PATH_MAX);
|
||||||
|
int ci = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
fname [ci++] = c;
|
||||||
|
while ((c = getc (list)) != '\n' && c != EOF && ci < PATH_MAX);
|
||||||
|
|
||||||
|
fname [ci++] = '\0';
|
||||||
|
matches = realloc (matches, ++num_files * sizeof (*matches));
|
||||||
|
matches [num_files - 1] = realloc (fname, ci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (list);
|
||||||
|
free (infilename);
|
||||||
|
infilename = NULL;
|
||||||
|
filelist = 1;
|
||||||
|
}
|
||||||
|
else if (*infilename != '-') { // skip this if infile is stdin (-)
|
||||||
|
if (!filespec_ext (infilename))
|
||||||
|
strcat (infilename, ".wv");
|
||||||
|
|
||||||
|
#ifdef NO_WILDCARDS
|
||||||
|
matches = malloc (sizeof (*matches));
|
||||||
|
matches [num_files++] = infilename;
|
||||||
|
filelist = 1;
|
||||||
|
#else
|
||||||
|
// search for and store any filenames that match the user supplied spec
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
if (findfirst (infilename, &ffblk, 0) == 0) {
|
||||||
|
do {
|
||||||
|
matches = realloc (matches, ++num_files * sizeof (*matches));
|
||||||
|
matches [num_files - 1] = strdup (ffblk.ff_name);
|
||||||
|
} while (findnext (&ffblk) == 0);
|
||||||
|
}
|
||||||
|
#elif defined (WIN32)
|
||||||
|
if ((i = _findfirst (infilename, &_finddata_t)) != -1L) {
|
||||||
|
do {
|
||||||
|
if (!(_finddata_t.attrib & _A_SUBDIR)) {
|
||||||
|
matches = realloc (matches, ++num_files * sizeof (*matches));
|
||||||
|
matches [num_files - 1] = strdup (_finddata_t.name);
|
||||||
|
}
|
||||||
|
} while (_findnext (i, &_finddata_t) == 0);
|
||||||
|
|
||||||
|
_findclose (i);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
i = 0;
|
||||||
|
if (glob(infilename, 0, NULL, &globs) == 0 && globs.gl_pathc > 0) {
|
||||||
|
do {
|
||||||
|
if (stat(globs.gl_pathv[i], &fstats) == 0 && !(fstats.st_mode & S_IFDIR)) {
|
||||||
|
matches = realloc (matches, ++num_files * sizeof (*matches));
|
||||||
|
matches [num_files - 1] = strdup (globs.gl_pathv[i]);
|
||||||
|
}
|
||||||
|
} while (i++ < globs.gl_pathc);
|
||||||
|
}
|
||||||
|
globfree(&globs);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else { // handle case of stdin (-)
|
||||||
|
matches = malloc (sizeof (*matches));
|
||||||
|
matches [num_files++] = infilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the outfile specification begins with a '@', then it actually points
|
||||||
|
// to a file that contains the output specification. This was included for
|
||||||
|
// use by Wim Speekenbrink's frontends because certain filenames could not
|
||||||
|
// be passed on the command-line, but could be used for other purposes.
|
||||||
|
|
||||||
|
if (outfilename && outfilename [0] == '@') {
|
||||||
|
FILE *list = fopen (outfilename+1, "rt");
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (list == NULL) {
|
||||||
|
error_line ("file %s not found!", outfilename+1);
|
||||||
|
free(outfilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((c = getc (list)) == '\n');
|
||||||
|
|
||||||
|
if (c != EOF) {
|
||||||
|
int ci = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
outfilename [ci++] = c;
|
||||||
|
while ((c = getc (list)) != '\n' && c != EOF && ci < PATH_MAX);
|
||||||
|
|
||||||
|
outfilename [ci] = '\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error_line ("output spec file is empty!");
|
||||||
|
free(outfilename);
|
||||||
|
fclose (list);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we found any files to process, this is where we start
|
||||||
|
|
||||||
|
if (num_files) {
|
||||||
|
int soft_errors = 0;
|
||||||
|
|
||||||
|
if (outfilename && *outfilename != '-') {
|
||||||
|
outpath = (filespec_path (outfilename) != NULL);
|
||||||
|
|
||||||
|
if (num_files > 1 && !outpath) {
|
||||||
|
error_line ("%s is not a valid output path", outfilename);
|
||||||
|
free(outfilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
outpath = 0;
|
||||||
|
|
||||||
|
add_extension = !outfilename || outpath || !filespec_ext (outfilename);
|
||||||
|
|
||||||
|
// loop through and process files in list
|
||||||
|
|
||||||
|
for (file_index = 0; file_index < num_files; ++file_index) {
|
||||||
|
if (check_break ())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// get input filename from list
|
||||||
|
|
||||||
|
if (filelist)
|
||||||
|
infilename = matches [file_index];
|
||||||
|
else if (*infilename != '-') {
|
||||||
|
*filespec_name (infilename) = '\0';
|
||||||
|
strcat (infilename, matches [file_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate output filename
|
||||||
|
|
||||||
|
if (outpath) {
|
||||||
|
strcat (outfilename, filespec_name (matches [file_index]));
|
||||||
|
|
||||||
|
if (filespec_ext (outfilename))
|
||||||
|
*filespec_ext (outfilename) = '\0';
|
||||||
|
}
|
||||||
|
else if (!outfilename) {
|
||||||
|
outfilename = malloc (strlen (infilename) + 10);
|
||||||
|
strcpy (outfilename, infilename);
|
||||||
|
|
||||||
|
if (filespec_ext (outfilename))
|
||||||
|
*filespec_ext (outfilename) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outfilename && *outfilename != '-' && add_extension)
|
||||||
|
strcat (outfilename, raw_decode ? ".raw" : ".wav");
|
||||||
|
|
||||||
|
if (num_files > 1)
|
||||||
|
fprintf (stderr, "\n%s:\n", infilename);
|
||||||
|
|
||||||
|
result = unpack_file (infilename, verify_only ? NULL : outfilename);
|
||||||
|
|
||||||
|
if (result == HARD_ERROR)
|
||||||
|
break;
|
||||||
|
else if (result == SOFT_ERROR)
|
||||||
|
++soft_errors;
|
||||||
|
|
||||||
|
// clean up in preparation for potentially another file
|
||||||
|
|
||||||
|
if (outpath)
|
||||||
|
*filespec_name (outfilename) = '\0';
|
||||||
|
else if (*outfilename != '-') {
|
||||||
|
free (outfilename);
|
||||||
|
outfilename = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (matches [file_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_files > 1) {
|
||||||
|
if (soft_errors)
|
||||||
|
fprintf (stderr, "\n **** warning: errors occurred in %d of %d files! ****\n", soft_errors, num_files);
|
||||||
|
else if (!quiet_mode)
|
||||||
|
fprintf (stderr, "\n **** %d files successfully processed ****\n", num_files);
|
||||||
|
}
|
||||||
|
|
||||||
|
free (matches);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error_line (filespec_wild (infilename) ? "nothing to do!" :
|
||||||
|
"file %s not found!", infilename);
|
||||||
|
|
||||||
|
if (outfilename)
|
||||||
|
free(outfilename);
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALLOC
|
||||||
|
error_line ("malloc_count = %d", dump_alloc ());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack the specified WavPack input file into the specified output file name.
|
||||||
|
// This function uses the library routines provided in wputils.c to do all
|
||||||
|
// unpacking. This function takes care of reformatting the data (which is
|
||||||
|
// returned in native-endian longs) to the standard little-endian format. This
|
||||||
|
// function also handles optionally calculating and displaying the MD5 sum of
|
||||||
|
// the resulting audio data and verifying the sum if a sum was stored in the
|
||||||
|
// source and lossless compression is used.
|
||||||
|
|
||||||
|
static uchar *format_samples (int bps, uchar *dst, int32_t *src, uint32_t samcnt);
|
||||||
|
static void dump_summary (WavpackContext *wpc, char *name, FILE *dst);
|
||||||
|
|
||||||
|
extern int delta_blocks [8];
|
||||||
|
|
||||||
|
static int unpack_file (char *infilename, char *outfilename)
|
||||||
|
{
|
||||||
|
int result = NO_ERROR, md5_diff = FALSE, open_flags = 0, bytes_per_sample, num_channels, wvc_mode, bps;
|
||||||
|
uint32_t outfile_length, output_buffer_size, bcount, total_unpacked_samples = 0;
|
||||||
|
uchar *output_buffer = NULL, *output_pointer = NULL;
|
||||||
|
double dtime, progress = -1.0;
|
||||||
|
MD5_CTX md5_context;
|
||||||
|
WavpackContext *wpc;
|
||||||
|
int32_t *temp_buffer;
|
||||||
|
char error [80];
|
||||||
|
FILE *outfile;
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
struct time time1, time2;
|
||||||
|
#elif defined(WIN32)
|
||||||
|
struct _timeb time1, time2;
|
||||||
|
#else
|
||||||
|
struct timeval time1, time2;
|
||||||
|
struct timezone timez;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// use library to open WavPack file
|
||||||
|
|
||||||
|
if (outfilename && !raw_decode)
|
||||||
|
open_flags |= OPEN_WRAPPER;
|
||||||
|
|
||||||
|
if (raw_decode)
|
||||||
|
open_flags |= OPEN_STREAMING;
|
||||||
|
|
||||||
|
if (!ignore_wvc)
|
||||||
|
open_flags |= OPEN_WVC;
|
||||||
|
|
||||||
|
wpc = WavpackOpenFileInput (infilename, error, open_flags, 0);
|
||||||
|
|
||||||
|
if (!wpc) {
|
||||||
|
error_line (error);
|
||||||
|
return SOFT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calc_md5)
|
||||||
|
MD5Init (&md5_context);
|
||||||
|
|
||||||
|
wvc_mode = WavpackGetMode (wpc) & MODE_WVC;
|
||||||
|
num_channels = WavpackGetNumChannels (wpc);
|
||||||
|
bps = WavpackGetBytesPerSample (wpc);
|
||||||
|
bytes_per_sample = num_channels * bps;
|
||||||
|
|
||||||
|
if (summary) {
|
||||||
|
dump_summary (wpc, infilename, stdout);
|
||||||
|
WavpackCloseFile (wpc);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outfilename) {
|
||||||
|
if (*outfilename != '-') {
|
||||||
|
|
||||||
|
// check the output file for overwrite warning required
|
||||||
|
|
||||||
|
if (!overwrite_all && (outfile = fopen (outfilename, "rb")) != NULL) {
|
||||||
|
DoCloseHandle (outfile);
|
||||||
|
fprintf (stderr, "overwrite %s (yes/no/all)? ", FN_FIT (outfilename));
|
||||||
|
SetConsoleTitle ("overwrite?");
|
||||||
|
|
||||||
|
switch (yna ()) {
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
result = SOFT_ERROR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
overwrite_all = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
WavpackCloseFile (wpc);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file for writing
|
||||||
|
|
||||||
|
if ((outfile = fopen (outfilename, "wb")) == NULL) {
|
||||||
|
error_line ("can't create file %s!", outfilename);
|
||||||
|
WavpackCloseFile (wpc);
|
||||||
|
return SOFT_ERROR;
|
||||||
|
}
|
||||||
|
else if (!quiet_mode)
|
||||||
|
fprintf (stderr, "restoring %s,", FN_FIT (outfilename));
|
||||||
|
}
|
||||||
|
else { // come here to open stdout as destination
|
||||||
|
|
||||||
|
outfile = stdout;
|
||||||
|
#if defined(WIN32)
|
||||||
|
setmode (fileno (stdout), O_BINARY);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!quiet_mode)
|
||||||
|
fprintf (stderr, "unpacking %s%s to stdout,", *infilename == '-' ?
|
||||||
|
"stdin" : FN_FIT (infilename), wvc_mode ? " (+.wvc)" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outbuf_k)
|
||||||
|
output_buffer_size = outbuf_k * 1024;
|
||||||
|
else
|
||||||
|
output_buffer_size = 1024 * 256;
|
||||||
|
|
||||||
|
output_pointer = output_buffer = malloc (output_buffer_size);
|
||||||
|
}
|
||||||
|
else { // in verify only mode we don't worry about headers
|
||||||
|
outfile = NULL;
|
||||||
|
|
||||||
|
if (!quiet_mode)
|
||||||
|
fprintf (stderr, "verifying %s%s,", *infilename == '-' ? "stdin" :
|
||||||
|
FN_FIT (infilename), wvc_mode ? " (+.wvc)" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
gettime (&time1);
|
||||||
|
#elif defined(WIN32)
|
||||||
|
_ftime (&time1);
|
||||||
|
#else
|
||||||
|
gettimeofday(&time1,&timez);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (WavpackGetWrapperBytes (wpc)) {
|
||||||
|
if (outfile && (!DoWriteFile (outfile, WavpackGetWrapperData (wpc), WavpackGetWrapperBytes (wpc), &bcount) ||
|
||||||
|
bcount != WavpackGetWrapperBytes (wpc))) {
|
||||||
|
error_line ("can't write .WAV data, disk probably full!");
|
||||||
|
DoTruncateFile (outfile);
|
||||||
|
result = HARD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
WavpackFreeWrapper (wpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_buffer = malloc (4096L * num_channels * 4);
|
||||||
|
|
||||||
|
while (result == NO_ERROR) {
|
||||||
|
uint32_t samples_to_unpack, samples_unpacked;
|
||||||
|
|
||||||
|
if (output_buffer) {
|
||||||
|
samples_to_unpack = (output_buffer_size - (output_pointer - output_buffer)) / bytes_per_sample;
|
||||||
|
|
||||||
|
if (samples_to_unpack > 4096)
|
||||||
|
samples_to_unpack = 4096;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
samples_to_unpack = 4096;
|
||||||
|
|
||||||
|
samples_unpacked = WavpackUnpackSamples (wpc, temp_buffer, samples_to_unpack);
|
||||||
|
total_unpacked_samples += samples_unpacked;
|
||||||
|
|
||||||
|
if (output_buffer) {
|
||||||
|
if (samples_unpacked)
|
||||||
|
output_pointer = format_samples (bps, output_pointer, temp_buffer, samples_unpacked * num_channels);
|
||||||
|
|
||||||
|
if (!samples_unpacked || (output_buffer_size - (output_pointer - output_buffer)) < bytes_per_sample) {
|
||||||
|
if (!DoWriteFile (outfile, output_buffer, output_pointer - output_buffer, &bcount) ||
|
||||||
|
bcount != output_pointer - output_buffer) {
|
||||||
|
error_line ("can't write .WAV data, disk probably full!");
|
||||||
|
DoTruncateFile (outfile);
|
||||||
|
result = HARD_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
output_pointer = output_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calc_md5 && samples_unpacked) {
|
||||||
|
format_samples (bps, (uchar *) temp_buffer, temp_buffer, samples_unpacked * num_channels);
|
||||||
|
MD5Update (&md5_context, temp_buffer, bps * samples_unpacked * num_channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!samples_unpacked)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (check_break ()) {
|
||||||
|
fprintf (stderr, "^C\n");
|
||||||
|
DoTruncateFile (outfile);
|
||||||
|
result = SOFT_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WavpackGetProgress (wpc) != -1.0 &&
|
||||||
|
progress != floor (WavpackGetProgress (wpc) * 100.0 + 0.5)) {
|
||||||
|
int nobs = progress == -1.0;
|
||||||
|
|
||||||
|
progress = WavpackGetProgress (wpc);
|
||||||
|
display_progress (progress);
|
||||||
|
progress = floor (progress * 100.0 + 0.5);
|
||||||
|
|
||||||
|
if (!quiet_mode)
|
||||||
|
fprintf (stderr, "%s%3d%% done...",
|
||||||
|
nobs ? " " : "\b\b\b\b\b\b\b\b\b\b\b\b", (int) progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free (temp_buffer);
|
||||||
|
|
||||||
|
if (output_buffer)
|
||||||
|
free (output_buffer);
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
error_line ("delta = %d, count = %d", i, delta_blocks [i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!check_break () && calc_md5) {
|
||||||
|
char md5_string1 [] = "00000000000000000000000000000000";
|
||||||
|
char md5_string2 [] = "00000000000000000000000000000000";
|
||||||
|
uchar md5_original [16], md5_unpacked [16];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
MD5Final (md5_unpacked, &md5_context);
|
||||||
|
|
||||||
|
if (WavpackGetMD5Sum (wpc, md5_original)) {
|
||||||
|
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
sprintf (md5_string1 + (i * 2), "%02x", md5_original [i]);
|
||||||
|
|
||||||
|
error_line ("original md5: %s", md5_string1);
|
||||||
|
|
||||||
|
if (memcmp (md5_unpacked, md5_original, 16))
|
||||||
|
md5_diff = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
sprintf (md5_string2 + (i * 2), "%02x", md5_unpacked [i]);
|
||||||
|
|
||||||
|
error_line ("unpacked md5: %s", md5_string2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WavpackGetWrapperBytes (wpc)) {
|
||||||
|
if (outfile && result == NO_ERROR &&
|
||||||
|
(!DoWriteFile (outfile, WavpackGetWrapperData (wpc), WavpackGetWrapperBytes (wpc), &bcount) ||
|
||||||
|
bcount != WavpackGetWrapperBytes (wpc))) {
|
||||||
|
error_line ("can't write .WAV data, disk probably full!");
|
||||||
|
DoTruncateFile (outfile);
|
||||||
|
result = HARD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
WavpackFreeWrapper (wpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we are not just in verify only mode, grab the size of the output
|
||||||
|
// file and close the file
|
||||||
|
|
||||||
|
if (outfile != NULL) {
|
||||||
|
fflush (outfile);
|
||||||
|
outfile_length = DoGetFileSize (outfile);
|
||||||
|
|
||||||
|
if (!DoCloseHandle (outfile)) {
|
||||||
|
error_line ("can't close file!");
|
||||||
|
result = SOFT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outfilename && *outfilename != '-' && !outfile_length)
|
||||||
|
DoDeleteFile (outfilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (WIN32)
|
||||||
|
if (result == NO_ERROR && copy_time && outfilename &&
|
||||||
|
!copy_timestamp (infilename, outfilename))
|
||||||
|
error_line ("failure copying time stamp!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (result == NO_ERROR && WavpackGetNumSamples (wpc) != (uint32_t) -1 &&
|
||||||
|
total_unpacked_samples != WavpackGetNumSamples (wpc)) {
|
||||||
|
error_line ("incorrect number of samples!");
|
||||||
|
result = SOFT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == NO_ERROR && WavpackGetNumErrors (wpc)) {
|
||||||
|
error_line ("crc errors detected in %d block(s)!", WavpackGetNumErrors (wpc));
|
||||||
|
result = SOFT_ERROR;
|
||||||
|
}
|
||||||
|
else if (result == NO_ERROR && md5_diff && (WavpackGetMode (wpc) & MODE_LOSSLESS)) {
|
||||||
|
error_line ("MD5 signatures should match, but do not!");
|
||||||
|
result = SOFT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute and display the time consumed along with some other details of
|
||||||
|
// the unpacking operation (assuming there was no error).
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
gettime (&time2);
|
||||||
|
dtime = time2.ti_sec * 100.0 + time2.ti_hund + time2.ti_min * 6000.0 + time2.ti_hour * 360000.00;
|
||||||
|
dtime -= time1.ti_sec * 100.0 + time1.ti_hund + time1.ti_min * 6000.0 + time1.ti_hour * 360000.00;
|
||||||
|
|
||||||
|
if ((dtime /= 100.0) < 0.0)
|
||||||
|
dtime += 86400.0;
|
||||||
|
#elif defined(WIN32)
|
||||||
|
_ftime (&time2);
|
||||||
|
dtime = time2.time + time2.millitm / 1000.0;
|
||||||
|
dtime -= time1.time + time1.millitm / 1000.0;
|
||||||
|
#else
|
||||||
|
gettimeofday(&time2,&timez);
|
||||||
|
dtime = time2.tv_sec + time2.tv_usec / 1000000.0;
|
||||||
|
dtime -= time1.tv_sec + time1.tv_usec / 1000000.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (result == NO_ERROR && !quiet_mode) {
|
||||||
|
char *file, *fext, *oper, *cmode, cratio [16] = "";
|
||||||
|
|
||||||
|
if (outfilename && *outfilename != '-') {
|
||||||
|
file = FN_FIT (outfilename);
|
||||||
|
fext = "";
|
||||||
|
oper = "restored";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
file = (*infilename == '-') ? "stdin" : FN_FIT (infilename);
|
||||||
|
fext = wvc_mode ? " (+.wvc)" : "";
|
||||||
|
oper = outfilename ? "unpacked" : "verified";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WavpackGetMode (wpc) & MODE_LOSSLESS) {
|
||||||
|
cmode = "lossless";
|
||||||
|
|
||||||
|
if (WavpackGetRatio (wpc) != 0.0)
|
||||||
|
sprintf (cratio, ", %.2f%%", 100.0 - WavpackGetRatio (wpc) * 100.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmode = "lossy";
|
||||||
|
|
||||||
|
if (WavpackGetAverageBitrate (wpc, TRUE) != 0.0)
|
||||||
|
sprintf (cratio, ", %d kbps", (int) (WavpackGetAverageBitrate (wpc, TRUE) / 1000.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
error_line ("%s %s%s in %.2f secs (%s%s)", oper, file, fext, dtime, cmode, cratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
WavpackCloseFile (wpc);
|
||||||
|
|
||||||
|
if (result == NO_ERROR && delete_source) {
|
||||||
|
error_line ("%s source file %s", DoDeleteFile (infilename) ?
|
||||||
|
"deleted" : "can't delete", infilename);
|
||||||
|
|
||||||
|
if (wvc_mode) {
|
||||||
|
char in2filename [PATH_MAX];
|
||||||
|
|
||||||
|
strcpy (in2filename, infilename);
|
||||||
|
strcat (in2filename, "c");
|
||||||
|
|
||||||
|
error_line ("%s source file %s", DoDeleteFile (in2filename) ?
|
||||||
|
"deleted" : "can't delete", in2filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reformat samples from longs in processor's native endian mode to
|
||||||
|
// little-endian data with (possibly) less than 4 bytes / sample.
|
||||||
|
|
||||||
|
static uchar *format_samples (int bps, uchar *dst, int32_t *src, uint32_t samcnt)
|
||||||
|
{
|
||||||
|
int32_t temp;
|
||||||
|
|
||||||
|
switch (bps) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
while (samcnt--)
|
||||||
|
*dst++ = *src++ + 128;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
while (samcnt--) {
|
||||||
|
*dst++ = (uchar) (temp = *src++);
|
||||||
|
*dst++ = (uchar) (temp >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
while (samcnt--) {
|
||||||
|
*dst++ = (uchar) (temp = *src++);
|
||||||
|
*dst++ = (uchar) (temp >> 8);
|
||||||
|
*dst++ = (uchar) (temp >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
while (samcnt--) {
|
||||||
|
*dst++ = (uchar) (temp = *src++);
|
||||||
|
*dst++ = (uchar) (temp >> 8);
|
||||||
|
*dst++ = (uchar) (temp >> 16);
|
||||||
|
*dst++ = (uchar) (temp >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_summary (WavpackContext *wpc, char *name, FILE *dst)
|
||||||
|
{
|
||||||
|
int num_channels = WavpackGetNumChannels (wpc);
|
||||||
|
uchar md5_sum [16], modes [80];
|
||||||
|
|
||||||
|
fprintf (dst, "\n");
|
||||||
|
|
||||||
|
if (name && *name != '-') {
|
||||||
|
fprintf (dst, "file name: %s%s\n", name, (WavpackGetMode (wpc) & MODE_WVC) ? " (+wvc)" : "");
|
||||||
|
fprintf (dst, "file size: %lu bytes\n", WavpackGetFileSize (wpc));
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (dst, "source: %d-bit %s at %ld Hz\n", WavpackGetBitsPerSample (wpc),
|
||||||
|
(WavpackGetMode (wpc) & MODE_FLOAT) ? "floats" : "ints",
|
||||||
|
WavpackGetSampleRate (wpc));
|
||||||
|
|
||||||
|
fprintf (dst, "channels: %d (%s)\n", num_channels,
|
||||||
|
num_channels > 2 ? "multichannel" : (num_channels == 1 ? "mono" : "stereo"));
|
||||||
|
|
||||||
|
if (WavpackGetNumSamples (wpc) != (uint32_t) -1) {
|
||||||
|
double seconds = (double) WavpackGetNumSamples (wpc) / WavpackGetSampleRate (wpc);
|
||||||
|
int minutes = (int) floor (seconds / 60.0);
|
||||||
|
int hours = (int) floor (seconds / 3600.0);
|
||||||
|
|
||||||
|
seconds -= minutes * 60.0;
|
||||||
|
minutes -= hours * 60.0;
|
||||||
|
|
||||||
|
fprintf (dst, "duration: %d:%02d:%0.2f\n", hours, minutes, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
modes [0] = 0;
|
||||||
|
|
||||||
|
if (WavpackGetMode (wpc) & MODE_HYBRID)
|
||||||
|
strcat (modes, "hybrid ");
|
||||||
|
|
||||||
|
strcat (modes, (WavpackGetMode (wpc) & MODE_LOSSLESS) ? "lossless" : "lossy");
|
||||||
|
|
||||||
|
if (WavpackGetMode (wpc) & MODE_FAST)
|
||||||
|
strcat (modes, ", fast");
|
||||||
|
else if (WavpackGetMode (wpc) & MODE_HIGH)
|
||||||
|
strcat (modes, ", high");
|
||||||
|
|
||||||
|
if (WavpackGetMode (wpc) & MODE_EXTRA)
|
||||||
|
strcat (modes, ", extra");
|
||||||
|
|
||||||
|
if (WavpackGetMode (wpc) & MODE_SFX)
|
||||||
|
strcat (modes, ", sfx");
|
||||||
|
|
||||||
|
fprintf (dst, "modalities: %s\n", modes);
|
||||||
|
|
||||||
|
if (WavpackGetRatio (wpc) != 0.0) {
|
||||||
|
fprintf (dst, "compression: %.2f%%\n", 100.0 - (100 * WavpackGetRatio (wpc)));
|
||||||
|
fprintf (dst, "ave bitrate: %d kbps\n", (int) ((WavpackGetAverageBitrate (wpc, TRUE) + 500.0) / 1000.0));
|
||||||
|
|
||||||
|
if (WavpackGetMode (wpc) & MODE_WVC)
|
||||||
|
fprintf (dst, "ave lossy bitrate: %d kbps\n", (int) ((WavpackGetAverageBitrate (wpc, FALSE) + 500.0) / 1000.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WavpackGetVersion (wpc))
|
||||||
|
fprintf (dst, "encoder version: %d\n", WavpackGetVersion (wpc));
|
||||||
|
|
||||||
|
if (WavpackGetMD5Sum (wpc, md5_sum)) {
|
||||||
|
char md5_string [] = "00000000000000000000000000000000";
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
sprintf (md5_string + (i * 2), "%02x", md5_sum [i]);
|
||||||
|
|
||||||
|
fprintf (dst, "original md5: %s\n", md5_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// This function displays the progress status on the title bar of the DOS //
|
||||||
|
// window that WavPack is running in. The "file_progress" argument is for //
|
||||||
|
// the current file only and ranges from 0 - 1; this function takes into //
|
||||||
|
// account the total number of files to generate a batch progress number. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void display_progress (double file_progress)
|
||||||
|
{
|
||||||
|
char title [40];
|
||||||
|
|
||||||
|
file_progress = (file_index + file_progress) / num_files;
|
||||||
|
sprintf (title, "%d%% (WvUnpack)", (int) ((file_progress * 100.0) + 0.5));
|
||||||
|
SetConsoleTitle (title);
|
||||||
|
}
|
Loading…
Reference in a new issue