285 lines
7.9 KiB
C
285 lines
7.9 KiB
C
/* 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: shn.h 19 2005-06-07 04:16:15Z vspader $
|
|
*/
|
|
|
|
#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
|