aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Encoder/enc_flac
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Encoder/enc_flac')
-rw-r--r--Src/Plugins/Encoder/enc_flac/AudioCoderFlac.cpp203
-rw-r--r--Src/Plugins/Encoder/enc_flac/AudioCoderFlac.h29
-rw-r--r--Src/Plugins/Encoder/enc_flac/StreamFileWin32.cpp69
-rw-r--r--Src/Plugins/Encoder/enc_flac/StreamFileWin32.h18
-rw-r--r--Src/Plugins/Encoder/enc_flac/api__enc_flac.h10
-rw-r--r--Src/Plugins/Encoder/enc_flac/enc_flac2.rc119
-rw-r--r--Src/Plugins/Encoder/enc_flac/enc_flac2.sln56
-rw-r--r--Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj277
-rw-r--r--Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj.filters44
-rw-r--r--Src/Plugins/Encoder/enc_flac/main.cpp320
-rw-r--r--Src/Plugins/Encoder/enc_flac/resource.h24
-rw-r--r--Src/Plugins/Encoder/enc_flac/version.rc239
12 files changed, 1208 insertions, 0 deletions
diff --git a/Src/Plugins/Encoder/enc_flac/AudioCoderFlac.cpp b/Src/Plugins/Encoder/enc_flac/AudioCoderFlac.cpp
new file mode 100644
index 00000000..38bb124e
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/AudioCoderFlac.cpp
@@ -0,0 +1,203 @@
+#include "AudioCoderFlac.h"
+#include <bfc/platform/types.h>
+#include <FLAC/metadata.h>
+
+AudioCoderFlac::AudioCoderFlac(unsigned int nch, unsigned int bps, unsigned int samplerate, unsigned int compression)
+{
+ /* initialize stuff first so we can clean up safely if things go wrong */
+ finished = false;
+ finishedBytes = 0;
+ padding = 0;
+ encoder = 0;
+ win32State.bytesWritten = 0;
+ win32State.handle = INVALID_HANDLE_VALUE;
+ tempFile[0]=0;
+
+ wchar_t tempPath[MAX_PATH-14] = {0};
+ GetTempPath(MAX_PATH-14, tempPath);
+ GetTempFileName(tempPath, L"wfl", 0, tempFile);
+ win32State.handle = CreateFile(tempFile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+
+ if (win32State.handle != INVALID_HANDLE_VALUE)
+ {
+ this->nch = nch;
+ this->bps = bps;
+ encoder = FLAC__stream_encoder_new();
+
+ if (!encoder)
+ return;
+
+ // set stream info
+ if (!FLAC__stream_encoder_set_channels(encoder, nch)
+ || !FLAC__stream_encoder_set_bits_per_sample(encoder, bps)
+ || !FLAC__stream_encoder_set_sample_rate(encoder, samplerate)
+ || !FLAC__stream_encoder_set_total_samples_estimate(encoder, 0)
+ || !FLAC__stream_encoder_set_compression_level(encoder, compression)
+ || !FLAC__stream_encoder_set_blocksize(encoder, 0))
+ {
+ FLAC__stream_encoder_delete(encoder);
+ encoder=0;
+ return;
+ }
+ // TODO: set any more config stuff
+
+ // TODO: seektable?
+ //FLAC__StreamMetadata *seektable = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE);
+
+ padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
+ if (padding)
+ {
+ padding->length = 16384; // TODO: configurable padding size
+ if (!FLAC__stream_encoder_set_metadata(encoder, &padding, 1))
+ {
+ FLAC__stream_encoder_delete(encoder);
+ encoder=0;
+ return;
+ }
+ }
+
+ if (FLAC__stream_encoder_init_stream(encoder, Win32_Write, Win32_Seek, Win32_Tell, NULL, &win32State) != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
+ {
+ FLAC__stream_encoder_delete(encoder);
+ encoder=0;
+ return;
+ }
+ }
+}
+
+bool AudioCoderFlac::OK()
+{
+ if (!encoder)
+ return false;
+
+ return FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK;
+}
+
+AudioCoderFlac::~AudioCoderFlac()
+{
+ if (encoder)
+ FLAC__stream_encoder_delete(encoder);
+
+ if (padding)
+ FLAC__metadata_object_delete(padding);
+
+ if (win32State.handle != INVALID_HANDLE_VALUE)
+ CloseHandle(win32State.handle);
+
+}
+
+static void Copy8(FLAC__int32 *buffer, void *inputData, int numSamples)
+{
+ uint8_t *in = (uint8_t *)inputData;
+
+ for (int i=0;i<numSamples;i++)
+ {
+ buffer[i] = (FLAC__int32)in[i];
+ }
+}
+
+static void Copy16(FLAC__int32 *buffer, void *inputData, int numSamples)
+{
+ int16_t *in = (int16_t *)inputData;
+
+ for (int i=0;i<numSamples;i++)
+ {
+ buffer[i] = (FLAC__int32)in[i];
+ }
+}
+
+static void Copy24(FLAC__int32 *buffer, void *inputData, int numSamples)
+{
+ uint8_t *in = (uint8_t *)inputData;
+
+ for (int i=0;i<numSamples;i++)
+ {
+ FLAC__int32 val = (((FLAC__int32)in[0]) << 0);
+ val = val | (((FLAC__int32)in[1]) << 8);
+ val = val | (((FLAC__int32)in[2]) << 16);
+
+ buffer[i] = (FLAC__int32)val;
+ in+=3;
+ }
+}
+
+static void Copy32(FLAC__int32 *buffer, void *inputData, int numSamples)
+{
+ int32_t *in = (int32_t *)inputData;
+
+ for (int i=0;i<numSamples;i++)
+ {
+ buffer[i] = (FLAC__int32)in[i];
+ }
+}
+
+int AudioCoderFlac::Encode(int framepos, void *in, int in_avail, int *in_used, void *out, int out_avail)
+{
+ FLAC__int32 buffer[65536];
+
+
+ FLAC__uint64 startBytes = win32State.bytesWritten;
+
+ if (!in_avail)
+ {
+ if (finished)
+ {
+ int ret = (int)finishedBytes;
+ finishedBytes = 0;
+ return ret;
+ }
+ return 0;
+ }
+
+
+ int numSamples = in_avail/(bps/8);
+
+ if (numSamples>65536)
+ numSamples = 65536;
+
+ switch (bps)
+ {
+ case 8:
+ Copy8(buffer, in, numSamples);
+ break;
+ case 16:
+ Copy16(buffer, in, numSamples);
+ break;
+ case 24:
+ Copy24(buffer, in, numSamples);
+ break;
+ case 32:
+ Copy32(buffer, in, numSamples);
+ break;
+ }
+
+ FLAC__bool result = FLAC__stream_encoder_process_interleaved(encoder, buffer, numSamples/nch);
+
+ if (result)
+ {
+ *in_used = numSamples*(bps/8);
+ return (int)(win32State.bytesWritten - startBytes);
+ }
+
+ return 0;
+}
+
+void AudioCoderFlac::PrepareToFinish()
+{
+ FLAC__uint64 startBytes = win32State.bytesWritten;
+ FLAC__stream_encoder_finish(encoder);
+ finishedBytes = win32State.bytesWritten - startBytes;
+}
+
+void AudioCoderFlac::Finish(const wchar_t *destination)
+{
+ if (win32State.handle != INVALID_HANDLE_VALUE)
+ CloseHandle(win32State.handle);
+
+ win32State.handle = INVALID_HANDLE_VALUE;
+ if (!MoveFile(tempFile, destination))
+ {
+ if (CopyFile(tempFile, destination, FALSE))
+ DeleteFile(tempFile);
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/Encoder/enc_flac/AudioCoderFlac.h b/Src/Plugins/Encoder/enc_flac/AudioCoderFlac.h
new file mode 100644
index 00000000..e28eba96
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/AudioCoderFlac.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "../nsv/enc_if.h"
+#include <FLAC/stream_encoder.h>
+#include "StreamFileWin32.h"
+
+typedef struct {
+ unsigned int compression; // 0-8
+} configtype;
+
+class AudioCoderFlac : public AudioCoder
+{
+public:
+ AudioCoderFlac(unsigned int nch, unsigned int bps, unsigned int samplerate, unsigned int compression);
+ ~AudioCoderFlac();
+ int Encode(int framepos, void *in, int in_avail, int *in_used, void *out, int out_avail); //returns bytes in out
+ void PrepareToFinish();
+ void Finish(const wchar_t *destination);
+ bool OK();
+
+private:
+ FLAC__StreamEncoder *encoder;
+ FLAC__StreamMetadata *padding;
+ Win32_State win32State;
+ unsigned int nch;
+ unsigned int bps;
+ wchar_t tempFile[MAX_PATH];
+ bool finished;
+ FLAC__uint64 finishedBytes;
+}; \ No newline at end of file
diff --git a/Src/Plugins/Encoder/enc_flac/StreamFileWin32.cpp b/Src/Plugins/Encoder/enc_flac/StreamFileWin32.cpp
new file mode 100644
index 00000000..04c152dd
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/StreamFileWin32.cpp
@@ -0,0 +1,69 @@
+#include "StreamFileWin32.h"
+#include <assert.h>
+
+static __int64 Seek64(HANDLE hf, __int64 distance, DWORD MoveMethod)
+{
+ LARGE_INTEGER li;
+
+ li.QuadPart = distance;
+
+ li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);
+
+ if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
+ {
+ li.QuadPart = -1;
+ }
+
+ return li.QuadPart;
+}
+
+
+FLAC__StreamEncoderWriteStatus Win32_Write(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
+{
+ assert(bytes <= 4294967295U);
+
+ HANDLE file = ((Win32_State *)client_data)->handle;
+ if(bytes > 0)
+ {
+ assert(sizeof(FLAC__byte) == 1);
+ DWORD bytesWritten = 0, bytesToWrite = (DWORD)bytes;
+ BOOL result = WriteFile(file, buffer, bytesToWrite, &bytesWritten, NULL);
+ ((Win32_State *)client_data)->bytesWritten += bytesWritten;
+
+ if (!result)
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+ }
+ else
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+}
+
+FLAC__StreamEncoderSeekStatus Win32_Seek(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+{
+ HANDLE file = ((Win32_State *)client_data)->handle;
+
+ __int64 result = Seek64(file, absolute_byte_offset, FILE_BEGIN);
+
+ if (result == INVALID_SET_FILE_POINTER)
+ return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
+ else
+ {
+ return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
+ }
+}
+
+FLAC__StreamEncoderTellStatus Win32_Tell(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+{
+ HANDLE file = ((Win32_State *)client_data)->handle;
+
+ __int64 position = Seek64(file, 0, FILE_CURRENT);
+
+ if (position == INVALID_SET_FILE_POINTER)
+ return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
+ else
+ {
+ *absolute_byte_offset=position;
+ return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
+ }
+}
+
diff --git a/Src/Plugins/Encoder/enc_flac/StreamFileWin32.h b/Src/Plugins/Encoder/enc_flac/StreamFileWin32.h
new file mode 100644
index 00000000..6c09bc46
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/StreamFileWin32.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <FLAC/all.h>
+#include <windows.h>
+
+struct Win32_State
+{
+public:
+ HANDLE handle;
+ FLAC__uint64 bytesWritten;
+};
+
+FLAC__StreamEncoderWriteStatus Win32_Write(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
+FLAC__StreamEncoderSeekStatus Win32_Seek(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+FLAC__StreamEncoderTellStatus Win32_Tell(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+void Progress(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
+
+
diff --git a/Src/Plugins/Encoder/enc_flac/api__enc_flac.h b/Src/Plugins/Encoder/enc_flac/api__enc_flac.h
new file mode 100644
index 00000000..2b62bfb4
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/api__enc_flac.h
@@ -0,0 +1,10 @@
+#ifndef NULLSOFT_ENC_FLAC_API_H
+#define NULLSOFT_ENC_FLAC_API_H
+
+#include "api/service/api_service.h"
+#include "../Agave/Language/api_language.h"
+
+#include "api/application/api_application.h"
+#define WASABI_API_APP application
+
+#endif // !NULLSOFT_ENC_FLAC_API_H
diff --git a/Src/Plugins/Encoder/enc_flac/enc_flac2.rc b/Src/Plugins/Encoder/enc_flac/enc_flac2.rc
new file mode 100644
index 00000000..adb678f3
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/enc_flac2.rc
@@ -0,0 +1,119 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_CONFIG DIALOGEX 0, 0, 256, 167
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "FLAC Encoder Options",IDC_STATIC,0,0,256,166
+ LTEXT "Compression factor:",IDC_STATIC,7,13,66,8
+ CONTROL "",IDC_COMPRESSIONSLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOOLTIPS | WS_TABSTOP,5,23,243,17
+ LTEXT "Fast Encoding",IDC_STATIC,9,43,46,8
+ LTEXT "Best Compression",IDC_STATIC,191,43,58,8
+ LTEXT "FLAC is the Free Lossless Audio Codec, ",IDC_STATIC,5,143,128,8
+ CONTROL "http://flac.sf.net/",IDC_URL,"Button",BS_OWNERDRAW | WS_TABSTOP,131,142,62,9
+ LTEXT "",IDC_STATIC_FLAC_VER,5,151,242,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_CONFIG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_LIBFLAC_DLL_MISSING "[libflac.dll missing]"
+ IDS_ENC_FLAC_DESC "FLAC Encoder v%s (libFLAC v%s)"
+END
+
+STRINGTABLE
+BEGIN
+ 65535 "{73760073-560C-433b-BC59-3FCC94CDEA4A}"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Encoder/enc_flac/enc_flac2.sln b/Src/Plugins/Encoder/enc_flac/enc_flac2.sln
new file mode 100644
index 00000000..fd840cc5
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/enc_flac2.sln
@@ -0,0 +1,56 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29613.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "enc_flac", "enc_flac2.vcxproj", "{922008CC-4A0E-4EA1-92F2-AA822965BDF6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4FC28B55-2A14-43D5-86F7-201054F338A9} = {4FC28B55-2A14-43D5-86F7-201054F338A9}
+ {4CEFBC83-C215-11DB-8314-0800200C9A66} = {4CEFBC83-C215-11DB-8314-0800200C9A66}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libFLAC_dynamic", "..\libFLAC\libFLAC_dynamic.vcxproj", "{4CEFBC83-C215-11DB-8314-0800200C9A66}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4FC28B55-2A14-43D5-86F7-201054F338A9} = {4FC28B55-2A14-43D5-86F7-201054F338A9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libogg", "..\libogg\libogg.vcxproj", "{4FC28B55-2A14-43D5-86F7-201054F338A9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {922008CC-4A0E-4EA1-92F2-AA822965BDF6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {922008CC-4A0E-4EA1-92F2-AA822965BDF6}.Debug|Win32.Build.0 = Debug|Win32
+ {922008CC-4A0E-4EA1-92F2-AA822965BDF6}.Debug|x64.ActiveCfg = Debug|x64
+ {922008CC-4A0E-4EA1-92F2-AA822965BDF6}.Release|Win32.ActiveCfg = Release|Win32
+ {922008CC-4A0E-4EA1-92F2-AA822965BDF6}.Release|Win32.Build.0 = Release|Win32
+ {922008CC-4A0E-4EA1-92F2-AA822965BDF6}.Release|x64.ActiveCfg = Release|x64
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Debug|x64.Build.0 = Debug|x64
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|Win32.Build.0 = Release|Win32
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|x64.ActiveCfg = Release|x64
+ {4CEFBC83-C215-11DB-8314-0800200C9A66}.Release|x64.Build.0 = Release|x64
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|Win32.Build.0 = Debug|Win32
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|x64.ActiveCfg = Debug|x64
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|x64.Build.0 = Debug|x64
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|Win32.ActiveCfg = Release|Win32
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|Win32.Build.0 = Release|Win32
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|x64.ActiveCfg = Release|x64
+ {4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A0F24E75-21BB-4DDF-A287-A481B554B4EB}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj b/Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj
new file mode 100644
index 00000000..b937baea
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>enc_flac</ProjectName>
+ <ProjectGuid>{922008CC-4A0E-4EA1-92F2-AA822965BDF6}</ProjectGuid>
+ <RootNamespace>enc_flac</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ENC_FLAC2_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>uxtheme.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;ENC_FLAC2_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>uxtheme.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ENC_FLAC2_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>uxtheme.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;ENC_FLAC2_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>uxtheme.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="api__enc_flac.h" />
+ <ClInclude Include="AudioCoderFlac.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="StreamFileWin32.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="AudioCoderFlac.cpp" />
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="StreamFileWin32.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="enc_flac2.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj.filters b/Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj.filters
new file mode 100644
index 00000000..41b6f1a1
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/enc_flac2.vcxproj.filters
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="AudioCoderFlac.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="StreamFileWin32.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="StreamFileWin32.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="AudioCoderFlac.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="api__enc_flac.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{c641c9a9-b7d5-4744-bd44-2edc534f2425}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{63979e7c-4d4b-4fc2-89c6-3f476c40adfe}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{cc58b311-a8ed-4e0e-852b-cc82f0d2a83e}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="enc_flac2.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Encoder/enc_flac/main.cpp b/Src/Plugins/Encoder/enc_flac/main.cpp
new file mode 100644
index 00000000..d0507c59
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/main.cpp
@@ -0,0 +1,320 @@
+#include "api__enc_flac.h"
+#include "../Winamp/wa_ipc.h"
+#include "../nsv/enc_if.h"
+#include "../nu/AutoWideFn.h"
+#include "AudioCoderFlac.h"
+#include "resource.h"
+#include <commctrl.h>
+#include <windows.h>
+#include <Uxtheme.h>
+#include <api/service/waservicefactory.h>
+#include <api/application/api_application.h>
+#include <mmsystem.h>
+#include <strsafe.h>
+
+#define ENC_VERSION "2.46"
+
+HWND winampwnd = 0;
+int isthemethere = 0;
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+api_application *WASABI_API_APP = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+typedef struct
+{
+ configtype cfg;
+ char configfile[MAX_PATH];
+}
+configwndrec;
+
+void readconfig(const char *configfile, configtype *cfg)
+{
+ if (configfile)
+ {
+ cfg->compression = GetPrivateProfileIntA("audio_flac", "compression", 5, configfile);
+ }
+ else
+ {
+ cfg->compression = 5;
+ }
+}
+
+void writeconfig(const char *configfile, configtype *cfg)
+{
+ if (configfile)
+ {
+ char str[64] = {0};
+ StringCchPrintfA(str, 64, "%u", cfg->compression);
+ WritePrivateProfileStringA("audio_flac", "compression", str, configfile);
+ }
+}
+
+static HINSTANCE GetMyInstance()
+{
+ MEMORY_BASIC_INFORMATION mbi = {0};
+ if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
+ return (HINSTANCE)mbi.AllocationBase;
+ return NULL;
+}
+
+void GetLocalisationApiService(void)
+{
+ if(!WASABI_API_LNG)
+ {
+ // loader so that we can get the localisation service api for use
+ if(!WASABI_API_SVC)
+ {
+ WASABI_API_SVC = (api_service*)SendMessage(winampwnd, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1)
+ {
+ WASABI_API_SVC = NULL;
+ return;
+ }
+ }
+
+ if(!WASABI_API_APP)
+ {
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf) WASABI_API_APP = reinterpret_cast<api_application*>(sf->getInterface());
+ }
+
+ if(!WASABI_API_LNG)
+ {
+ waServiceFactory *sf = WASABI_API_SVC->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(GetMyInstance(),EncFlacLangGUID);
+ }
+}
+
+static const char *GetFLACVersion()
+{
+ return "1.4.2";
+}
+
+static HCURSOR link_hand_cursor;
+LRESULT link_handlecursor(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT ret = CallWindowProcW((WNDPROC)GetPropW(hwndDlg, L"link_proc"), hwndDlg, uMsg, wParam, lParam);
+ // override the normal cursor behaviour so we have a hand to show it is a link
+ if(uMsg == WM_SETCURSOR)
+ {
+ if((HWND)wParam == hwndDlg)
+ {
+ if(!link_hand_cursor)
+ {
+ link_hand_cursor = LoadCursor(NULL, IDC_HAND);
+ }
+ SetCursor(link_hand_cursor);
+ return TRUE;
+ }
+ }
+ return ret;
+}
+
+void link_handledraw(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_DRAWITEM)
+ {
+ DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam;
+ if (di->CtlType == ODT_BUTTON)
+ {
+ wchar_t wt[123] = {0};
+ int y;
+ RECT r;
+ HPEN hPen, hOldPen;
+ GetDlgItemTextW(hwndDlg, (int)wParam, wt, sizeof(wt)/sizeof(wt[0]));
+
+ // due to the fun of theming and owner drawing we have to get the background colour
+ if(isthemethere){
+ HTHEME hTheme = OpenThemeData(hwndDlg, L"Tab");
+ if (hTheme) {
+ DrawThemeParentBackground(di->hwndItem, di->hDC, &di->rcItem);
+ CloseThemeData(hTheme);
+ }
+ }
+
+ // draw text
+ SetTextColor(di->hDC, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220));
+ r = di->rcItem;
+ r.left += 2;
+ DrawTextW(di->hDC, wt, -1, &r, DT_VCENTER | DT_SINGLELINE);
+
+ memset(&r, 0, sizeof(r));
+ DrawTextW(di->hDC, wt, -1, &r, DT_SINGLELINE | DT_CALCRECT);
+
+ // draw underline
+ y = di->rcItem.bottom - ((di->rcItem.bottom - di->rcItem.top) - (r.bottom - r.top)) / 2 - 1;
+ hPen = CreatePen(PS_SOLID, 0, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220));
+ hOldPen = (HPEN) SelectObject(di->hDC, hPen);
+ MoveToEx(di->hDC, di->rcItem.left + 2, y, NULL);
+ LineTo(di->hDC, di->rcItem.right + 2 - ((di->rcItem.right - di->rcItem.left) - (r.right - r.left)), y);
+ SelectObject(di->hDC, hOldPen);
+ DeleteObject(hPen);
+ }
+ }
+}
+
+void link_startsubclass(HWND hwndDlg, UINT id)
+{
+HWND ctrl = GetDlgItem(hwndDlg, id);
+ if(!GetPropW(ctrl, L"link_proc"))
+ {
+ SetPropW(ctrl, L"link_proc",
+ (HANDLE)SetWindowLongPtrW(ctrl, GWLP_WNDPROC, (LONG_PTR)link_handlecursor));
+ }
+}
+
+BOOL CALLBACK DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static configwndrec *wr;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ wr = (configwndrec *)lParam;
+ SendMessage(GetDlgItem(hwndDlg,IDC_COMPRESSIONSLIDER),TBM_SETRANGE,TRUE,MAKELONG(0,8));
+ SendMessage(GetDlgItem(hwndDlg,IDC_COMPRESSIONSLIDER),TBM_SETPOS,TRUE,wr->cfg.compression);
+ const char *libFlacVer = GetFLACVersion();
+ if (libFlacVer && *libFlacVer)
+ {
+ char flac_string[1024] = {0};
+ StringCchPrintfA(flac_string, 1024, "libFLAC v%s",libFlacVer);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_FLAC_VER, flac_string);
+ }
+ link_startsubclass(hwndDlg, IDC_URL);
+ }
+ break;
+
+ case WM_COMMAND:
+ if(LOWORD(wParam) == IDC_URL)
+ {
+ SendMessage(winampwnd, WM_WA_IPC, (WPARAM)"http://flac.sf.net/", IPC_OPEN_URL);
+ }
+ break;
+
+ case WM_NOTIFY:
+ if(wParam == IDC_COMPRESSIONSLIDER)
+ {
+ LPNMHDR l = (LPNMHDR)lParam;
+ if(l->idFrom == IDC_COMPRESSIONSLIDER)
+ wr->cfg.compression = (unsigned int)SendMessage(GetDlgItem(hwndDlg,IDC_COMPRESSIONSLIDER),TBM_GETPOS,0,0);
+ }
+ break;
+
+ case WM_DESTROY:
+ writeconfig(wr->configfile,&wr->cfg);
+ free(wr); wr=NULL;
+ break;
+ }
+
+ const int controls[] =
+ {
+ IDC_COMPRESSIONSLIDER,
+ };
+ if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam, controls, ARRAYSIZE(controls)))
+ {
+ return TRUE;
+ }
+
+ link_handledraw(hwndDlg,uMsg,wParam,lParam);
+ return 0;
+}
+
+extern "C"
+{
+ unsigned int __declspec(dllexport) GetAudioTypes3(int idx, char *desc)
+ {
+ if (idx == 0)
+ {
+ GetLocalisationApiService();
+ const char *libFlacVer = GetFLACVersion();
+ StringCchPrintfA(desc, 1024, WASABI_API_LNGSTRING(IDS_ENC_FLAC_DESC), ENC_VERSION, libFlacVer);
+ return mmioFOURCC('F', 'L', 'A', 'C');
+ }
+ return 0;
+ }
+
+ AudioCoder __declspec(dllexport) *CreateAudio3(int nch, int srate, int bps, unsigned int srct, unsigned int *outt, char *configfile)
+ {
+ if (srct == mmioFOURCC('P', 'C', 'M', ' ') && *outt == mmioFOURCC('F', 'L', 'A', 'C'))
+ {
+ configtype cfg;
+ readconfig(configfile, &cfg);
+ *outt = mmioFOURCC('F', 'L', 'A', 'C');
+ AudioCoderFlac *t=new AudioCoderFlac(nch, bps, srate, cfg.compression);
+ if (!t->OK())
+ {
+ delete t;
+ return NULL;
+ }
+ return t;
+ }
+ return NULL;
+ }
+
+ void __declspec(dllexport) FinishAudio3(const char *filename, AudioCoder *coder)
+ {
+ ((AudioCoderFlac*)coder)->Finish(AutoWideFn(filename));
+ }
+
+ void __declspec(dllexport) FinishAudio3W(const wchar_t *filename, AudioCoder *coder)
+ {
+ ((AudioCoderFlac*)coder)->Finish(filename);
+ }
+
+ void __declspec(dllexport) PrepareToFinish(const char *filename, AudioCoder *coder)
+ {
+ ((AudioCoderFlac*)coder)->PrepareToFinish();
+ }
+
+ void __declspec(dllexport) PrepareToFinishW(const wchar_t *filename, AudioCoder *coder)
+ {
+ ((AudioCoderFlac*)coder)->PrepareToFinish();
+ }
+
+
+ HWND __declspec(dllexport) ConfigAudio3(HWND hwndParent, HINSTANCE hinst, unsigned int outt, char *configfile)
+ {
+ if (outt == mmioFOURCC('F', 'L', 'A', 'C'))
+ {
+ configwndrec *wr = (configwndrec*)malloc(sizeof(configwndrec));
+ if (configfile) StringCchCopyA(wr->configfile, MAX_PATH, configfile);
+ else wr->configfile[0] = 0;
+ readconfig(configfile, &wr->cfg);
+ GetLocalisationApiService();
+ return WASABI_API_CREATEDIALOGPARAMW(IDD_CONFIG, hwndParent, DlgProc, (LPARAM)wr);
+ }
+ return NULL;
+ }
+
+ int __declspec(dllexport) SetConfigItem(unsigned int outt, char *item, char *data, char *configfile)
+ {
+ // nothing yet
+ return 0;
+ }
+
+ int __declspec(dllexport) GetConfigItem(unsigned int outt, char *item, char *data, int len, char *configfile)
+ {
+ if (outt == mmioFOURCC('F', 'L', 'A', 'C'))
+ {
+ /*
+ configtype cfg;
+ readconfig(configfile, &cfg);
+ */
+ if (!_stricmp(item, "bitrate")) StringCchCopyA(data, len, "755"); // FUCKO: this is ment to be an estimate for approximations of output filesize (used by ml_pmp). Improve this.
+ else if (!_stricmp(item,"extension")) StringCchCopyA(data, len, "flac");
+ return 1;
+ }
+ return 0;
+ }
+
+ void __declspec(dllexport) SetWinampHWND(HWND hwnd)
+ {
+ winampwnd = hwnd;
+ isthemethere = !SendMessage(hwnd,WM_WA_IPC,IPC_ISWINTHEMEPRESENT,IPC_USE_UXTHEME_FUNC);
+ }
+}; \ No newline at end of file
diff --git a/Src/Plugins/Encoder/enc_flac/resource.h b/Src/Plugins/Encoder/enc_flac/resource.h
new file mode 100644
index 00000000..6d233f22
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/resource.h
@@ -0,0 +1,24 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by enc_flac2.rc
+//
+#define IDD_CONFIG 9
+#define IDS_LIBFLAC_DLL_MISSING 102
+#define IDS_STRING103 103
+#define IDS_ENC_FLAC_DESC 103
+#define IDC_SLIDER1 1001
+#define IDC_COMPRESSIONSLIDER 1001
+#define IDC_STATIC_FLAC_VER 1002
+#define IDC_BUTTON1 1003
+#define IDC_URL 1003
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1004
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/Encoder/enc_flac/version.rc2 b/Src/Plugins/Encoder/enc_flac/version.rc2
new file mode 100644
index 00000000..6bc10f30
--- /dev/null
+++ b/Src/Plugins/Encoder/enc_flac/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,46,0,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Encoder Plug-in"
+ VALUE "FileVersion", "2,46,0,0"
+ VALUE "InternalName", "Nullsoft FLAC Encoder"
+ VALUE "LegalCopyright", "Copyright © 2006-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "enc_flac.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END