Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
203
Src/Plugins/Encoder/enc_flac/AudioCoderFlac.cpp
Normal file
203
Src/Plugins/Encoder/enc_flac/AudioCoderFlac.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue