diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_flac/main.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_flac/main.cpp')
-rw-r--r-- | Src/Plugins/Input/in_flac/main.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_flac/main.cpp b/Src/Plugins/Input/in_flac/main.cpp new file mode 100644 index 00000000..047d1529 --- /dev/null +++ b/Src/Plugins/Input/in_flac/main.cpp @@ -0,0 +1,277 @@ +/* +** Copyright © 2007-2014 Winamp SA +** +** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held +** liable for any damages arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to +** alter it and redistribute it freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +** +** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +** +** 3. This notice may not be removed or altered from any source distribution. +** +** Author: Ben Allison benski@winamp.com +** Created: March 1, 2007 +** +*/ +#include "main.h" +#include "api__in_flv.h" +#include "Metadata.h" +#include "../Agave/Language/api_language.h" +#include <api/service/waServiceFactory.h> +#include "../Winamp/wa_ipc.h" +#include "../nu/Singleton.h" +#include "../nu/Autochar.h" +#include <shlwapi.h> +#include "resource.h" +#include "AlbumArt.h" +#include "RawReader.h" +#include <strsafe.h> +#include "nswasabi/ReferenceCounted.h" +#include "mkv_flac_decoder.h" + +api_config *AGAVE_API_CONFIG = 0; +api_memmgr *WASABI_API_MEMMGR=0; +AlbumArtFactory albumArtFactory; +static RawMediaReaderService raw_media_reader_service; +static SingletonServiceFactory<svc_raw_media_reader, RawMediaReaderService> raw_factory; +static MKVDecoder mkv_service; +static SingletonServiceFactory<svc_mkvdecoder, MKVDecoder> mkv_factory; +// wasabi based services for localisation support +api_language *WASABI_API_LNG = 0; +HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0; + +HANDLE killswitch=0; +HANDLE playThread=0; + +const wchar_t *winampINI=0; +void Config(HWND hwndParent); +void About(HWND hwndParent); +wchar_t pluginName[256] = {0}; + +int Init() +{ + if (!IsWindow(plugin.hMainWindow)) + return IN_INIT_FAILURE; + + killswitch = CreateEvent(0, TRUE, FALSE, 0); + plugin.service->service_register(&albumArtFactory); + raw_factory.Register(plugin.service, &raw_media_reader_service); + mkv_factory.Register(plugin.service, &mkv_service); + + waServiceFactory *sf = (waServiceFactory *)plugin.service->service_getServiceByGuid(AgaveConfigGUID); + if (sf) AGAVE_API_CONFIG= (api_config *)sf->getInterface(); + sf = (waServiceFactory *)plugin.service->service_getServiceByGuid(memMgrApiServiceGuid); + if (sf) WASABI_API_MEMMGR= (api_memmgr *)sf->getInterface(); + + // loader so that we can get the localisation service api for use + sf = plugin.service->service_getServiceByGuid(languageApiGUID); + if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface()); + + // need to have this initialised before we try to do anything with localisation features + WASABI_API_START_LANG(plugin.hDllInstance,InFlacLangGUID); + + StringCchPrintfW(pluginName,256,WASABI_API_LNGSTRINGW(IDS_NULLSOFT_FLAC_DECODER),PLUGIN_VER); + plugin.description = (char*)pluginName; + + winampINI = (const wchar_t *)SendMessage(plugin.hMainWindow, WM_WA_IPC, 0, IPC_GETINIFILEW); + + wchar_t exts[1024] = {0}; + GetPrivateProfileStringW(L"in_flac", L"extensions", DEFAULT_EXTENSIONSW, exts, 1024, winampINI); + plugin.FileExtensions = BuildExtensions(AutoChar(exts)); + + config_average_bitrate = !!GetPrivateProfileIntW(L"in_flac", L"average_bitrate", 1, winampINI); + + plugin.UsesOutputPlug|=8; + return IN_INIT_SUCCESS; +} + +void Quit() +{ + CloseHandle(killswitch); + waServiceFactory *sf = (waServiceFactory *)plugin.service->service_getServiceByGuid(AgaveConfigGUID); + if (sf) sf->releaseInterface(AGAVE_API_CONFIG); + sf = (waServiceFactory *)plugin.service->service_getServiceByGuid(memMgrApiServiceGuid); + if (sf) sf->releaseInterface(WASABI_API_MEMMGR); + + plugin.service->service_deregister(&albumArtFactory); + raw_factory.Deregister(plugin.service); +} + +void GetFileInfo(const in_char *file, in_char *title, int *length_in_ms) +{ + if (length_in_ms) + { + if (!file || !*file && currentSongLength != -1000) + *length_in_ms = currentSongLength; + else + { + FLACMetadata metadata; + unsigned __int64 length_in_msec; + if (metadata.Open(file) && metadata.GetLengthMilliseconds(&length_in_msec)) + *length_in_ms = (int)length_in_msec; + else + *length_in_ms=-1000; + } + } + if (title) *title=0; +} + +int InfoBox(const in_char *file, HWND hwndParent) { return 0; } + +int IsOurFile(const in_char *fn) +{ + return 0; +} + +wchar_t *lastfn=0; +HANDLE threadStarted; +extern FLAC__uint64 lastoutputtime; +extern volatile int bufferCount; +int Play(const in_char *fn) +{ + free(lastfn); + lastfn=_wcsdup(fn); + currentSongLength=-1000; + plugin.is_seekable = 0; + plugin.SetInfo(0,0,0,0); + lastoutputtime=0; + bufferCount=0; + ResetEvent(killswitch); + DWORD threadId; + threadStarted = CreateEvent(0, TRUE, FALSE, 0); + + ReferenceCountedNXString filename_nx; + nx_uri_t filename_uri; + NXStringCreateWithUTF16(&filename_nx, fn); + NXURICreateWithNXString(&filename_uri, filename_nx); + + playThread=CreateThread(0, 0, FLACThread, filename_uri, 0, &threadId); + SetThreadPriority(playThread, AGAVE_API_CONFIG->GetInt(playbackConfigGroupGUID, L"priority", THREAD_PRIORITY_HIGHEST)); + WaitForSingleObject(threadStarted, INFINITE); + CloseHandle(threadStarted); + return 0; +} + +int localPause=0; +void Pause() +{ + localPause=1; + QueueUserAPC(APCPause, playThread, (ULONG_PTR)1); +} + +void UnPause() +{ + localPause=0; + QueueUserAPC(APCPause, playThread, (ULONG_PTR)0); +} + +int IsPaused() +{ + return localPause; +} + +void Stop() +{ + SetEvent(killswitch); + WaitForSingleObject(playThread, INFINITE); + currentSongLength=-1000; + plugin.outMod->Close(); + plugin.SAVSADeInit(); + free(lastfn); + lastfn=0; +} + +int GetLength() +{ + return currentSongLength; +} + + +int GetOutputTime() +{ + if (bufferCount) + return bufferCount; + + if (plugin.outMod) + { + return (int)lastoutputtime + (plugin.outMod->GetOutputTime() - plugin.outMod->GetWrittenTime()); + } + else + return 0; +} + +void SetOutputTime(int time_in_ms) +{ + lastoutputtime=time_in_ms; // cheating a bit here :) + QueueUserAPC(APCSeek, playThread, (ULONG_PTR)time_in_ms); +} + +int pan = 0, volume = -666; +void SetVolume(int _volume) +{ + volume = _volume; + if (plugin.outMod) + plugin.outMod->SetVolume(volume); +} + +void SetPan(int _pan) +{ + pan = _pan; + if (plugin.outMod) + plugin.outMod->SetPan(pan); +} + +void EQSet(int on, char data[10], int preamp) +{} + +In_Module plugin = +{ + IN_VER_RET, + "nullsoft(in_flac.dll)", + 0, + 0, + "FLAC\0FLAC Files\0", + 1, + 1, + Config, + About, + Init, + Quit, + GetFileInfo, + InfoBox, + IsOurFile, + Play, + Pause, + UnPause, + IsPaused, + Stop, + GetLength, + GetOutputTime, + SetOutputTime, + SetVolume, + SetPan, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + EQSet, + 0, + 0 +}; + +extern "C" __declspec(dllexport) In_Module * winampGetInModule2() +{ + return &plugin; +}
\ No newline at end of file |