diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 8a870c2fb..ce1ad19ea 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 8E1296DA0A2BA9CE00443124 /* PlaylistHeaderView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */; }; 8E1296DB0A2BA9CE00443124 /* PlaylistHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */; }; 8E4C7F090A0509FC003BE25F /* DragScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E4C7F070A0509FC003BE25F /* DragScrollView.m */; }; + 8E4CAB5B0A32251B00214C1D /* ShnFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E4CAB5A0A32251B00214C1D /* ShnFile.mm */; }; 8E6A8E2C0A0D8A68002ABE9C /* CoreAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6A8E280A0D8A68002ABE9C /* CoreAudioFile.m */; }; 8E6A8E380A0D8AD8002ABE9C /* CoreAudioUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6A8E360A0D8AD8002ABE9C /* CoreAudioUtils.m */; }; 8E75756909F31D5A0080F1EE /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75751909F31D5A0080F1EE /* AppController.m */; }; @@ -39,7 +40,6 @@ 8E75757E09F31D5A0080F1EE /* FlacFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75754809F31D5A0080F1EE /* FlacFile.m */; }; 8E75757F09F31D5A0080F1EE /* MonkeysFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E75754A09F31D5A0080F1EE /* MonkeysFile.mm */; }; 8E75758109F31D5A0080F1EE /* MusepackFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75754E09F31D5A0080F1EE /* MusepackFile.m */; }; - 8E75758209F31D5A0080F1EE /* ShnFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75755009F31D5A0080F1EE /* ShnFile.m */; }; 8E75758309F31D5A0080F1EE /* SoundFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E75755209F31D5A0080F1EE /* SoundFile.mm */; }; 8E75758409F31D5A0080F1EE /* VorbisFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75755409F31D5A0080F1EE /* VorbisFile.m */; }; 8E75758609F31D5A0080F1EE /* WavPackFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75755809F31D5A0080F1EE /* WavPackFile.m */; }; @@ -84,14 +84,12 @@ 8E75774009F31F2A0080F1EE /* MAC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75773F09F31F2A0080F1EE /* MAC.framework */; }; 8E75774409F31F370080F1EE /* MPCDec.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75774309F31F370080F1EE /* MPCDec.framework */; }; 8E75774709F31F450080F1EE /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75774609F31F450080F1EE /* Ogg.framework */; }; - 8E75774B09F31F500080F1EE /* Shorten.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75774A09F31F500080F1EE /* Shorten.framework */; }; 8E75774E09F31F600080F1EE /* TagLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75774D09F31F600080F1EE /* TagLib.framework */; }; 8E75775109F31F6B0080F1EE /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75775009F31F6B0080F1EE /* Vorbis.framework */; }; 8E75775409F31F750080F1EE /* WavPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E75775309F31F750080F1EE /* WavPack.framework */; }; 8E757B4F09F326710080F1EE /* WavPack.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75775309F31F750080F1EE /* WavPack.framework */; }; 8E757B5009F326710080F1EE /* Vorbis.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75775009F31F6B0080F1EE /* Vorbis.framework */; }; 8E757B5109F326710080F1EE /* TagLib.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75774D09F31F600080F1EE /* TagLib.framework */; }; - 8E757B5209F326710080F1EE /* Shorten.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75774A09F31F500080F1EE /* Shorten.framework */; }; 8E757B5309F326710080F1EE /* Ogg.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75774609F31F450080F1EE /* Ogg.framework */; }; 8E757B5409F326710080F1EE /* MPCDec.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75774309F31F370080F1EE /* MPCDec.framework */; }; 8E757B5509F326710080F1EE /* MAC.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E75773F09F31F2A0080F1EE /* MAC.framework */; }; @@ -127,7 +125,6 @@ 8E757B4F09F326710080F1EE /* WavPack.framework in CopyFiles */, 8E757B5009F326710080F1EE /* Vorbis.framework in CopyFiles */, 8E757B5109F326710080F1EE /* TagLib.framework in CopyFiles */, - 8E757B5209F326710080F1EE /* Shorten.framework in CopyFiles */, 8E757B5309F326710080F1EE /* Ogg.framework in CopyFiles */, 8E757B5409F326710080F1EE /* MPCDec.framework in CopyFiles */, 8E757B5509F326710080F1EE /* MAC.framework in CopyFiles */, @@ -163,6 +160,7 @@ 8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PlaylistHeaderView.m; sourceTree = ""; }; 8E4C7F060A0509FC003BE25F /* DragScrollView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DragScrollView.h; sourceTree = ""; }; 8E4C7F070A0509FC003BE25F /* DragScrollView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DragScrollView.m; sourceTree = ""; }; + 8E4CAB5A0A32251B00214C1D /* ShnFile.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ShnFile.mm; sourceTree = ""; }; 8E643DF20A2B585600844A28 /* GameFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameFile.h; sourceTree = ""; }; 8E643DF30A2B585600844A28 /* GameFile.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GameFile.mm; sourceTree = ""; }; 8E6A8E270A0D8A68002ABE9C /* CoreAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CoreAudioFile.h; sourceTree = ""; }; @@ -221,7 +219,6 @@ 8E75754D09F31D5A0080F1EE /* MusepackFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MusepackFile.h; sourceTree = ""; }; 8E75754E09F31D5A0080F1EE /* MusepackFile.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackFile.m; sourceTree = ""; }; 8E75754F09F31D5A0080F1EE /* ShnFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShnFile.h; sourceTree = ""; }; - 8E75755009F31D5A0080F1EE /* ShnFile.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = ShnFile.m; sourceTree = ""; }; 8E75755109F31D5A0080F1EE /* SoundFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoundFile.h; sourceTree = ""; }; 8E75755209F31D5A0080F1EE /* SoundFile.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SoundFile.mm; sourceTree = ""; }; 8E75755309F31D5A0080F1EE /* VorbisFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VorbisFile.h; sourceTree = ""; }; @@ -280,7 +277,6 @@ 8E75773F09F31F2A0080F1EE /* MAC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MAC.framework; path = Libraries/MAC/build/Release/MAC.framework; sourceTree = ""; }; 8E75774309F31F370080F1EE /* MPCDec.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MPCDec.framework; path = Libraries/MPCDec/build/Release/MPCDec.framework; sourceTree = ""; }; 8E75774609F31F450080F1EE /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = Libraries/Ogg/build/Release/Ogg.framework; sourceTree = ""; }; - 8E75774A09F31F500080F1EE /* Shorten.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Shorten.framework; path = Libraries/Shorten/build/Release/Shorten.framework; sourceTree = ""; }; 8E75774D09F31F600080F1EE /* TagLib.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TagLib.framework; path = Libraries/TagLib/build/Release/TagLib.framework; sourceTree = ""; }; 8E75775009F31F6B0080F1EE /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = Libraries/Vorbis/build/Release/Vorbis.framework; sourceTree = ""; }; 8E75775309F31F750080F1EE /* WavPack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WavPack.framework; path = Libraries/WavPack/build/Release/WavPack.framework; sourceTree = ""; }; @@ -301,7 +297,6 @@ 8E75774009F31F2A0080F1EE /* MAC.framework in Frameworks */, 8E75774409F31F370080F1EE /* MPCDec.framework in Frameworks */, 8E75774709F31F450080F1EE /* Ogg.framework in Frameworks */, - 8E75774B09F31F500080F1EE /* Shorten.framework in Frameworks */, 8E75774E09F31F600080F1EE /* TagLib.framework in Frameworks */, 8E75775109F31F6B0080F1EE /* Vorbis.framework in Frameworks */, 8E75775409F31F750080F1EE /* WavPack.framework in Frameworks */, @@ -497,7 +492,7 @@ 8E75754D09F31D5A0080F1EE /* MusepackFile.h */, 8E75754E09F31D5A0080F1EE /* MusepackFile.m */, 8E75754F09F31D5A0080F1EE /* ShnFile.h */, - 8E75755009F31D5A0080F1EE /* ShnFile.m */, + 8E4CAB5A0A32251B00214C1D /* ShnFile.mm */, 8E75755109F31D5A0080F1EE /* SoundFile.h */, 8E75755209F31D5A0080F1EE /* SoundFile.mm */, 8E75755309F31D5A0080F1EE /* VorbisFile.h */, @@ -573,7 +568,6 @@ 8E75775309F31F750080F1EE /* WavPack.framework */, 8E75775009F31F6B0080F1EE /* Vorbis.framework */, 8E75774D09F31F600080F1EE /* TagLib.framework */, - 8E75774A09F31F500080F1EE /* Shorten.framework */, 8E75774609F31F450080F1EE /* Ogg.framework */, 8E75774309F31F370080F1EE /* MPCDec.framework */, 8E75773F09F31F2A0080F1EE /* MAC.framework */, @@ -704,7 +698,6 @@ 8E75757E09F31D5A0080F1EE /* FlacFile.m in Sources */, 8E75757F09F31D5A0080F1EE /* MonkeysFile.mm in Sources */, 8E75758109F31D5A0080F1EE /* MusepackFile.m in Sources */, - 8E75758209F31D5A0080F1EE /* ShnFile.m in Sources */, 8E75758309F31D5A0080F1EE /* SoundFile.mm in Sources */, 8E75758409F31D5A0080F1EE /* VorbisFile.m in Sources */, 8E75758609F31D5A0080F1EE /* WavPackFile.m in Sources */, @@ -717,6 +710,7 @@ 8E6A8E2C0A0D8A68002ABE9C /* CoreAudioFile.m in Sources */, 8E6A8E380A0D8AD8002ABE9C /* CoreAudioUtils.m in Sources */, 8E1296DB0A2BA9CE00443124 /* PlaylistHeaderView.m in Sources */, + 8E4CAB5B0A32251B00214C1D /* ShnFile.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Libraries/Shorten/Files/shorten/include/ringbuffer.h b/Libraries/Shorten/Files/shorten/include/ringbuffer.h new file mode 100755 index 000000000..7778f9cef --- /dev/null +++ b/Libraries/Shorten/Files/shorten/include/ringbuffer.h @@ -0,0 +1,77 @@ +/* + Millennium Sound System + ©1999, Subband Software + + Description: GP Ring Buffer + Released: 9/15/99 + + Version history: + + Date Who Changes + --------+---------+------------------------------------------------------ + 09-15-99 DAB Initial release. + + DAB = Dmitry Boldyrev +*/ + +/* + * 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. + */ + +#ifndef __RINGBUFFER_H__ +#define __RINGBUFFER_H__ + +class RingBuffer +{ + public: + RingBuffer(); + ~RingBuffer(); + + int Init(long inSize); + + long WriteData(char *data, long len); + long ReadData(char *data, long len); + + long FreeSpace(bool inTrueSpace = true); + long UsedSpace(bool inTrueSpace = true); + long BufSize() + { + return mBufSize; + } + + void Empty(); + + void SaveRead(); + void RestoreRead(); + + bool IsReadMode() + { + return mSaveFreeSpace == -1; + } + + protected: + + char* mBuffer; + long mBufSize; + long mBufWxIdx; + + long mBufRdIdx; + long mFreeSpace; + + long mSaveFreeSpace; + long mSaveReadPos; +}; + +#endif //__RINGBUFFER_H__ diff --git a/Libraries/Shorten/Files/shorten/include/shn_reader.h b/Libraries/Shorten/Files/shorten/include/shn_reader.h new file mode 100644 index 000000000..ce52b3416 --- /dev/null +++ b/Libraries/Shorten/Files/shorten/include/shn_reader.h @@ -0,0 +1,204 @@ +/* + * 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__*/ diff --git a/Libraries/Shorten/Files/shorten/include/shorten.h b/Libraries/Shorten/Files/shorten/include/shorten.h index a54f668f2..d9d4a6dc1 100644 --- a/Libraries/Shorten/Files/shorten/include/shorten.h +++ b/Libraries/Shorten/Files/shorten/include/shorten.h @@ -1,3 +1,12 @@ +/* + * shorten.h + * shorten_decoder + * + * Created by Alex Lagutin on Sun Jul 07 2002. + * Copyright (c) 2002 Eckysoft All rights reserved. + * + */ + /****************************************************************************** * * * Copyright (C) 1992-1995 Tony Robinson * @@ -7,7 +16,7 @@ ******************************************************************************/ /* - * $Id: shorten.h 19 2005-06-07 04:16:15Z vspader $ + * $Id: shorten.h,v 1.4 2001/12/30 05:12:04 jason Exp $ */ #ifndef _SHORTEN_H @@ -18,7 +27,6 @@ #endif #include -#include #ifdef HAVE_INTTYPES_H # include @@ -49,8 +57,6 @@ #define sshort int16_t #define schar int8_t -#include "shn.h" - #define MAGIC "ajkg" #define FORMAT_VERSION 2 #define MIN_SUPPORTED_VERSION 1 @@ -155,66 +161,7 @@ #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*); +#define UINT_GET(nbit) \ + ((version == 0) ? uvar_get(nbit) : ulong_get()) #endif diff --git a/Libraries/Shorten/Files/shorten/src/array.cpp b/Libraries/Shorten/Files/shorten/src/array.cpp new file mode 100644 index 000000000..83e0b129d --- /dev/null +++ b/Libraries/Shorten/Files/shorten/src/array.cpp @@ -0,0 +1,50 @@ +/* + * array.cpp + * shorten_decoder + * + * Created by Alex Lagutin on Tue Jul 09 2002. + * Copyright (c) 2002 Eckysoft All rights reserved. + * + */ + +/****************************************************************************** +* * +* Copyright (C) 1992-1995 Tony Robinson * +* * +* See the file doc/LICENSE.shorten for conditions on distribution and usage * +* * +******************************************************************************/ + +/* + * $Id: array.c,v 1.6 2001/12/30 05:12:04 jason Exp $ + */ + +#include +#include +#include "shn_reader.h" + +void *shn_reader::pmalloc(ulong size) { + void *ptr; + + ptr = malloc(size); + + if(ptr == NULL) + mFatalError = true; + + return(ptr); +} + +slong **shn_reader::long2d(ulong n0, ulong n1) { + slong **array0 = NULL; + + if((array0 = (slong**) pmalloc((ulong) (n0 * sizeof(slong*) + + n0 * n1 * sizeof(slong)))) != NULL ) { + slong *array1 = (slong*) (array0 + n0); + ulong i; + + for(i = 0; i < n0; i++) + array0[i] = array1 + i * n1; + } + return(array0); +} + diff --git a/Libraries/Shorten/Files/shorten/src/decode.c b/Libraries/Shorten/Files/shorten/src/decode.c index ea701f295..196f05e30 100644 --- a/Libraries/Shorten/Files/shorten/src/decode.c +++ b/Libraries/Shorten/Files/shorten/src/decode.c @@ -13,6 +13,12 @@ #define FALSE 0 #endif +/* Derek start */ +pthread_mutex_t mRingLock; +pthread_cond_t mRunCond; +pthread_t mThread; +/* Derek end */ + int shn_seek(shn_file *this_shn, unsigned int time); int shn_seekable(shn_file *this_shn); shn_file *shn_load(char *filename, shn_config config); diff --git a/Libraries/Shorten/Files/shorten/src/fixio.cpp b/Libraries/Shorten/Files/shorten/src/fixio.cpp new file mode 100644 index 000000000..e2751d1ac --- /dev/null +++ b/Libraries/Shorten/Files/shorten/src/fixio.cpp @@ -0,0 +1,302 @@ +/* + * fixio.cpp + * shorten_decoder + * + * Created by Alex Lagutin on Tue Jul 09 2002. + * Copyright (c) 2002 Eckysoft All rights reserved. + * + */ + +/****************************************************************************** +* * +* Copyright (C) 1992-1995 Tony Robinson * +* * +* See the file doc/LICENSE.shorten for conditions on distribution and usage * +* * +******************************************************************************/ + +/* + * $Id: fixio.c,v 1.6 2001/12/30 05:12:04 jason Exp $ + */ + +#include +#include "shn_reader.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) + +extern "C" +{ + int Sulaw2linear(uchar); + uchar Slinear2ulaw(int); + uchar Slinear2alaw(int); +} + +void shn_reader::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 shn_reader::fwrite_type_init() +{ + init_sizeof_sample(); + mDecodeState.writebuf = (char*) NULL; + mDecodeState.writefub = (char*) NULL; + mDecodeState.nwritebuf = 0; +} + +void shn_reader::fwrite_type_quit() { + if(mDecodeState.writebuf != NULL) { + free(mDecodeState.writebuf); + mDecodeState.writebuf = NULL; + } + if(mDecodeState.writefub != NULL) { + free(mDecodeState.writefub); + mDecodeState.writefub = NULL; + } +} + +/* convert from signed ints to a given type and write */ +void shn_reader::fwrite_type(slong **data,int ftype,int nchan,int nitem) +{ + int hiloint = 1, hilo = !(*((char*) &hiloint)); + int i, nwrite = 0, datasize = sizeof_sample[ftype], chan; + slong *data0 = data[0]; + int bufAvailable = OUT_BUFFER_SIZE - mBytesInBuf; + + if(mDecodeState.nwritebuf < nchan * nitem * datasize) { + mDecodeState.nwritebuf = nchan * nitem * datasize; + if(mDecodeState.writebuf != NULL) free(mDecodeState.writebuf); + if(mDecodeState.writefub != NULL) free(mDecodeState.writefub); + mDecodeState.writebuf = (char*) pmalloc((ulong) mDecodeState.nwritebuf); + if (!mDecodeState.writebuf) + return; + mDecodeState.writefub = (char*) pmalloc((ulong) mDecodeState.nwritebuf); + if (!mDecodeState.writefub) + return; + } + + switch(ftype) { + case TYPE_AU1: /* leave the conversion to fix_bitshift() */ + case TYPE_AU2: { + uchar *writebufp = (uchar*) mDecodeState.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*) mDecodeState.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*) mDecodeState.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*) mDecodeState.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*) mDecodeState.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*) mDecodeState.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*) mDecodeState.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*) mDecodeState.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 *)&mBuffer[mBytesInBuf],(const void *)mDecodeState.writebuf,datasize*nchan*nitem); + mBytesInBuf += datasize*nchan*nitem; + nwrite = nitem; + } + else + { + // fprintf(stderr, "Buffer overrun in fwrite_type() [case 1]: %d bytes to read, but only %d bytes are available\n",datasize*nchan*nitem,bufAvailable); + } + break; + case TYPE_S16HL: + case TYPE_U16HL: + if(hilo) + { + if (datasize*nchan*nitem <= bufAvailable) { + memcpy((void *)&mBuffer[mBytesInBuf],(const void *)mDecodeState.writebuf,datasize*nchan*nitem); + mBytesInBuf += datasize*nchan*nitem; + nwrite = nitem; + } + else + { + //fprintf(stderr, "Buffer overrun in fwrite_type() [case 2]: %d bytes to read, but only %d bytes are available\n",datasize*nchan*nitem,bufAvailable); + } + } + else + { + swab(mDecodeState.writebuf, mDecodeState.writefub, datasize * nchan * nitem); + if (datasize*nchan*nitem <= bufAvailable) { + memcpy((void *)&mBuffer[mBytesInBuf],(const void *)mDecodeState.writefub,datasize*nchan*nitem); + mBytesInBuf += datasize*nchan*nitem; + nwrite = nitem; + } + else + { + //fprintf(stderr, "Buffer overrun in fwrite_type() [case 3]: %d bytes to read, but only %d bytes are available\n",datasize*nchan*nitem,bufAvailable); + } + } + break; + case TYPE_S16LH: + case TYPE_U16LH: + if(hilo) + { + swab(mDecodeState.writebuf, mDecodeState.writefub, datasize * nchan * nitem); + if (datasize*nchan*nitem <= bufAvailable) { + memcpy((void *)&mBuffer[mBytesInBuf],(const void *)mDecodeState.writefub,datasize*nchan*nitem); + mBytesInBuf += datasize*nchan*nitem; + nwrite = nitem; + } + else + { + //fprintf(stderr, "Buffer overrun in fwrite_type() [case 4]: %d bytes to read, but only %d bytes are available\n",datasize*nchan*nitem,bufAvailable); + } + } + else + { + if (datasize*nchan*nitem <= bufAvailable) { + memcpy((void *)&mBuffer[mBytesInBuf],(const void *)mDecodeState.writebuf,datasize*nchan*nitem); + mBytesInBuf += datasize*nchan*nitem; + nwrite = nitem; + } + else + { + //fprintf(stderr, "Buffer overrun in fwrite_type() [case 5]: %d bytes to read, but only %d bytes are available\n",datasize*nchan*nitem,bufAvailable); + } + } + break; + } + + if(nwrite != nitem) + { + mFatalError = true; + //fprintf(stderr,"Failed to write decompressed stream -\npossible corrupt or truncated file\n"); + } +} + +/*************/ +/* bitshifts */ +/*************/ + +void shn_reader::fix_bitshift(slong *buffer, int nitem, int bitshift, int 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; +} diff --git a/Libraries/Shorten/Files/shorten/src/ringbuffer.cpp b/Libraries/Shorten/Files/shorten/src/ringbuffer.cpp new file mode 100755 index 000000000..09cb0fdb1 --- /dev/null +++ b/Libraries/Shorten/Files/shorten/src/ringbuffer.cpp @@ -0,0 +1,197 @@ +/* + Millennium Sound System + ©1999-2000 Subband Software, Inc. + + Description: GP Ring Buffer class + Released: 9/15/99 + + Version history: + + Date Who Changes + --------+---------+------------------------------------------------------ + 06-19-00 AVL parameter types changes, conflicting function names fixed, + IsFreeSpace() changed to IsReadMode(), ReadDataCR() removed. + 09-15-99 DAB Initial release. + + DAB = Dmitry Boldyrev + AVL = Alex Lagutin +*/ +/* + * 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. + */ + +#include +#include "ringbuffer.h" + +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +RingBuffer::RingBuffer() +{ + mFreeSpace=0; + mBuffer=NULL; + + mBufSize=0; + mBufRdIdx=0; + mBufWxIdx=0; + + mSaveFreeSpace=-1; +} + +int RingBuffer::Init(long inSize) +{ + mBufSize=inSize; + if (mBuffer) { + delete[] mBuffer; + } + if ((mBuffer = new char[mBufSize]) == NULL) + return -1; + + Empty(); + + return 0; +} + +void +RingBuffer::Empty() +{ + mBufRdIdx=0; + mBufWxIdx=0; + mFreeSpace=mBufSize; + mSaveFreeSpace=-1; + +// if (mBuffer) { +// memset(mBuffer, 0, mBufSize); +// } +} + +RingBuffer::~RingBuffer() +{ + if (mBuffer) { + delete[] mBuffer; + } + mBuffer=NULL; +} + + +long RingBuffer::WriteData(char *data, long len) +{ + int written, before; + + if (!mBufSize || data==NULL || !mBuffer) + return 0; + + written=0; + if (!(len = MIN(FreeSpace(false), len))) + return 0; + + while (1) + { + if (len + mBufWxIdx < mBufSize) + { + ::memcpy(&mBuffer[mBufWxIdx], &data[written], (size_t) len); + mBufWxIdx += len; + written += len; + mFreeSpace -= len; + if (mSaveFreeSpace != -1) + mSaveFreeSpace -= len; + + return written; + } else + { + before = mBufSize - mBufWxIdx; + ::memcpy(&mBuffer[mBufWxIdx], &data[written], (size_t) before); + written += before; + len -= before; + mFreeSpace -= before; + if (mSaveFreeSpace != -1) + mSaveFreeSpace -= before; + + mBufWxIdx = 0; + } + } +} + +void RingBuffer::SaveRead() +{ + if (mSaveFreeSpace!=-1) + return; + mSaveReadPos=mBufRdIdx; + mSaveFreeSpace=mFreeSpace; +} + +void RingBuffer::RestoreRead() +{ + if (mSaveFreeSpace==-1) + return; + mBufRdIdx=mSaveReadPos; + mFreeSpace=mSaveFreeSpace; + mSaveFreeSpace=-1; +} + +long RingBuffer::ReadData(char *data, long len) +{ + int read, before; + + if (!mBufSize) return 0; + + read = 0; + if (!(len = MIN(UsedSpace(true), len))) + return 0; + + while (1) + { + if (len + mBufRdIdx < mBufSize) + { + if (data) { + ::memcpy(&data[read], &mBuffer[mBufRdIdx], (size_t) len); + } + mBufRdIdx += len; + read += len; + mFreeSpace += len; + + return read; + } else + { + before = mBufSize - mBufRdIdx; + if (data) { + ::memcpy(&data[read], &mBuffer[mBufRdIdx], (size_t) before); + } + read += before; + len -= before; + mFreeSpace += before; + + mBufRdIdx = 0; + } + } +} + +long RingBuffer::FreeSpace(bool inTrueSpace) +{ + if (inTrueSpace) + return mFreeSpace; + else + return (mSaveFreeSpace==-1) ? mFreeSpace : mSaveFreeSpace; +} + +long RingBuffer::UsedSpace(bool inTrueSpace) +{ + if (inTrueSpace) + return (mBufSize - mFreeSpace); + else + return (mSaveFreeSpace==-1) ? (mBufSize - mFreeSpace) : + (mBufSize - mSaveFreeSpace); +} diff --git a/Libraries/Shorten/Files/shorten/src/seek.cpp b/Libraries/Shorten/Files/shorten/src/seek.cpp new file mode 100644 index 000000000..5d76e2c38 --- /dev/null +++ b/Libraries/Shorten/Files/shorten/src/seek.cpp @@ -0,0 +1,157 @@ +/* + * seek.cpp + * shorten_decoder + * + * Created by Alex Lagutin on Tue Jul 09 2002. + * Copyright (c) 2002 Eckysoft All rights reserved. + * + */ + +/* seek.c - functions related to real-time seeking + * 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: seek.c,v 1.4 2001/12/30 05:12:04 jason Exp $ + */ + +#include +#include "shn_reader.h" + +#define SEEK_HEADER_SIGNATURE "SEEK" +#define SEEK_TRAILER_SIGNATURE "SHNAMPSK" +#define SEEK_SUFFIX ".skt" + +shn_seek_entry *shn_reader::seek_entry_search(ulong goal, ulong min, ulong max) +{ + ulong med = (min + max) / 2; + shn_seek_entry *middle = &mSeekTable[med]; + ulong sample = uchar_to_ulong_le(middle->data); + + if (goal < sample) + return seek_entry_search(goal, min, med-1); + if (goal > sample + 25600) + return seek_entry_search(goal, med+1, max); + + return middle; +} + +void shn_reader::load_seek_table(const char *fn) +{ + FILE *fp; + int found = 0; + + if (!(fp = fopen(fn, "r"))) + return; + + fseek(fp, -SEEK_TRAILER_SIZE, SEEK_END); + if (fread(mSeekTrailer.data, 1, SEEK_TRAILER_SIZE, fp) == SEEK_TRAILER_SIZE) + { + mSeekTrailer.seekTableSize = uchar_to_ulong_le(mSeekTrailer.data); + if (!memcmp(&mSeekTrailer.data[4], SEEK_TRAILER_SIGNATURE, strlen(SEEK_TRAILER_SIGNATURE))) + { + fseek(fp, -mSeekTrailer.seekTableSize, SEEK_END); + mSeekTrailer.seekTableSize -= (SEEK_HEADER_SIZE + SEEK_TRAILER_SIZE); + if (fread(mSeekHeader.data, 1, SEEK_HEADER_SIZE, fp) == SEEK_HEADER_SIZE) + { + long entries = mSeekTrailer.seekTableSize/sizeof(shn_seek_entry); + + if ((mSeekTable = (shn_seek_entry *) malloc(sizeof(shn_seek_entry)*entries))) + { + if ((long)fread(mSeekTable, sizeof(shn_seek_entry), entries, fp) == entries) + { + //fprintf(stderr, "Successfully loaded seek table appended to file: '%s'\n", fn); + mSeekTableEntries = entries; + found = 1; + } + else + { + free(mSeekTable); + mSeekTable = NULL; + } + } + } + } + } + fclose(fp); + + if (found) + return; + + { + // try load from separate seek file + char *slash, *ext; + char seek_fn[MAX_PATH]; + + strcpy(seek_fn, fn); + slash = strrchr(seek_fn, '/'); + ext = strrchr((slash ? slash : seek_fn), '.'); + if (ext) + *ext = 0; + strcat(seek_fn, SEEK_SUFFIX); + load_separate_seek_table(seek_fn); + } +} + +int shn_reader::load_separate_seek_table(const char *fn) +{ + FILE *fp; + long seek_table_len, entries; + int result = 0; + + //fprintf(stderr, "Looking for seek table in separate file: '%s'\n", fn); + + if (!(fp = fopen(fn, "r"))) + return 0; + + fseek(fp, 0, SEEK_END); + seek_table_len = (long)ftell(fp) - SEEK_HEADER_SIZE; + entries = seek_table_len/sizeof(shn_seek_entry); + fseek(fp, 0, SEEK_SET); + + if (fread(mSeekHeader.data, 1, SEEK_HEADER_SIZE, fp) == SEEK_HEADER_SIZE) + { + mSeekHeader.version = uchar_to_ulong_le(&mSeekHeader.data[4]); + mSeekHeader.shnFileSize = uchar_to_ulong_le(&mSeekHeader.data[8]); + if (!memcmp(mSeekHeader.data, SEEK_HEADER_SIGNATURE, strlen(SEEK_HEADER_SIGNATURE))) + { + if (mSeekHeader.shnFileSize == mWAVEHeader.actual_size) + { + if ((mSeekTable = (shn_seek_entry *) malloc(sizeof(shn_seek_entry)*entries))) + { + if ((long)fread(mSeekTable, sizeof(shn_seek_entry), entries, fp) == entries) + { + //fprintf(stderr, "Successfully loaded seek table in separate file: '%s'\n", fn); + mSeekTableEntries = entries; + } + else + { + free(mSeekTable); + mSeekTable = NULL; + } + } + } + else + { + //fprintf(stderr, "Seek table .shn file size and actual .shn file size differ\n"); + } + } + } + + fclose(fp); + return result; +} diff --git a/Libraries/Shorten/Files/shorten/src/shn_reader.cpp b/Libraries/Shorten/Files/shorten/src/shn_reader.cpp new file mode 100644 index 000000000..42818c6d7 --- /dev/null +++ b/Libraries/Shorten/Files/shorten/src/shn_reader.cpp @@ -0,0 +1,979 @@ +/* + * shn_reader.cpp + * shorten_decoder + * + * Created by Alex Lagutin on Sun Jul 07 2002. + * Copyright (c) 2002 Eckysoft All rights reserved. + * + */ + +/* shn.c - main functions for xmms-shn + * 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.c,v 1.9 2001/12/30 05:12:04 jason Exp $ + */ + +#include +#include +#include +#include +#include "shn_reader.h" + +#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 WAVE_FORMAT_PCM (0x0001) +#define CANONICAL_HEADER_SIZE (44) + +#define CACHE_SIZE (256*1024) //256K + +static 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\n", ftype); + break; + } + + for(chan = 0; chan < nchan; chan++) + for(i = 0; i < nblock; i++) + offset[chan][i] = mean; +} + +shn_reader::shn_reader() +{ + init(); + pthread_mutex_init(&mRingLock, NULL); + pthread_cond_init(&mRunCond, NULL); +} + +shn_reader::~shn_reader() +{ + exit(); + pthread_mutex_destroy(&mRingLock); + pthread_cond_destroy(&mRunCond); +} + +void shn_reader::init() +{ + mSeekTable = NULL; + mSeekTo = -1; + mFP = NULL; + mFatalError = false; + mGoing = false; + mEOF = false; + memset(&mDecodeState, 0, sizeof(mDecodeState)); + memset(&mWAVEHeader, 0, sizeof(mWAVEHeader)); + mRing.Init(CACHE_SIZE); +} + +void shn_reader::exit() +{ + if (mGoing) + { + mGoing = false; + pthread_cond_signal(&mRunCond); + pthread_join(mThread, NULL); + } + + if (mDecodeState.getbuf) + { + free(mDecodeState.getbuf); + mDecodeState.getbuf = NULL; + } + if (mDecodeState.writebuf) + { + free(mDecodeState.writebuf); + mDecodeState.writebuf = NULL; + } + if (mDecodeState.writefub) + { + free(mDecodeState.writefub); + mDecodeState.writefub = NULL; + } + if (mSeekTable) + { + free(mSeekTable); + mSeekTable = NULL; + } + if (mFP) + { + fclose(mFP); + mFP = NULL; + } +} + +int shn_reader::open(const char *fn, bool should_load_seek_table) +{ + struct stat sz; + + exit(); + init(); + + if (stat(fn, &sz)) + return -1; + + if (!S_ISREG(sz.st_mode)) + return -1; + + mWAVEHeader.actual_size = (ulong)sz.st_size; + + mFP = fopen(fn, "r"); + + if (!mFP) + return -1; + + if (!get_wave_header() || !verify_header()) + { + fclose(mFP); + mFP = NULL; + return -1; + } + + if (should_load_seek_table) + load_seek_table(fn); + + return 0; +} + +int shn_reader::go() +{ + if (!mFP) + return -1; + + fseek(mFP, 0, SEEK_SET); + mGoing = true; + + if (pthread_create(&mThread, NULL, (void *(*)(void *))thread_runner, this)) + { + mGoing = false; + return -1; + } + return 0; +} + +long shn_reader::read(void *buf, long size) +{ + long actread; + + if (!mGoing) + return -2; + + pthread_mutex_lock(&mRingLock); + actread = mRing.ReadData((char *) buf, size); + if (!actread) + actread = mEOF ? -2 : -1; + + pthread_mutex_unlock(&mRingLock); + if (actread > 0) + pthread_cond_signal(&mRunCond); + + return actread; +} + +float shn_reader::seek(float seconds) +{ + if (!mSeekTable) + return -1.0f; + + mSeekTo = (int) seconds; + shn_seek_entry *seek_info = seek_entry_search(mSeekTo * (ulong)mWAVEHeader.samples_per_sec,0, + (ulong)(mSeekTableEntries - 1)); + ulong sample = uchar_to_ulong_le(seek_info->data); + return (float)sample/((float)mWAVEHeader.samples_per_sec); +} + +int shn_reader::shn_get_buffer_block_size(int blocks)//derek +{ + int blk_size = blocks * (mWAVEHeader.bits_per_sample / 8) * mWAVEHeader.channels; + if(blk_size > OUT_BUFFER_SIZE) + { + blk_size = NUM_DEFAULT_BUFFER_BLOCKS * (mWAVEHeader.bits_per_sample / 8) * mWAVEHeader.channels; + } + + return blk_size; +} + +unsigned int shn_reader::shn_get_song_length()//derek +{ + if(mWAVEHeader.length > 0) + return (unsigned int)(1000 * mWAVEHeader.length); + + /* Something failed or just isn't correct */ + return (unsigned int)0; +} + +bool shn_reader::file_info(long *size, int *nch, float *rate, float *time, + int *samplebits, bool *seekable) +{ + float frate; + int frame_size; + + if (!mFP) + return false; + + if (seekable) + *seekable = mSeekTable ? true : false; + + if (size) + *size = mWAVEHeader.actual_size; + + if (nch) + *nch = mWAVEHeader.channels; + + frame_size = (uint)mWAVEHeader.channels * (uint)mWAVEHeader.bits_per_sample / 8; + frate = (float)mWAVEHeader.samples_per_sec; + + if (rate) + *rate = frate; + + if (time) + *time = (float)mWAVEHeader.data_size/((float)frame_size * frate); + + if (samplebits) + *samplebits = mWAVEHeader.bits_per_sample; + + return true; +} + +void shn_reader::init_decode_state() +{ + if (mDecodeState.getbuf) + free(mDecodeState.getbuf); + + if (mDecodeState.writebuf) + free(mDecodeState.writebuf); + + if (mDecodeState.writefub) + free(mDecodeState.writefub); + + memset(&mDecodeState, 0, sizeof(mDecodeState)); +} + +int shn_reader::get_wave_header() +{ + int version = FORMAT_VERSION; + int ftype = TYPE_EOF; + char *magic = MAGIC; + int internal_ftype; + int retval = 1; + + init_decode_state(); + mBytesInHeader = 0; + /***********************/ + /* EXTRACT starts here */ + /***********************/ + + /* read magic number */ +#ifdef STRICT_FORMAT_COMPATABILITY + if(FORMAT_VERSION < 2) + { + for(int i = 0; i < strlen(magic); i++) + if(getc(mFP) != magic[i]) + return 0; + + /* get version number */ + version = getc(mFP); + if (version == EOF) + return 0; + } + else +#endif /* STRICT_FORMAT_COMPATABILITY */ + { + int nscan = 0; + + version = MAX_VERSION + 1; + while(version > MAX_VERSION) + { + int byte = getc(mFP); + if(byte == EOF) + return 0; + if(magic[nscan] != '\0' && byte == magic[nscan]) + nscan++; + else + if(magic[nscan] == '\0' && byte <= MAX_VERSION) + version = byte; + else + { + if(byte == magic[0]) + nscan = 1; + else + { + nscan = 0; + } + version = MAX_VERSION + 1; + } + } + } + + /* check version number */ + if(version > MAX_SUPPORTED_VERSION) + return 0; + + /* initialise the variable length file read for the compressed stream */ + var_get_init(); + if (mFatalError) + return 0; + + /* get the internal file type */ + internal_ftype = UINT_GET(TYPESIZE); + + /* has the user requested a change in file type? */ + if(internal_ftype != ftype) { + if(ftype == TYPE_EOF) + ftype = internal_ftype; /* no problems here */ + else /* check that the requested conversion is valid */ + if(internal_ftype == TYPE_AU1 || internal_ftype == TYPE_AU2 || + internal_ftype == TYPE_AU3 || ftype == TYPE_AU1 ||ftype == TYPE_AU2 || ftype == TYPE_AU3) + goto got_enough_data; + } + + UINT_GET(CHANSIZE); + + /* get blocksize if version > 0 */ + if(version > 0) + { + int byte, nskip; + UINT_GET((int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2)); + UINT_GET(LPCQSIZE); + UINT_GET(0); + nskip = UINT_GET(NSKIPSIZE); + for(int i = 0; i < nskip; i++) + { + byte = uvar_get(XBYTESIZE); + } + } + + /* find verbatim command */ + while(1) + { + int cmd = uvar_get(FNSIZE); + switch(cmd) + { + case FN_VERBATIM: + { + int cklen = uvar_get(VERBATIM_CKSIZE_SIZE); + + while (cklen--) + { + if (mBytesInHeader >= OUT_BUFFER_SIZE) + { + retval = 0; + goto got_enough_data; + } + mBytesInBuf = 0; + mHeader[mBytesInHeader++] = (unsigned char)uvar_get(VERBATIM_BYTE_SIZE); + } + } + break; + + default: + goto got_enough_data; + } + } + +got_enough_data: + + /* wind up */ + var_get_quit(); + + mBytesInBuf = 0; + + return retval; +} + +int shn_reader::verify_header() +{ + ulong l; + int cur = 0; + + if (mBytesInHeader < CANONICAL_HEADER_SIZE) + return 0; + + if (WAVE_RIFF != uchar_to_ulong_le(&mHeader[cur])) + return 0; + cur += 4; + + mWAVEHeader.chunk_size = uchar_to_ulong_le(&mHeader[cur]); + cur += 4; + + if (WAVE_WAVE != uchar_to_ulong_le(&mHeader[cur])) + return 0; + cur += 4; + + for (;;) + { + cur += 4; + + l = uchar_to_ulong_le(&mHeader[cur]); + cur += 4; + + if (WAVE_FMT == uchar_to_ulong_le(&mHeader[cur-8])) + break; + + cur += l; + } + + if (l < 16) + return 0; + + mWAVEHeader.wave_format = uchar_to_ushort_le(&mHeader[cur]); + cur += 2; + + switch (mWAVEHeader.wave_format) + { + case WAVE_FORMAT_PCM: + break; + + default: + return 0; + } + + mWAVEHeader.channels = uchar_to_ushort_le(&mHeader[cur]); + cur += 2; + mWAVEHeader.samples_per_sec = uchar_to_ulong_le(&mHeader[cur]); + cur += 4; + mWAVEHeader.avg_bytes_per_sec = uchar_to_ulong_le(&mHeader[cur]); + cur += 4; + mWAVEHeader.block_align = uchar_to_ushort_le(&mHeader[cur]); + cur += 2; + mWAVEHeader.bits_per_sample = uchar_to_ushort_le(&mHeader[cur]); + cur += 2; + + if (mWAVEHeader.bits_per_sample != 8 && mWAVEHeader.bits_per_sample != 16) + return 0; + + l -= 16; + + if (l > 0) + cur += l; + + for (;;) + { + cur += 4; + + l = uchar_to_ulong_le(&mHeader[cur]); + cur += 4; + + if (WAVE_DATA == uchar_to_ulong_le(&mHeader[cur-8])) + break; + + cur += l; + } + + mWAVEHeader.rate = ((uint)mWAVEHeader.samples_per_sec * + (uint)mWAVEHeader.channels * + (uint)mWAVEHeader.bits_per_sample) / 8; + mWAVEHeader.header_size = cur; + mWAVEHeader.data_size = l; + mWAVEHeader.total_size = mWAVEHeader.chunk_size + 8; + mWAVEHeader.length = mWAVEHeader.data_size / mWAVEHeader.rate; + + /* header looks ok */ + return 1; +} + +void shn_reader::write_and_wait(int block_size) +{ + int bytes_to_write; + + if (mBytesInBuf < block_size) + return; + + bytes_to_write = MIN(mBytesInBuf, block_size); + + if (bytes_to_write <= 0) + return; + + while (mGoing && mSeekTo == -1) + { + long written; + + pthread_mutex_lock(&mRingLock); + written = mRing.WriteData((char *) mBuffer, bytes_to_write); + bytes_to_write -= written; + mBytesInBuf -= written; + if (!bytes_to_write) + { + pthread_mutex_unlock(&mRingLock); + break; + } + pthread_cond_wait(&mRunCond, &mRingLock); + pthread_mutex_unlock(&mRingLock); + } +} + +void shn_reader::Run() +{ + slong **buffer = NULL, **offset = NULL; + slong lpcqoffset = 0; + int version = FORMAT_VERSION, bitshift = 0; + int ftype = TYPE_EOF; + char *magic = MAGIC; + int blocksize = DEFAULT_BLOCK_SIZE, nchan = DEFAULT_NCHAN; + int i, chan, nwrap, nskip = DEFAULT_NSKIP; + int *qlpc = NULL, maxnlpc = DEFAULT_MAXNLPC, nmean = UNDEFINED_UINT; + int cmd; + int internal_ftype; + int blk_size; + int cklen; + uchar tmp; + +restart: + + mBytesInBuf = 0; + + init_decode_state(); + + blk_size = 512 * (mWAVEHeader.bits_per_sample / 8) * mWAVEHeader.channels; + + /***********************/ + /* EXTRACT starts here */ + /***********************/ + + /* read magic number */ +#ifdef STRICT_FORMAT_COMPATABILITY + if(FORMAT_VERSION < 2) + { + for(i = 0; i < strlen(magic); i++) + if(getc(this_shn->vars.fd) != magic[i]) + { + mFatalError = true; + goto exit_thread; + } + + /* get version number */ + version = getc(this_shn->vars.fd); + if (version == EOF) + { + mFatalError = true; + goto exit_thread; + } + } + else +#endif /* STRICT_FORMAT_COMPATABILITY */ + { + int nscan = 0; + + version = MAX_VERSION + 1; + while(version > MAX_VERSION) + { + int byte = getc(mFP); + if(byte == EOF) { + mFatalError = true; + goto exit_thread; + } + if(magic[nscan] != '\0' && byte == magic[nscan]) + nscan++; + else + if(magic[nscan] == '\0' && byte <= MAX_VERSION) + version = byte; + else + { + if(byte == magic[0]) + nscan = 1; + else + { + nscan = 0; + } + version = MAX_VERSION + 1; + } + } + } + + /* check version number */ + if(version > MAX_SUPPORTED_VERSION) { + mFatalError = true; + goto exit_thread; + } + + /* set up the default nmean, ignoring the command line state */ + nmean = (version < 2) ? DEFAULT_V0NMEAN : DEFAULT_V2NMEAN; + + /* initialise the variable length file read for the compressed stream */ + var_get_init(); + if (mFatalError) + goto exit_thread; + + /* initialise the fixed length file write for the uncompressed stream */ + fwrite_type_init(); + + /* get the internal file type */ + internal_ftype = UINT_GET(TYPESIZE); + + /* has the user requested a change in file type? */ + if(internal_ftype != ftype) { + if(ftype == TYPE_EOF) + ftype = internal_ftype; /* no problems here */ + else /* check that the requested conversion is valid */ + if(internal_ftype == TYPE_AU1 || internal_ftype == TYPE_AU2 || + internal_ftype == TYPE_AU3 || ftype == TYPE_AU1 ||ftype == TYPE_AU2 || ftype == TYPE_AU3) { + mFatalError = true; + goto cleanup; + } + } + + nchan = UINT_GET(CHANSIZE); + + /* get blocksize if version > 0 */ + if(version > 0) + { + int byte; + blocksize = UINT_GET((int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2)); + maxnlpc = UINT_GET(LPCQSIZE); + nmean = UINT_GET(0); + nskip = UINT_GET(NSKIPSIZE); + for(i = 0; i < nskip; i++) + { + byte = uvar_get(XBYTESIZE); + } + } + else + blocksize = DEFAULT_BLOCK_SIZE; + + nwrap = MAX(NWRAP, maxnlpc); + + /* grab some space for the input buffer */ + buffer = long2d((ulong) nchan, (ulong) (blocksize + nwrap)); + if (mFatalError) + goto exit_thread; + offset = long2d((ulong) nchan, (ulong) MAX(1, nmean)); + if (mFatalError) { + if (buffer) { + free(buffer); + buffer = NULL; + } + goto exit_thread; + } + + for(chan = 0; chan < nchan; chan++) + { + for(i = 0; i < nwrap; i++) + buffer[chan][i] = 0; + buffer[chan] += nwrap; + } + + if(maxnlpc > 0) { + qlpc = (int*) pmalloc((ulong) (maxnlpc * sizeof(*qlpc))); + if (mFatalError) { + if (buffer) { + free(buffer); + buffer = NULL; + } + if (offset) { + free(offset); + buffer = NULL; + } + goto exit_thread; + } + } + + if(version > 1) + lpcqoffset = V2LPCQOFFSET; + + init_offset(offset, nchan, MAX(1, nmean), internal_ftype); + + /* get commands from file and execute them */ + chan = 0; + while(1) + { + cmd = uvar_get(FNSIZE); + if (mFatalError) + goto cleanup; + + switch(cmd) + { + case FN_ZERO: + case FN_DIFF0: + case FN_DIFF1: + case FN_DIFF2: + case FN_DIFF3: + case FN_QLPC: + { + slong coffset, *cbuffer = buffer[chan]; + int resn = 0, nlpc, j; + + if(cmd != FN_ZERO) + { + resn = uvar_get(ENERGYSIZE); + if (mFatalError) + goto cleanup; + /* this is a hack as version 0 differed in definition of var_get */ + if(version == 0) + resn--; + } + + /* find mean offset : N.B. this code duplicated */ + if(nmean == 0) + coffset = offset[chan][0]; + else + { + slong sum = (version < 2) ? 0 : nmean / 2; + for(i = 0; i < nmean; i++) + sum += offset[chan][i]; + if(version < 2) + coffset = sum / nmean; + else + coffset = ROUNDEDSHIFTDOWN(sum / nmean, bitshift); + } + + switch(cmd) + { + case FN_ZERO: + for(i = 0; i < blocksize; i++) + cbuffer[i] = 0; + break; + case FN_DIFF0: + for(i = 0; i < blocksize; i++) { + cbuffer[i] = var_get(resn) + coffset; + if (mFatalError) + goto cleanup; + } + break; + case FN_DIFF1: + for(i = 0; i < blocksize; i++) { + cbuffer[i] = var_get(resn) + cbuffer[i - 1]; + if (mFatalError) + goto cleanup; + } + break; + case FN_DIFF2: + for(i = 0; i < blocksize; i++) { + cbuffer[i] = var_get(resn) + (2 * cbuffer[i - 1] - cbuffer[i - 2]); + if (mFatalError) + goto cleanup; + } + break; + case FN_DIFF3: + for(i = 0; i < blocksize; i++) { + cbuffer[i] = var_get(resn) + 3 * (cbuffer[i - 1] - cbuffer[i - 2]) + cbuffer[i - 3]; + if (mFatalError) + goto cleanup; + } + break; + case FN_QLPC: + nlpc = uvar_get(LPCQSIZE); + if (mFatalError) + goto cleanup; + + for(i = 0; i < nlpc; i++) { + qlpc[i] = var_get(LPCQUANT); + if (mFatalError) + goto cleanup; + } + for(i = 0; i < nlpc; i++) + cbuffer[i - nlpc] -= coffset; + for(i = 0; i < blocksize; i++) + { + slong sum = lpcqoffset; + + for(j = 0; j < nlpc; j++) + sum += qlpc[j] * cbuffer[i - j - 1]; + cbuffer[i] = var_get(resn) + (sum >> LPCQUANT); + if (mFatalError) + goto cleanup; + } + if(coffset != 0) + for(i = 0; i < blocksize; i++) + cbuffer[i] += coffset; + break; + } + + /* store mean value if appropriate : N.B. Duplicated code */ + if(nmean > 0) + { + slong sum = (version < 2) ? 0 : blocksize / 2; + + for(i = 0; i < blocksize; i++) + sum += cbuffer[i]; + + for(i = 1; i < nmean; i++) + offset[chan][i - 1] = offset[chan][i]; + if(version < 2) + offset[chan][nmean - 1] = sum / blocksize; + else + offset[chan][nmean - 1] = (sum / blocksize) << bitshift; + } + + /* do the wrap */ + for(i = -nwrap; i < 0; i++) + cbuffer[i] = cbuffer[i + blocksize]; + + fix_bitshift(cbuffer, blocksize, bitshift, internal_ftype); + + if(chan == nchan - 1) + { + if (!mGoing || mFatalError) + goto cleanup; + + fwrite_type(buffer, ftype, nchan, blocksize); + + write_and_wait(blk_size); + + if (mSeekTo != -1) + { + shn_seek_entry *seek_info = seek_entry_search(mSeekTo * (ulong)mWAVEHeader.samples_per_sec,0, + (ulong)(mSeekTableEntries - 1)); + + pthread_mutex_lock(&mRingLock); + mRing.Empty(); + pthread_mutex_unlock(&mRingLock); + + buffer[0][-1] = uchar_to_slong_le(seek_info->data+24); + buffer[0][-2] = uchar_to_slong_le(seek_info->data+28); + buffer[0][-3] = uchar_to_slong_le(seek_info->data+32); + offset[0][0] = uchar_to_slong_le(seek_info->data+48); + offset[0][1] = uchar_to_slong_le(seek_info->data+52); + offset[0][2] = uchar_to_slong_le(seek_info->data+56); + offset[0][3] = uchar_to_slong_le(seek_info->data+60); + if (nchan > 1) + { + buffer[1][-1] = uchar_to_slong_le(seek_info->data+36); + buffer[1][-2] = uchar_to_slong_le(seek_info->data+40); + buffer[1][-3] = uchar_to_slong_le(seek_info->data+44); + offset[1][0] = uchar_to_slong_le(seek_info->data+64); + offset[1][1] = uchar_to_slong_le(seek_info->data+68); + offset[1][2] = uchar_to_slong_le(seek_info->data+72); + offset[1][3] = uchar_to_slong_le(seek_info->data+76); + } + bitshift = uchar_to_ushort_le(seek_info->data+22); + fseek(mFP,(slong)uchar_to_ulong_le(seek_info->data+8),SEEK_SET); + fread((uchar*) mDecodeState.getbuf, 1, BUFSIZ, mFP); + mDecodeState.getbufp = mDecodeState.getbuf + uchar_to_ushort_le(seek_info->data+14); + mDecodeState.nbitget = uchar_to_ushort_le(seek_info->data+16); + mDecodeState.nbyteget = uchar_to_ushort_le(seek_info->data+12); + mDecodeState.gbuffer = uchar_to_ulong_le(seek_info->data+18); + + mBytesInBuf = 0; + + + mSeekTo = -1; + } + + } + chan = (chan + 1) % nchan; + break; + } + + break; + + case FN_QUIT: + /* empty out last of buffer */ + write_and_wait(mBytesInBuf); + + mEOF = true; + + while (1) + { + if (!mGoing) + goto finish; + if (mSeekTo != -1) + { + var_get_quit(); + fwrite_type_quit(); + + if (buffer) free((void *) buffer); + if (offset) free((void *) offset); + if(maxnlpc > 0 && qlpc) + free((void *) qlpc); + + fseek(mFP,0,SEEK_SET); + goto restart; + } + } + + goto cleanup; + break; + + case FN_BLOCKSIZE: + blocksize = UINT_GET((int) (log((double) blocksize) / M_LN2)); + if (mFatalError) + goto cleanup; + break; + case FN_BITSHIFT: + bitshift = uvar_get(BITSHIFTSIZE); + if (mFatalError) + goto cleanup; + break; + case FN_VERBATIM: + cklen = uvar_get(VERBATIM_CKSIZE_SIZE); + if (mFatalError) + goto cleanup; + + while (cklen--) { + tmp = (uchar)uvar_get(VERBATIM_BYTE_SIZE); + if (mFatalError) + goto cleanup; + } + + break; + + default: + mFatalError = true; + //fprintf(stderr,"Sanity check fails trying to decode function: %d\n",cmd); + goto cleanup; + } + } + +cleanup: + + write_and_wait(mBytesInBuf); + +finish: + + mSeekTo = -1; + mEOF = true; + + /* wind up */ + var_get_quit(); + fwrite_type_quit(); + + if (buffer) free((void *) buffer); + if (offset) free((void *) offset); + if(maxnlpc > 0 && qlpc) + free((void *) qlpc); + +exit_thread: + + pthread_exit(NULL); +} diff --git a/Libraries/Shorten/Files/shorten/src/sulawalaw.c b/Libraries/Shorten/Files/shorten/src/sulawalaw.c index 7f720dc8b..61b417b87 100644 --- a/Libraries/Shorten/Files/shorten/src/sulawalaw.c +++ b/Libraries/Shorten/Files/shorten/src/sulawalaw.c @@ -1,5 +1,5 @@ /* - * $Id: sulawalaw.c 19 2005-06-07 04:16:15Z vspader $ + * $Id: sulawalaw.c,v 1.5 2001/12/30 05:12:04 jason Exp $ */ #include diff --git a/Libraries/Shorten/Files/shorten/src/vario.cpp b/Libraries/Shorten/Files/shorten/src/vario.cpp new file mode 100644 index 000000000..31e979f0c --- /dev/null +++ b/Libraries/Shorten/Files/shorten/src/vario.cpp @@ -0,0 +1,139 @@ +/* + * vario.cpp + * shorten_decoder + * + * Created by Alex Lagutin on Tue Jul 09 2002. + * Copyright (c) 2002 Eckysoft All rights reserved. + * + */ + +/****************************************************************************** +* * +* Copyright (C) 1992-1995 Tony Robinson * +* * +* See the file doc/LICENSE.shorten for conditions on distribution and usage * +* * +******************************************************************************/ + +/* + * $Id: vario.c,v 1.6 2001/12/30 05:12:04 jason Exp $ + */ + +#include "shn_reader.h" + +void shn_reader::var_get_init() +{ + int i; + ulong val = 0; + + masktab[0] = val; + for (i = 1; i < MASKTABSIZE; i++) + { + val <<= 1; + val |= 1; + masktab[i] = val; + } + + mDecodeState.getbuf = (uchar *) malloc(BUFSIZ); + mDecodeState.getbufp = mDecodeState.getbuf; + mDecodeState.nbyteget = 0; + mDecodeState.gbuffer = 0; + mDecodeState.nbitget = 0; + + if (!mDecodeState.getbuf) + mFatalError = true; +} + +ulong shn_reader::word_get() +{ + ulong buffer; + + if (mDecodeState.nbyteget < 4) + { + mDecodeState.nbyteget += fread(mDecodeState.getbuf, 1, BUFSIZ, mFP); + if (mDecodeState.nbyteget < 4) + { + mFatalError = true; + return 0; + } + mDecodeState.getbufp = mDecodeState.getbuf; + } + + buffer = (((long) (mDecodeState.getbufp[0])) << 24) | (((long) (mDecodeState.getbufp[1])) << 16) + | (((long) (mDecodeState.getbufp[2])) << 8) | ((long) (mDecodeState.getbufp[3])); + + mDecodeState.getbufp += 4; + mDecodeState.nbyteget -= 4; + + return buffer; +} + +long shn_reader::uvar_get(int nbin) +{ + long result; + + if (!mDecodeState.nbitget) + { + mDecodeState.gbuffer = word_get(); + if (mFatalError) + return 0; + mDecodeState.nbitget = 32; + } + + for (result = 0; !(mDecodeState.gbuffer & (1L << --(mDecodeState.nbitget))); result++) + { + if (!mDecodeState.nbitget) + { + mDecodeState.gbuffer = word_get(); + if (mFatalError) + return 0; + mDecodeState.nbitget = 32; + } + } + + while (nbin) + { + if(mDecodeState.nbitget >= nbin) + { + result = (result << nbin) | ((mDecodeState.gbuffer >> (mDecodeState.nbitget-nbin)) & masktab[nbin]); + mDecodeState.nbitget -= nbin; + nbin = 0; + } + else + { + result = (result << mDecodeState.nbitget) | (mDecodeState.gbuffer & masktab[mDecodeState.nbitget]); + mDecodeState.gbuffer = word_get(); + if (mFatalError) + return 0; + nbin -= mDecodeState.nbitget; + mDecodeState.nbitget = 32; + } + } + + return result; +} + +ulong shn_reader::ulong_get() +{ + uint nbit = uvar_get(ULONGSIZE); + + if (mFatalError) + return 0; + + return uvar_get(nbit); +} + +long shn_reader::var_get(int nbin) +{ + ulong uvar = uvar_get(nbin + 1); + if (mFatalError) + return 0; + + return ((uvar & 1) ? ((long) ~(uvar >> 1)) : ((long) (uvar >> 1))); +} + +void shn_reader::var_get_quit() +{ + free(mDecodeState.getbuf); + mDecodeState.getbuf = NULL; +} diff --git a/Libraries/Shorten/Shorten.xcodeproj/project.pbxproj b/Libraries/Shorten/Shorten.xcodeproj/project.pbxproj index 8722feb77..42810c79a 100644 --- a/Libraries/Shorten/Shorten.xcodeproj/project.pbxproj +++ b/Libraries/Shorten/Shorten.xcodeproj/project.pbxproj @@ -7,62 +7,54 @@ objects = { /* Begin PBXBuildFile section */ + 597A37500A2A2C9A00730CFA /* bitshift.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FDCD5D0A29226D006C1800 /* bitshift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 597A37510A2A2C9A00730CFA /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FDCD5E0A29226D006C1800 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 597A37520A2A2C9A00730CFA /* shn_reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FDCD5F0A29226D006C1800 /* shn_reader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 597A37530A2A2C9A00730CFA /* shorten.h in Headers */ = {isa = PBXBuildFile; fileRef = 59FDCD600A29226D006C1800 /* shorten.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 59F1214E0A311CD40052FE42 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F1214D0A311CD40052FE42 /* config.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 59FDCD6C0A2922E1006C1800 /* array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD650A2922E1006C1800 /* array.cpp */; }; + 59FDCD6D0A2922E1006C1800 /* fixio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD660A2922E1006C1800 /* fixio.cpp */; }; + 59FDCD6E0A2922E1006C1800 /* ringbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD670A2922E1006C1800 /* ringbuffer.cpp */; }; + 59FDCD6F0A2922E1006C1800 /* seek.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD680A2922E1006C1800 /* seek.cpp */; }; + 59FDCD700A2922E1006C1800 /* shn_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD690A2922E1006C1800 /* shn_reader.cpp */; }; + 59FDCD710A2922E1006C1800 /* sulawalaw.c in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD6A0A2922E1006C1800 /* sulawalaw.c */; }; + 59FDCD720A2922E1006C1800 /* vario.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59FDCD6B0A2922E1006C1800 /* vario.cpp */; }; 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; - 8E756C7109F3174E0080F1EE /* bitshift.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E756C6C09F3174E0080F1EE /* bitshift.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E756C7209F3174E0080F1EE /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E756C6D09F3174E0080F1EE /* config.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E756C7309F3174E0080F1EE /* decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E756C6E09F3174E0080F1EE /* decode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E756C7409F3174E0080F1EE /* shn.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E756C6F09F3174E0080F1EE /* shn.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E756C7509F3174E0080F1EE /* shorten.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E756C7009F3174E0080F1EE /* shorten.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E756C8609F317680080F1EE /* array.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C7A09F317680080F1EE /* array.c */; }; - 8E756C8709F317680080F1EE /* convert.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C7B09F317680080F1EE /* convert.c */; }; - 8E756C8809F317680080F1EE /* decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C7C09F317680080F1EE /* decode.c */; }; - 8E756C8909F317680080F1EE /* fixio.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C7D09F317680080F1EE /* fixio.c */; }; - 8E756C8A09F317680080F1EE /* id3v2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C7E09F317680080F1EE /* id3v2.c */; }; - 8E756C8B09F317680080F1EE /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C7F09F317680080F1EE /* misc.c */; }; - 8E756C8C09F317680080F1EE /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C8009F317680080F1EE /* output.c */; }; - 8E756C8D09F317680080F1EE /* seek.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C8109F317680080F1EE /* seek.c */; }; - 8E756C8E09F317680080F1EE /* shorten.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C8209F317680080F1EE /* shorten.c */; }; - 8E756C8F09F317680080F1EE /* sulawalaw.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C8309F317680080F1EE /* sulawalaw.c */; }; - 8E756C9009F317680080F1EE /* vario.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C8409F317680080F1EE /* vario.c */; }; - 8E756C9109F317680080F1EE /* wave.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E756C8509F317680080F1EE /* wave.c */; }; /* End PBXBuildFile section */ /* Begin PBXBuildStyle section */ - 014CEA440018CDF011CA2923 /* Debug */ = { + 8E8303D10A3226D3008E1F34 /* Development */ = { isa = PBXBuildStyle; buildSettings = { + COPY_PHASE_STRIP = NO; }; - name = Debug; + name = Development; }; - 014CEA450018CDF011CA2923 /* Release */ = { + 8E8303D20A3226D3008E1F34 /* Deployment */ = { isa = PBXBuildStyle; buildSettings = { + COPY_PHASE_STRIP = YES; }; - name = Release; + name = Deployment; }; /* End PBXBuildStyle section */ /* Begin PBXFileReference section */ 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 59F1214D0A311CD40052FE42 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = Files/shorten/include/config.h; sourceTree = ""; }; + 59FDCD5D0A29226D006C1800 /* bitshift.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = bitshift.h; path = Files/shorten/include/bitshift.h; sourceTree = ""; }; + 59FDCD5E0A29226D006C1800 /* ringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ringbuffer.h; path = Files/shorten/include/ringbuffer.h; sourceTree = ""; }; + 59FDCD5F0A29226D006C1800 /* shn_reader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = shn_reader.h; path = Files/shorten/include/shn_reader.h; sourceTree = ""; }; + 59FDCD600A29226D006C1800 /* shorten.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = shorten.h; path = Files/shorten/include/shorten.h; sourceTree = ""; }; + 59FDCD650A2922E1006C1800 /* array.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = array.cpp; path = Files/shorten/src/array.cpp; sourceTree = ""; }; + 59FDCD660A2922E1006C1800 /* fixio.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = fixio.cpp; path = Files/shorten/src/fixio.cpp; sourceTree = ""; }; + 59FDCD670A2922E1006C1800 /* ringbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ringbuffer.cpp; path = Files/shorten/src/ringbuffer.cpp; sourceTree = ""; }; + 59FDCD680A2922E1006C1800 /* seek.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = seek.cpp; path = Files/shorten/src/seek.cpp; sourceTree = ""; }; + 59FDCD690A2922E1006C1800 /* shn_reader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = shn_reader.cpp; path = Files/shorten/src/shn_reader.cpp; sourceTree = ""; }; + 59FDCD6A0A2922E1006C1800 /* sulawalaw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sulawalaw.c; path = Files/shorten/src/sulawalaw.c; sourceTree = ""; }; + 59FDCD6B0A2922E1006C1800 /* vario.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = vario.cpp; path = Files/shorten/src/vario.cpp; sourceTree = ""; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8DC2EF5B0486A6940098B216 /* Shorten.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Shorten.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 8E756C6C09F3174E0080F1EE /* bitshift.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = bitshift.h; path = Files/shorten/include/bitshift.h; sourceTree = ""; }; - 8E756C6D09F3174E0080F1EE /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = Files/shorten/include/config.h; sourceTree = ""; }; - 8E756C6E09F3174E0080F1EE /* decode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = decode.h; path = Files/shorten/include/decode.h; sourceTree = ""; }; - 8E756C6F09F3174E0080F1EE /* shn.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = shn.h; path = Files/shorten/include/shn.h; sourceTree = ""; }; - 8E756C7009F3174E0080F1EE /* shorten.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = shorten.h; path = Files/shorten/include/shorten.h; sourceTree = ""; }; - 8E756C7A09F317680080F1EE /* array.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = array.c; path = Files/shorten/src/array.c; sourceTree = ""; }; - 8E756C7B09F317680080F1EE /* convert.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = convert.c; path = Files/shorten/src/convert.c; sourceTree = ""; }; - 8E756C7C09F317680080F1EE /* decode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = decode.c; path = Files/shorten/src/decode.c; sourceTree = ""; }; - 8E756C7D09F317680080F1EE /* fixio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fixio.c; path = Files/shorten/src/fixio.c; sourceTree = ""; }; - 8E756C7E09F317680080F1EE /* id3v2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = id3v2.c; path = Files/shorten/src/id3v2.c; sourceTree = ""; }; - 8E756C7F09F317680080F1EE /* misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = misc.c; path = Files/shorten/src/misc.c; sourceTree = ""; }; - 8E756C8009F317680080F1EE /* output.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = output.c; path = Files/shorten/src/output.c; sourceTree = ""; }; - 8E756C8109F317680080F1EE /* seek.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = seek.c; path = Files/shorten/src/seek.c; sourceTree = ""; }; - 8E756C8209F317680080F1EE /* shorten.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = shorten.c; path = Files/shorten/src/shorten.c; sourceTree = ""; }; - 8E756C8309F317680080F1EE /* sulawalaw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sulawalaw.c; path = Files/shorten/src/sulawalaw.c; sourceTree = ""; }; - 8E756C8409F317680080F1EE /* vario.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = vario.c; path = Files/shorten/src/vario.c; sourceTree = ""; }; - 8E756C8509F317680080F1EE /* wave.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = wave.c; path = Files/shorten/src/wave.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -131,18 +123,13 @@ 8E756C6A09F317170080F1EE /* Source */ = { isa = PBXGroup; children = ( - 8E756C7A09F317680080F1EE /* array.c */, - 8E756C7B09F317680080F1EE /* convert.c */, - 8E756C7C09F317680080F1EE /* decode.c */, - 8E756C7D09F317680080F1EE /* fixio.c */, - 8E756C7E09F317680080F1EE /* id3v2.c */, - 8E756C7F09F317680080F1EE /* misc.c */, - 8E756C8009F317680080F1EE /* output.c */, - 8E756C8109F317680080F1EE /* seek.c */, - 8E756C8209F317680080F1EE /* shorten.c */, - 8E756C8309F317680080F1EE /* sulawalaw.c */, - 8E756C8409F317680080F1EE /* vario.c */, - 8E756C8509F317680080F1EE /* wave.c */, + 59FDCD650A2922E1006C1800 /* array.cpp */, + 59FDCD660A2922E1006C1800 /* fixio.cpp */, + 59FDCD670A2922E1006C1800 /* ringbuffer.cpp */, + 59FDCD680A2922E1006C1800 /* seek.cpp */, + 59FDCD690A2922E1006C1800 /* shn_reader.cpp */, + 59FDCD6A0A2922E1006C1800 /* sulawalaw.c */, + 59FDCD6B0A2922E1006C1800 /* vario.cpp */, ); name = Source; sourceTree = ""; @@ -150,11 +137,11 @@ 8E756C6B09F3171C0080F1EE /* Headers */ = { isa = PBXGroup; children = ( - 8E756C6C09F3174E0080F1EE /* bitshift.h */, - 8E756C6D09F3174E0080F1EE /* config.h */, - 8E756C6E09F3174E0080F1EE /* decode.h */, - 8E756C6F09F3174E0080F1EE /* shn.h */, - 8E756C7009F3174E0080F1EE /* shorten.h */, + 59F1214D0A311CD40052FE42 /* config.h */, + 59FDCD5D0A29226D006C1800 /* bitshift.h */, + 59FDCD5E0A29226D006C1800 /* ringbuffer.h */, + 59FDCD5F0A29226D006C1800 /* shn_reader.h */, + 59FDCD600A29226D006C1800 /* shorten.h */, ); name = Headers; sourceTree = ""; @@ -162,15 +149,15 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 8DC2EF500486A6940098B216 /* Headers */ = { + 597A374E0A2A2C5300730CFA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 8E756C7109F3174E0080F1EE /* bitshift.h in Headers */, - 8E756C7209F3174E0080F1EE /* config.h in Headers */, - 8E756C7309F3174E0080F1EE /* decode.h in Headers */, - 8E756C7409F3174E0080F1EE /* shn.h in Headers */, - 8E756C7509F3174E0080F1EE /* shorten.h in Headers */, + 597A37500A2A2C9A00730CFA /* bitshift.h in Headers */, + 597A37510A2A2C9A00730CFA /* ringbuffer.h in Headers */, + 597A37520A2A2C9A00730CFA /* shn_reader.h in Headers */, + 597A37530A2A2C9A00730CFA /* shorten.h in Headers */, + 59F1214E0A311CD40052FE42 /* config.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -181,15 +168,13 @@ isa = PBXNativeTarget; buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Shorten" */; buildPhases = ( - 8DC2EF500486A6940098B216 /* Headers */, + 597A374E0A2A2C5300730CFA /* Headers */, 8DC2EF520486A6940098B216 /* Resources */, 8DC2EF540486A6940098B216 /* Sources */, 8DC2EF560486A6940098B216 /* Frameworks */, ); buildRules = ( ); - buildSettings = { - }; dependencies = ( ); name = Shorten; @@ -207,8 +192,8 @@ buildSettings = { }; buildStyles = ( - 014CEA440018CDF011CA2923 /* Debug */, - 014CEA450018CDF011CA2923 /* Release */, + 8E8303D10A3226D3008E1F34 /* Development */, + 8E8303D20A3226D3008E1F34 /* Deployment */, ); hasScannedForEncodings = 1; mainGroup = 0867D691FE84028FC02AAC07 /* Shorten */; @@ -236,18 +221,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8E756C8609F317680080F1EE /* array.c in Sources */, - 8E756C8709F317680080F1EE /* convert.c in Sources */, - 8E756C8809F317680080F1EE /* decode.c in Sources */, - 8E756C8909F317680080F1EE /* fixio.c in Sources */, - 8E756C8A09F317680080F1EE /* id3v2.c in Sources */, - 8E756C8B09F317680080F1EE /* misc.c in Sources */, - 8E756C8C09F317680080F1EE /* output.c in Sources */, - 8E756C8D09F317680080F1EE /* seek.c in Sources */, - 8E756C8E09F317680080F1EE /* shorten.c in Sources */, - 8E756C8F09F317680080F1EE /* sulawalaw.c in Sources */, - 8E756C9009F317680080F1EE /* vario.c in Sources */, - 8E756C9109F317680080F1EE /* wave.c in Sources */, + 59FDCD6C0A2922E1006C1800 /* array.cpp in Sources */, + 59FDCD6D0A2922E1006C1800 /* fixio.cpp in Sources */, + 59FDCD6E0A2922E1006C1800 /* ringbuffer.cpp in Sources */, + 59FDCD6F0A2922E1006C1800 /* seek.cpp in Sources */, + 59FDCD700A2922E1006C1800 /* shn_reader.cpp in Sources */, + 59FDCD710A2922E1006C1800 /* sulawalaw.c in Sources */, + 59FDCD720A2922E1006C1800 /* vario.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -315,6 +295,12 @@ buildSettings = { GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + ., + ../include, + ../../include, + include, + ); PREBINDING = NO; SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; @@ -325,6 +311,12 @@ buildSettings = { GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + ., + ../include, + ../../include, + include, + ); PREBINDING = NO; SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; diff --git a/Sound/SoundFile/ShnFile.h b/Sound/SoundFile/ShnFile.h index ff7501190..2f56b549e 100644 --- a/Sound/SoundFile/ShnFile.h +++ b/Sound/SoundFile/ShnFile.h @@ -7,18 +7,18 @@ // #import +#import + #import "SoundFile.h" -#import "Shorten/shorten.h" -#import "Shorten/shn.h" -#import "Shorten/decode.h" - @interface ShnFile : SoundFile { - shn_file *handle; + //shn_file *handle; + shn_reader *decoder; - int bufferSize; //total size + long bufferSize; //total size void *buffer; - int bufferAmount; //amount currently in + void *inputBuffer;//derek + long bufferAmount; //amount currently in } @end diff --git a/Sound/SoundFile/ShnFile.m b/Sound/SoundFile/ShnFile.m deleted file mode 100644 index 6b8027d8a..000000000 --- a/Sound/SoundFile/ShnFile.m +++ /dev/null @@ -1,115 +0,0 @@ -// -// ShnFile.m -// Cog -// -// Created by Vincent Spader on 6/6/05. -// Copyright 2005 Vincent Spader All rights reserved. -// - -#import "ShnFile.h" - - -@implementation ShnFile - -- (BOOL)open:(const char *)filename -{ - if ([self readInfo:filename] == NO) - return NO; - - bufferSize = shn_get_buffer_block_size(handle, 512); - buffer = malloc(bufferSize); - - return YES; -} - -- (BOOL)readInfo:(const char *)filename -{ - shn_config conf; - int r; - - conf.error_output_method = ERROR_OUTPUT_DEVNULL; - conf.seek_tables_path = NULL; - conf.relative_seek_tables_path = "."; - conf.verbose = 0; - conf.swap_bytes = 0; - - handle = shn_load((char *)filename, conf); - if (!handle) - return NO; - - r = shn_init_decoder(handle); - if (r < 0) - return NO; - - channels = shn_get_channels(handle); - frequency = shn_get_samplerate(handle); - bitsPerSample = shn_get_bitspersample(handle); - - unsigned int length; - length = shn_get_song_length(handle); - totalSize = (((double)(length)*frequency)/1000.0) * channels * (bitsPerSample/8); - - bitRate = (int)((double)totalSize/((double)length/1000.0)); - - return YES; -} - -- (int)fillBuffer:(void *)buf ofSize:(UInt32)size -{ - int numread = bufferAmount; - int count = 0; - - //Fill from buffer, going by bufferAmount - //if still needs more, decode and repeat - if (bufferAmount == 0) - { - bufferAmount = shn_read(handle, buffer, bufferSize); - if (bufferAmount == 0) - return 0; - } - - count = bufferAmount; - if (bufferAmount > size) - { - count = size; - } - - memcpy(buf, buffer, count); - - bufferAmount -= count; - - if (bufferAmount > 0) - memmove(buffer, &buffer[count], bufferAmount); - - if (count < size) - numread = [self fillBuffer:(&((char *)buf)[count]) ofSize:(size - count)]; - else - numread = 0; - - return count + numread; -} - -- (double)seekToTime:(double)milliseconds -{ - unsigned int sec; - - if (!shn_seekable(handle)) - return -1.0; - - sec = (int)(milliseconds/1000.0); - - shn_seek(handle, sec); - - return (sec * 1000.0); -} - -- (void)close -{ - if (buffer) - free(buffer); - - if (shn_cleanup_decoder(handle)) - shn_unload(handle); -} - -@end