# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-EXTRA_DIST = Makefile.vc \
- core_api.h \
- in_flac.cpp
+EXTRA_DIST = \
+ README.txt \
+ cnv_flacpcm.cpp \
+ cnv_flacpcm.dsp \
+ cnv_flacpcm.dsw \
+ cnv_flacpcm.h \
+ flacpcm.cpp \
+ flacpcm.h
--- /dev/null
+This plugin require the Wasabi SDK, and the project assumes that you have it\r
+installed in the standard place: \Wasabi SDK. If not, you will have to edit\r
+the .dsp file to change the path.\r
+\r
+Also, you must build libFLAC first; if you haven't, cd to src\libFLAC and\r
+run 'nmake /f Makefile.vc'\r
--- /dev/null
+/* FLAC input plugin for Winamp3\r
+ * Copyright (C) 2000,2001 Josh Coalson\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ *\r
+ * NOTE: this code is derived from the 'rawpcm' example by\r
+ * Nullsoft; the original license for the 'rawpcm' example follows.\r
+ */\r
+/*\r
+\r
+ Nullsoft WASABI Source File License\r
+\r
+ Copyright 1999-2001 Nullsoft, Inc.\r
+\r
+ This software is provided 'as-is', without any express or implied\r
+ warranty. In no event will the authors be held liable for any damages\r
+ arising from the use of this software.\r
+\r
+ Permission is granted to anyone to use this software for any purpose,\r
+ including commercial applications, and to alter it and redistribute it\r
+ freely, subject to the following restrictions:\r
+\r
+ 1. The origin of this software must not be misrepresented; you must not\r
+ claim that you wrote the original software. If you use this software\r
+ in a product, an acknowledgment in the product documentation would be\r
+ appreciated but is not required.\r
+ 2. Altered source versions must be plainly marked as such, and must not be\r
+ misrepresented as being the original software.\r
+ 3. This notice may not be removed or altered from any source distribution.\r
+\r
+\r
+ Brennan Underwood\r
+ brennan@nullsoft.com\r
+\r
+*/\r
+\r
+#include "cnv_flacpcm.h"\r
+#include "flacpcm.h"\r
+\r
+static WACNAME wac;\r
+WAComponentClient *the = &wac;\r
+\r
+#include "studio/services/servicei.h"\r
+static waServiceT<svc_mediaConverter, FlacPcm> flacpcm;\r
+\r
+// {683FA153-4055-467c-ABEE-5E35FA03C51E}\r
+static const GUID guid = \r
+{ 0x683fa153, 0x4055, 0x467c, { 0xab, 0xee, 0x5e, 0x35, 0xfa, 0x3, 0xc5, 0x1e } };\r
+\r
+_int nch;\r
+_int samplerate;\r
+_int bps;\r
+\r
+WACNAME::WACNAME() : CfgItemI("RAW files support") {\r
+#ifdef FORTIFY\r
+ FortifySetName("cnv_flacpcm.wac");\r
+ FortifyEnterScope();\r
+#endif\r
+}\r
+\r
+WACNAME::~WACNAME() {\r
+#ifdef FORTIFY\r
+ FortifyLeaveScope();\r
+#endif\r
+}\r
+\r
+GUID WACNAME::getGUID() {\r
+ return guid;\r
+}\r
+\r
+void WACNAME::onRegisterServices() {\r
+ api->service_register(&flacpcm);\r
+ api->core_registerExtension("*.flac","FLAC Files");\r
+\r
+ nch.setName("# of channels");\r
+ nch=2;\r
+ registerAttribute(&nch);\r
+ samplerate.setName("Sample rate");\r
+ samplerate=44100;\r
+ registerAttribute(&samplerate);\r
+ bps.setName("Bits per second");\r
+ bps=16;\r
+ registerAttribute(&bps);\r
+}\r
+\r
+void WACNAME::onDestroy() {\r
+ api->service_deregister(&flacpcm);\r
+ WAComponentClient::onDestroy();\r
+}\r
--- /dev/null
+# Microsoft Developer Studio Project File - Name="cnv_flacpcm" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=cnv_flacpcm - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "cnv_flacpcm.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "cnv_flacpcm.mak" CFG="cnv_flacpcm - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "cnv_flacpcm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "cnv_flacpcm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName "$/Studio/cnv_flacpcm"\r
+# PROP Scc_LocalPath "."\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF "$(CFG)" == "cnv_flacpcm - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "cnv_flacpcm_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "\Wasabi SDK\studio" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "cnv_flacpcm_EXPORTS" /D "USE_ASM" /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 libFLAC.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msacm32.lib winmm.lib /nologo /dll /machine:I386 /out:"../../obj/bin/cnv_flacpcm.wac" /libpath:"../../obj/lib"\r
+# SUBTRACT LINK32 /nodefaultlib\r
+\r
+!ELSEIF "$(CFG)" == "cnv_flacpcm - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "cnv_flacpcm_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "\Wasabi SDK\studio" /D "_DEBUG" /D "WACLIENT_NOICONSUPPORT" /D "REAL_STDIO" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "cnv_flacpcm_EXPORTS" /D "USE_ASM" /YX /FD /GZ /c\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 libFLAC.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msacm32.lib winmm.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /out:"../../obj/bin/cnv_flacpcm.wac" /pdbtype:sept /libpath:"../../obj/lib"\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "cnv_flacpcm - Win32 Release"\r
+# Name "cnv_flacpcm - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Group "Wasabi SDK"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\studio\assert.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\attribs\attribute.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\attribs\attrint.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\bitmap.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\blending.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\canvas.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\attribs\cfgitemi.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\studio\corecb.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\depend.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\nsGUID.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\pathparse.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\ptrlist.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\region.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\studio\services\servicei.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\std.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\common\string.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\studio\services\svc_mediaconverter.cpp"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\studio\services\svc_mediaconverter.h"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE="\Wasabi SDK\studio\studio\waclient.cpp"\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\cnv_flacpcm.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\flacpcm.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\cnv_flacpcm.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\flacpcm.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\README.txt\r
+# End Source File\r
+# End Target\r
+# End Project\r
--- /dev/null
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "cnv_flacpcm"=.\cnv_flacpcm.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
--- /dev/null
+/* FLAC input plugin for Winamp3\r
+ * Copyright (C) 2000,2001 Josh Coalson\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ *\r
+ * NOTE: this code is derived from the 'rawpcm' example by\r
+ * Nullsoft; the original license for the 'rawpcm' example follows.\r
+ */\r
+/*\r
+\r
+ Nullsoft WASABI Source File License\r
+\r
+ Copyright 1999-2001 Nullsoft, Inc.\r
+\r
+ This software is provided 'as-is', without any express or implied\r
+ warranty. In no event will the authors be held liable for any damages\r
+ arising from the use of this software.\r
+\r
+ Permission is granted to anyone to use this software for any purpose,\r
+ including commercial applications, and to alter it and redistribute it\r
+ freely, subject to the following restrictions:\r
+\r
+ 1. The origin of this software must not be misrepresented; you must not\r
+ claim that you wrote the original software. If you use this software\r
+ in a product, an acknowledgment in the product documentation would be\r
+ appreciated but is not required.\r
+ 2. Altered source versions must be plainly marked as such, and must not be\r
+ misrepresented as being the original software.\r
+ 3. This notice may not be removed or altered from any source distribution.\r
+\r
+\r
+ Brennan Underwood\r
+ brennan@nullsoft.com\r
+\r
+*/\r
+\r
+#ifndef _CNV_FLACPCM_H\r
+#define _CNV_FLACPCM_H\r
+\r
+#include "studio/wac.h"\r
+#include "common/rootcomp.h"\r
+#include "attribs/cfgitemi.h"\r
+#include "attribs/attrint.h"\r
+\r
+#define WACNAME WACcnv_flacpcm\r
+\r
+class WACNAME : public WAComponentClient, public CfgItemI {\r
+public:\r
+ WACNAME();\r
+ virtual ~WACNAME();\r
+\r
+ virtual const char *getName() { return "FLAC to PCM converter"; };\r
+ virtual GUID getGUID();\r
+\r
+ virtual void onRegisterServices();\r
+ virtual void onDestroy();\r
+\r
+ virtual int getDisplayComponent() { return FALSE; };\r
+\r
+ virtual CfgItem *getCfgInterface(int n) { return this; }\r
+};\r
+\r
+#endif\r
--- /dev/null
+/* FLAC input plugin for Winamp3\r
+ * Copyright (C) 2000,2001 Josh Coalson\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ *\r
+ * NOTE: this code is derived from the 'rawpcm' example by\r
+ * Nullsoft; the original license for the 'rawpcm' example follows.\r
+ */\r
+/*\r
+\r
+ Nullsoft WASABI Source File License\r
+\r
+ Copyright 1999-2001 Nullsoft, Inc.\r
+\r
+ This software is provided 'as-is', without any express or implied\r
+ warranty. In no event will the authors be held liable for any damages\r
+ arising from the use of this software.\r
+\r
+ Permission is granted to anyone to use this software for any purpose,\r
+ including commercial applications, and to alter it and redistribute it\r
+ freely, subject to the following restrictions:\r
+\r
+ 1. The origin of this software must not be misrepresented; you must not\r
+ claim that you wrote the original software. If you use this software\r
+ in a product, an acknowledgment in the product documentation would be\r
+ appreciated but is not required.\r
+ 2. Altered source versions must be plainly marked as such, and must not be\r
+ misrepresented as being the original software.\r
+ 3. This notice may not be removed or altered from any source distribution.\r
+\r
+\r
+ Brennan Underwood\r
+ brennan@nullsoft.com\r
+\r
+*/\r
+\r
+#include "flacpcm.h"\r
+extern "C" {\r
+#include "FLAC/utility.h"\r
+};\r
+\r
+\r
+struct id3v1_struct {\r
+ FLAC__byte raw[128];\r
+ char title[31];\r
+ char artist[31];\r
+ char album[31];\r
+ char comment[31];\r
+ unsigned year;\r
+ unsigned track; /* may be 0 if v1 (not v1.1) tag */\r
+ unsigned genre;\r
+ char description[1024]; /* the formatted description passed to the gui */\r
+};\r
+\r
+\r
+static bool get_id3v1_tag_(const char *filename, id3v1_struct *tag);\r
+\r
+\r
+FlacPcm::FlacPcm():\r
+needs_seek(false),\r
+seek_sample(0),\r
+samples_in_reservoir(0),\r
+abort_flag(false),\r
+reader(0),\r
+decoder(0)\r
+{\r
+}\r
+\r
+FlacPcm::~FlacPcm()\r
+{\r
+ cleanup();\r
+}\r
+\r
+int FlacPcm::getInfos(MediaInfo *infos)\r
+{\r
+ reader = infos->getReader();\r
+ if(!reader) return 0;\r
+\r
+ //@@@ to be really "clean" we should go through the reader instead of directly to the file...\r
+ if(!FLAC__utility_get_streaminfo(infos->getFilename(), &stream_info))\r
+ return 1;\r
+\r
+ id3v1_struct tag;\r
+\r
+ //@@@ ditto here...\r
+ bool has_tag = get_id3v1_tag_(infos->getFilename(), &tag);\r
+\r
+ infos->setLength(lengthInMsec());\r
+ //@@@ infos->setTitle(Std::filename(infos->getFilename()));\r
+ infos->setTitle(tag.description);\r
+ infos->setInfo(StringPrintf("FLAC:<%ihz:%ibps:%dch>", stream_info.sample_rate, stream_info.bits_per_sample, stream_info.channels)); //@@@ fix later\r
+ if(has_tag) {\r
+ infos->setData("Title", tag.title);\r
+ infos->setData("Artist", tag.artist);\r
+ infos->setData("Album", tag.album);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+int FlacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)\r
+{\r
+ reader = infos->getReader();\r
+ if(reader == 0)\r
+ return 0;\r
+\r
+ if(decoder == 0) {\r
+ decoder = FLAC__seekable_stream_decoder_new();\r
+ if(decoder == 0)\r
+ return 0;\r
+ FLAC__seekable_stream_decoder_set_md5_checking(decoder, false);\r
+ FLAC__seekable_stream_decoder_set_read_callback(decoder, readCallback_);\r
+ FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekCallback_);\r
+ FLAC__seekable_stream_decoder_set_tell_callback(decoder, tellCallback_);\r
+ FLAC__seekable_stream_decoder_set_length_callback(decoder, lengthCallback_);\r
+ FLAC__seekable_stream_decoder_set_eof_callback(decoder, eofCallback_);\r
+ FLAC__seekable_stream_decoder_set_write_callback(decoder, writeCallback_);\r
+ FLAC__seekable_stream_decoder_set_metadata_callback(decoder, metadataCallback_);\r
+ FLAC__seekable_stream_decoder_set_error_callback(decoder, errorCallback_);\r
+ FLAC__seekable_stream_decoder_set_client_data(decoder, this);\r
+\r
+ if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) {\r
+ cleanup();\r
+ return 0;\r
+ }\r
+ if(!FLAC__seekable_stream_decoder_process_metadata(decoder)) {\r
+ cleanup();\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ if(needs_seek) {\r
+ FLAC__seekable_stream_decoder_seek_absolute(decoder, seek_sample);\r
+ needs_seek = false;\r
+ }\r
+\r
+ bool eof = false;\r
+\r
+ while(samples_in_reservoir < 576) {\r
+ if(FLAC__seekable_stream_decoder_get_state(decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {\r
+ eof = true;\r
+ break;\r
+ }\r
+ else if(!FLAC__seekable_stream_decoder_process_one_frame(decoder))\r
+ break;\r
+ }\r
+\r
+ if(samples_in_reservoir == 0) {\r
+ eof = true;\r
+ }\r
+ else {\r
+ const unsigned channels = stream_info.channels;\r
+ const unsigned bits_per_sample = stream_info.bits_per_sample;\r
+ const unsigned bytes_per_sample = (bits_per_sample+7)/8;\r
+ const unsigned sample_rate = stream_info.sample_rate;\r
+ unsigned i, n = min(samples_in_reservoir, 576), delta;\r
+ signed short *ssbuffer = (signed short*)output;\r
+\r
+ for(i = 0; i < n*channels; i++)\r
+ ssbuffer[i] = reservoir[i];\r
+ delta = i;\r
+ for( ; i < samples_in_reservoir*channels; i++)\r
+ reservoir[i-delta] = reservoir[i];\r
+ samples_in_reservoir -= n;\r
+\r
+ const int bytes = n * channels * bytes_per_sample;\r
+\r
+ ChunkInfosI *ci=new ChunkInfosI();\r
+ ci->addInfo("srate", sample_rate);\r
+ ci->addInfo("bps", bits_per_sample);\r
+ ci->addInfo("nch", channels);\r
+\r
+ chunk_list->setChunk("PCM", output, bytes, ci);\r
+ }\r
+\r
+ if(eof)\r
+ return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+int FlacPcm::corecb_onSeeked(int newpos)\r
+{\r
+ if(stream_info.total_samples == 0 || newpos < 0)\r
+ return 1;\r
+\r
+ needs_seek = true;\r
+ seek_sample = (FLAC__uint64)((double)newpos / (double)lengthInMsec() * (double)(FLAC__int64)stream_info.total_samples);\r
+ return 0;\r
+}\r
+\r
+void FlacPcm::cleanup()\r
+{\r
+ if(decoder) {\r
+ if(FLAC__seekable_stream_decoder_get_state(decoder) != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)\r
+ FLAC__seekable_stream_decoder_finish(decoder);\r
+ FLAC__seekable_stream_decoder_delete(decoder);\r
+ decoder = 0;\r
+ }\r
+}\r
+FLAC__SeekableStreamDecoderReadStatus FlacPcm::readCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ *bytes = instance->reader->read((char*)buffer, *bytes);\r
+ return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;\r
+}\r
+\r
+FLAC__SeekableStreamDecoderSeekStatus FlacPcm::seekCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ if(instance->reader->seek((int)absolute_byte_offset) < 0)\r
+ return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;\r
+ else\r
+ return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;\r
+}\r
+\r
+FLAC__SeekableStreamDecoderTellStatus FlacPcm::tellCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ int pos = instance->reader->getPos();\r
+ if(pos < 0)\r
+ return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;\r
+ else {\r
+ *absolute_byte_offset = pos;\r
+ return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;\r
+ }\r
+}\r
+\r
+FLAC__SeekableStreamDecoderLengthStatus FlacPcm::lengthCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ int length = instance->reader->getPos();\r
+ if(length < 0)\r
+ return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;\r
+ else {\r
+ *stream_length = length;\r
+ return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;\r
+ }\r
+}\r
+\r
+FLAC__bool FlacPcm::eofCallback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ return instance->reader->getPos() == instance->reader->getLength();\r
+}\r
+\r
+FLAC__StreamDecoderWriteStatus FlacPcm::writeCallback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ const unsigned bps = instance->stream_info.bits_per_sample, channels = instance->stream_info.channels, wide_samples = frame->header.blocksize;\r
+ unsigned wide_sample, sample, channel;\r
+\r
+ (void)decoder;\r
+\r
+ if(instance->abort_flag)\r
+ return FLAC__STREAM_DECODER_WRITE_ABORT;\r
+\r
+ for(sample = instance->samples_in_reservoir*channels, wide_sample = 0; wide_sample < wide_samples; wide_sample++)\r
+ for(channel = 0; channel < channels; channel++, sample++)\r
+ instance->reservoir[sample] = (FLAC__int16)buffer[channel][wide_sample];\r
+\r
+ instance->samples_in_reservoir += wide_samples;\r
+\r
+ return FLAC__STREAM_DECODER_WRITE_CONTINUE;\r
+}\r
+\r
+void FlacPcm::metadataCallback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ (void)decoder;\r
+ if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {\r
+ instance->stream_info = metadata->data.stream_info;\r
+\r
+ if(instance->stream_info.bits_per_sample != 16) {\r
+ //@@@ how to do this? MessageBox(mod.hMainWindow, "ERROR: plugin can only handle 16-bit samples\n", "ERROR: plugin can only handle 16-bit samples", 0);\r
+ instance->abort_flag = true;\r
+ return;\r
+ }\r
+ }\r
+}\r
+\r
+void FlacPcm::errorCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)\r
+{\r
+ FlacPcm *instance = (FlacPcm*)client_data;\r
+ (void)decoder;\r
+ if(status != FLAC__STREAM_DECODER_ERROR_LOST_SYNC)\r
+ instance->abort_flag = true;\r
+}\r
+\r
+/***********************************************************************\r
+ * local routines\r
+ **********************************************************************/\r
+\r
+bool get_id3v1_tag_(const char *filename, id3v1_struct *tag)\r
+{\r
+ const char *temp;\r
+ FILE *f = fopen(filename, "rb");\r
+ memset(tag, 0, sizeof(id3v1_struct));\r
+strcpy(tag->title,"Sonata K.42");\r
+strcpy(tag->artist,"Domenico Scarlatti");\r
+strcpy(tag->album,"Narcisso Yepes Plays Scarlatti");\r
+sprintf(tag->description, "%s - %s", tag->artist, tag->title);\r
+\r
+ /* set the title and description to the filename by default */\r
+ temp = strrchr(filename, '/');\r
+ if(!temp)\r
+ temp = filename;\r
+ else\r
+ temp++;\r
+ strcpy(tag->description, temp);\r
+ *strrchr(tag->description, '.') = '\0';\r
+ strncpy(tag->title, tag->description, 30); tag->title[30] = '\0';\r
+\r
+ if(0 == f)\r
+ return false;\r
+ if(-1 == fseek(f, -128, SEEK_END)) {\r
+ fclose(f);\r
+ return false;\r
+ }\r
+ if(fread(tag->raw, 1, 128, f) < 128) {\r
+ fclose(f);\r
+ return false;\r
+ }\r
+ fclose(f);\r
+ if(strncmp((const char*)tag->raw, "TAG", 3))\r
+ return false;\r
+ else {\r
+ char year_str[5];\r
+\r
+ memcpy(tag->title, tag->raw+3, 30);\r
+ memcpy(tag->artist, tag->raw+33, 30);\r
+ memcpy(tag->album, tag->raw+63, 30);\r
+ memcpy(year_str, tag->raw+93, 4); year_str[4] = '\0'; tag->year = atoi(year_str);\r
+ memcpy(tag->comment, tag->raw+97, 30);\r
+ tag->genre = (unsigned)((FLAC__byte)tag->raw[127]);\r
+ tag->track = (unsigned)((FLAC__byte)tag->raw[126]);\r
+\r
+ sprintf(tag->description, "%s - %s", tag->artist, tag->title);\r
+\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* FLAC input plugin for Winamp3\r
+ * Copyright (C) 2000,2001 Josh Coalson\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ *\r
+ * NOTE: this code is derived from the 'rawpcm' example by\r
+ * Nullsoft; the original license for the 'rawpcm' example follows.\r
+ */\r
+/*\r
+\r
+ Nullsoft WASABI Source File License\r
+\r
+ Copyright 1999-2001 Nullsoft, Inc.\r
+\r
+ This software is provided 'as-is', without any express or implied\r
+ warranty. In no event will the authors be held liable for any damages\r
+ arising from the use of this software.\r
+\r
+ Permission is granted to anyone to use this software for any purpose,\r
+ including commercial applications, and to alter it and redistribute it\r
+ freely, subject to the following restrictions:\r
+\r
+ 1. The origin of this software must not be misrepresented; you must not\r
+ claim that you wrote the original software. If you use this software\r
+ in a product, an acknowledgment in the product documentation would be\r
+ appreciated but is not required.\r
+ 2. Altered source versions must be plainly marked as such, and must not be\r
+ misrepresented as being the original software.\r
+ 3. This notice may not be removed or altered from any source distribution.\r
+\r
+\r
+ Brennan Underwood\r
+ brennan@nullsoft.com\r
+\r
+*/\r
+\r
+#ifndef _FLACPCM_H\r
+#define _FLACPCM_H\r
+\r
+#include "studio/services/svc_mediaconverter.h"\r
+#include "studio/services/servicei.h"\r
+#include "studio/corecb.h"\r
+#include "studio/wac.h"\r
+#include "attribs/cfgitemi.h"\r
+#include "attribs/attrint.h"\r
+extern "C" {\r
+#include "FLAC/seekable_stream_decoder.h"\r
+};\r
+\r
+class FlacPcm : public svc_mediaConverterI {\r
+public:\r
+ FlacPcm();\r
+ virtual ~FlacPcm();\r
+\r
+ // service\r
+ static const char *getServiceName() { return "FLAC to PCM converter service"; }\r
+\r
+ virtual int canConvertFrom(svc_fileReader *reader, const char *name, const char *chunktype)\r
+ { return name && !STRICMP(Std::extension(name), "flac"); } // only accepts *.flac files\r
+\r
+ virtual const char *getConverterTo() { return "PCM"; }\r
+\r
+ virtual int getInfos(MediaInfo *infos);\r
+\r
+ virtual int processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch);\r
+\r
+ virtual int getLatency(void) { return 0; }\r
+\r
+ // callbacks\r
+ virtual int corecb_onSeeked(int newpos);\r
+\r
+protected:\r
+ bool needs_seek;\r
+ FLAC__uint64 seek_sample;\r
+ unsigned samples_in_reservoir;\r
+ bool abort_flag;\r
+ svc_fileReader *reader;\r
+ FLAC__SeekableStreamDecoder *decoder;\r
+ FLAC__StreamMetaData_StreamInfo stream_info;\r
+ FLAC__int16 reservoir[FLAC__MAX_BLOCK_SIZE * 2 * 2]; // *2 for max channels, another *2 for overflow\r
+ unsigned char output[576 * 2 * (16/8)]; // *2 for max channels, (16/8) for max bytes per sample\r
+\r
+ unsigned lengthInMsec() { return (unsigned)((FLAC__uint64)1000 * stream_info.total_samples / stream_info.sample_rate); }\r
+private:\r
+ void cleanup();\r
+ static FLAC__SeekableStreamDecoderReadStatus readCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);\r
+ static FLAC__SeekableStreamDecoderSeekStatus seekCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);\r
+ static FLAC__SeekableStreamDecoderTellStatus tellCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);\r
+ static FLAC__SeekableStreamDecoderLengthStatus lengthCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);\r
+ static FLAC__bool eofCallback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);\r
+ static FLAC__StreamDecoderWriteStatus writeCallback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);\r
+ static void metadataCallback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);\r
+ static void errorCallback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);\r
+};\r
+#endif\r