check in new version of the winamp3 plugin
authorJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 8 Nov 2001 23:54:10 +0000 (23:54 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 8 Nov 2001 23:54:10 +0000 (23:54 +0000)
src/plugin_winamp3/Makefile.am
src/plugin_winamp3/README.txt [new file with mode: 0644]
src/plugin_winamp3/cnv_flacpcm.cpp [new file with mode: 0644]
src/plugin_winamp3/cnv_flacpcm.dsp [new file with mode: 0644]
src/plugin_winamp3/cnv_flacpcm.dsw [new file with mode: 0644]
src/plugin_winamp3/cnv_flacpcm.h [new file with mode: 0644]
src/plugin_winamp3/flacpcm.cpp [new file with mode: 0644]
src/plugin_winamp3/flacpcm.h [new file with mode: 0644]

index 0074ebf..f7a328a 100644 (file)
 #  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
diff --git a/src/plugin_winamp3/README.txt b/src/plugin_winamp3/README.txt
new file mode 100644 (file)
index 0000000..ab7e9e2
--- /dev/null
@@ -0,0 +1,6 @@
+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
diff --git a/src/plugin_winamp3/cnv_flacpcm.cpp b/src/plugin_winamp3/cnv_flacpcm.cpp
new file mode 100644 (file)
index 0000000..e0a6672
--- /dev/null
@@ -0,0 +1,101 @@
+/* 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
diff --git a/src/plugin_winamp3/cnv_flacpcm.dsp b/src/plugin_winamp3/cnv_flacpcm.dsp
new file mode 100644 (file)
index 0000000..7198a5f
--- /dev/null
@@ -0,0 +1,205 @@
+# 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
diff --git a/src/plugin_winamp3/cnv_flacpcm.dsw b/src/plugin_winamp3/cnv_flacpcm.dsw
new file mode 100644 (file)
index 0000000..e1b42d0
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/src/plugin_winamp3/cnv_flacpcm.h b/src/plugin_winamp3/cnv_flacpcm.h
new file mode 100644 (file)
index 0000000..bd06185
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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
diff --git a/src/plugin_winamp3/flacpcm.cpp b/src/plugin_winamp3/flacpcm.cpp
new file mode 100644 (file)
index 0000000..e1d7a37
--- /dev/null
@@ -0,0 +1,354 @@
+/* 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
diff --git a/src/plugin_winamp3/flacpcm.h b/src/plugin_winamp3/flacpcm.h
new file mode 100644 (file)
index 0000000..b1f814f
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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