/* * shn_reader.h * shorten_decoder * * Created by Alex Lagutin on Sun Jul 07 2002. * Copyright (c) 2002 Eckysoft All rights reserved. * */ /* xmms-shn - a shorten (.shn) plugin for XMMS * Copyright (C) 2000-2001 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,v 1.6 2001/12/30 05:12:04 jason Exp $ */ #ifndef __SHN_READER_H__ #define __SHN_READER_H__ #include #include #include "shorten.h" #include "ringbuffer.h" /* Derek */ typedef unsigned int uint; /* surely no headers will be this large. right? RIGHT? */ #define OUT_BUFFER_SIZE 16384 #define NUM_DEFAULT_BUFFER_BLOCKS 512L #define SEEK_HEADER_SIZE 12 #define SEEK_TRAILER_SIZE 12 #define SEEK_ENTRY_SIZE 80 #define MASKTABSIZE 33 typedef struct _shn_decode_state { uchar *getbuf; uchar *getbufp; int nbitget; int nbyteget; ulong gbuffer; char *writebuf; char *writefub; int nwritebuf; } shn_decode_state; typedef struct _shn_seek_header { uchar data[SEEK_HEADER_SIZE]; ulong 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; 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; ulong problems; } shn_wave_header; class shn_reader { private: shn_decode_state mDecodeState; shn_wave_header mWAVEHeader; shn_seek_header mSeekHeader; shn_seek_trailer mSeekTrailer; shn_seek_entry *mSeekTable; int mSeekTo; bool mEOF; bool mGoing; long mSeekTableEntries; int mBytesInBuf; uchar mBuffer[OUT_BUFFER_SIZE]; int mBytesInHeader; uchar mHeader[OUT_BUFFER_SIZE]; bool mFatalError; FILE *mFP; RingBuffer mRing; pthread_mutex_t mRingLock; pthread_cond_t mRunCond; pthread_t mThread; ulong masktab[MASKTABSIZE]; int sizeof_sample[TYPE_EOF]; public: shn_reader(); ~shn_reader(); int open(const char *fn, bool should_load_seek_table = true); int go(); void exit(); bool file_info(long *size, int *nch, float *rate, float *time, int *samplebits, bool *seekable); long read(void *buf, long size); float seek(float sec); int shn_get_buffer_block_size(int blocks);//derek unsigned int shn_get_song_length();//derek private: void init(); void Run(); int get_wave_header(); int verify_header(); void init_decode_state(); void write_and_wait(int block_size); /* fixio.cpp */ void init_sizeof_sample(); void fwrite_type_init(); void fwrite_type_quit(); void fix_bitshift(slong *buffer, int nitem, int bitshift, int ftype); void fwrite_type(slong **data,int ftype,int nchan,int nitem); /* vario.cpp */ void var_get_init(); ulong word_get(); long uvar_get(int nbin); ulong ulong_get(); long var_get(int nbin); void var_get_quit(); /* seek.cpp */ void load_seek_table(const char *fn); int load_separate_seek_table(const char *fn); shn_seek_entry *seek_entry_search(ulong goal, ulong min, ulong max); /* array.cpp */ void *pmalloc(ulong size); slong **long2d(ulong n0, ulong n1); friend void *thread_runner(shn_reader *reader) { reader->Run(); return NULL; } }; inline ulong 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]); } inline slong uchar_to_slong_le(uchar *buf) /* converts 4 bytes stored in little-endian format to an slong */ { return (long)uchar_to_ulong_le(buf); } inline ushort uchar_to_ushort_le(uchar *buf) /* converts 4 bytes stored in little-endian format to a ushort */ { return (ushort)((buf[1] << 8) + buf[0]); } #endif /*__SHN_READER_H__*/