mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 15:15:40 +00:00
dep/libchdr: Update to a03e693
This commit is contained in:
parent
ef6e18a1b2
commit
6b8486674f
|
@ -1,4 +1,5 @@
|
|||
add_library(libchdr
|
||||
include/dr_libs/dr_flac.h
|
||||
include/libchdr/bitstream.h
|
||||
include/libchdr/cdrom.h
|
||||
include/libchdr/chd.h
|
||||
|
|
12365
dep/libchdr/include/dr_libs/dr_flac.h
Normal file
12365
dep/libchdr/include/dr_libs/dr_flac.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -347,7 +347,7 @@ struct _chd_verify_result
|
|||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _MSC_VER
|
||||
#ifdef CHD_DLL
|
||||
#ifdef CHD_DLL_EXPORTS
|
||||
#define CHD_EXPORT __declspec(dllexport)
|
||||
|
@ -355,7 +355,6 @@ struct _chd_verify_result
|
|||
#define CHD_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
// Static library.
|
||||
#define CHD_EXPORT
|
||||
#endif
|
||||
#else
|
||||
|
@ -393,6 +392,8 @@ CHD_EXPORT const char *chd_error_string(chd_error err);
|
|||
/* return a pointer to the extracted CHD header data */
|
||||
CHD_EXPORT const chd_header *chd_get_header(chd_file *chd);
|
||||
|
||||
/* read CHD header data from file into the pointed struct */
|
||||
CHD_EXPORT chd_error chd_read_header(const char *filename, chd_header *header);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
/* Configure CHDR features here */
|
||||
#define WANT_RAW_DATA_SECTOR 1
|
||||
#define WANT_SUBCODE 0
|
||||
#define NEED_CACHE_HUNK 0
|
||||
#define VERIFY_BLOCK_CRC 0
|
||||
#define WANT_SUBCODE 1
|
||||
#define NEED_CACHE_HUNK 1
|
||||
#define VERIFY_BLOCK_CRC 1
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,12 +4,21 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
#ifdef USE_LIBRETRO_VFS
|
||||
#include <streams/file_stream_transforms.h>
|
||||
#endif
|
||||
|
||||
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
#if defined(__PS3__) || defined(__PSL1GHT__)
|
||||
#undef UINT32
|
||||
#undef UINT16
|
||||
#undef UINT8
|
||||
#undef INT32
|
||||
#undef INT16
|
||||
#undef INT8
|
||||
#endif
|
||||
|
||||
typedef uint64_t UINT64;
|
||||
typedef uint32_t UINT32;
|
||||
typedef uint16_t UINT16;
|
||||
|
@ -22,17 +31,33 @@ typedef int8_t INT8;
|
|||
|
||||
#define core_file FILE
|
||||
#define core_fopen(file) fopen(file, "rb")
|
||||
#define core_fseek fseek
|
||||
|
||||
#if defined USE_LIBRETRO_VFS
|
||||
#define core_fseek fseek
|
||||
#define core_ftell ftell
|
||||
#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WIN64__)
|
||||
#define core_fseek _fseeki64
|
||||
#define core_ftell _ftelli64
|
||||
#elif defined(_LARGEFILE_SOURCE) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
|
||||
#define core_fseek fseeko64
|
||||
#define core_ftell ftello64
|
||||
#elif defined(__PS3__) && !defined(__PSL1GHT__) || defined(__SWITCH__)
|
||||
#define core_fseek(x,y,z) fseek(x,(off_t)y,z)
|
||||
#define core_ftell(x) (off_t)ftell(x)
|
||||
#else
|
||||
#define core_fseek fseeko
|
||||
#define core_ftell ftello
|
||||
#endif
|
||||
#define core_fread(fc, buff, len) fread(buff, 1, len, fc)
|
||||
#define core_fclose fclose
|
||||
#define core_ftell ftell
|
||||
static inline size_t core_fsize(core_file *f)
|
||||
|
||||
static UINT64 core_fsize(core_file *f)
|
||||
{
|
||||
long rv;
|
||||
long p = ftell(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
rv = ftell(f);
|
||||
fseek(f, p, SEEK_SET);
|
||||
UINT64 rv;
|
||||
UINT64 p = core_ftell(f);
|
||||
core_fseek(f, 0, SEEK_END);
|
||||
rv = core_ftell(f);
|
||||
core_fseek(f, p, SEEK_SET);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#define __FLAC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <FLAC/all.h>
|
||||
|
||||
/***************************************************************************
|
||||
* TYPE DEFINITIONS
|
||||
|
@ -24,14 +23,14 @@
|
|||
typedef struct _flac_decoder flac_decoder;
|
||||
struct _flac_decoder {
|
||||
/* output state */
|
||||
FLAC__StreamDecoder* decoder; /* actual encoder */
|
||||
void * decoder; /* actual encoder */
|
||||
uint32_t sample_rate; /* decoded sample rate */
|
||||
uint8_t channels; /* decoded number of channels */
|
||||
uint8_t bits_per_sample; /* decoded bits per sample */
|
||||
uint32_t compressed_offset; /* current offset in compressed data */
|
||||
const FLAC__byte * compressed_start; /* start of compressed data */
|
||||
const uint8_t * compressed_start; /* start of compressed data */
|
||||
uint32_t compressed_length; /* length of compressed data */
|
||||
const FLAC__byte * compressed2_start; /* start of compressed data */
|
||||
const uint8_t * compressed2_start; /* start of compressed data */
|
||||
uint32_t compressed2_length; /* length of compressed data */
|
||||
int16_t * uncompressed_start[8]; /* pointer to start of uncompressed data (up to 8 streams) */
|
||||
uint32_t uncompressed_offset; /* current position in uncompressed data */
|
||||
|
@ -42,7 +41,7 @@ struct _flac_decoder {
|
|||
|
||||
/* ======================> flac_decoder */
|
||||
|
||||
void flac_decoder_init(flac_decoder* decoder);
|
||||
int flac_decoder_init(flac_decoder* decoder);
|
||||
void flac_decoder_free(flac_decoder* decoder);
|
||||
int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length);
|
||||
int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\msvc\vsprops\Configurations.props" />
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='DebugUWP' And '$(Configuration)'!='ReleaseUWP'">
|
||||
<ProjectReference Include="..\libFLAC\libFLAC.vcxproj">
|
||||
<Project>{97cbd3cb-cbc7-4d52-abde-f0ae7b794a5d}</Project>
|
||||
|
@ -13,7 +12,6 @@
|
|||
<Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\libchdr_bitstream.c" />
|
||||
<ClCompile Include="src\libchdr_cdrom.c" />
|
||||
|
@ -22,6 +20,7 @@
|
|||
<ClCompile Include="src\libchdr_huffman.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\dr_libs\dr_flac.h" />
|
||||
<ClInclude Include="include\libchdr\bitstream.h" />
|
||||
<ClInclude Include="include\libchdr\cdrom.h" />
|
||||
<ClInclude Include="include\libchdr\chd.h" />
|
||||
|
@ -30,13 +29,10 @@
|
|||
<ClInclude Include="include\libchdr\flac.h" />
|
||||
<ClInclude Include="include\libchdr\huffman.h" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{425D6C99-D1C8-43C2-B8AC-4D7B1D941017}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\msvc\vsprops\StaticLibrary.props" />
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
|
@ -44,6 +40,5 @@
|
|||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Import Project="..\msvc\vsprops\Targets.props" />
|
||||
</Project>
|
|
@ -15,5 +15,6 @@
|
|||
<ClInclude Include="include\libchdr\huffman.h" />
|
||||
<ClInclude Include="include\libchdr\bitstream.h" />
|
||||
<ClInclude Include="include\libchdr\cdrom.h" />
|
||||
<ClInclude Include="include\dr_libs\dr_flac.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -15,7 +15,7 @@
|
|||
schemes will differ after track 1!
|
||||
|
||||
***************************************************************************/
|
||||
#include <assert.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <libchdr/cdrom.h>
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
|
||||
#include "LzmaEnc.h"
|
||||
#include "LzmaDec.h"
|
||||
#if defined(__PS3__) || defined(__PSL1GHT__)
|
||||
#define __MACTYPES__
|
||||
#endif
|
||||
#include "zlib.h"
|
||||
|
||||
#undef TRUE
|
||||
|
@ -430,7 +433,7 @@ static void *lzma_fast_alloc(void *p, size_t size)
|
|||
addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
|
||||
if (addr==NULL)
|
||||
return NULL;
|
||||
for (int scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
||||
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
||||
{
|
||||
if (codec->allocptr[scan] == NULL)
|
||||
{
|
||||
|
@ -794,8 +797,7 @@ static chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes)
|
|||
#endif
|
||||
|
||||
/* flac decoder init */
|
||||
flac_decoder_init(&cdfl->decoder);
|
||||
if (cdfl->decoder.decoder == NULL)
|
||||
if (flac_decoder_init(&cdfl->decoder))
|
||||
return CHDERR_OUT_OF_MEMORY;
|
||||
|
||||
return CHDERR_NONE;
|
||||
|
@ -1161,7 +1163,7 @@ static inline int chd_compressed(chd_header* header) {
|
|||
static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
|
||||
{
|
||||
int result = 0;
|
||||
int hunknum;
|
||||
uint32_t hunknum;
|
||||
int repcount = 0;
|
||||
uint8_t lastcomp = 0;
|
||||
uint32_t last_self = 0;
|
||||
|
@ -1383,8 +1385,15 @@ CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent,
|
|||
EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
|
||||
|
||||
/* if we need a parent, make sure we have one */
|
||||
if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
|
||||
EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
|
||||
if (parent == NULL)
|
||||
{
|
||||
/* Detect parent requirement for versions below 5 */
|
||||
if (newchd->header.version < 5 && newchd->header.flags & CHDFLAGS_HAS_PARENT)
|
||||
EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
|
||||
/* Detection for version 5 and above - if parentsha1 != 0, we have a parent */
|
||||
else if (newchd->header.version >= 5 && memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
|
||||
EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
|
||||
}
|
||||
|
||||
/* make sure we have a valid parent */
|
||||
if (parent != NULL)
|
||||
|
@ -1561,6 +1570,12 @@ CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent,
|
|||
chd_error err;
|
||||
core_file *file = NULL;
|
||||
|
||||
if (filename == NULL)
|
||||
{
|
||||
err = CHDERR_INVALID_PARAMETER;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* choose the proper mode */
|
||||
switch(mode)
|
||||
{
|
||||
|
@ -1677,6 +1692,9 @@ CHD_EXPORT void chd_close(chd_file *chd)
|
|||
if (chd->file_cache)
|
||||
free(chd->file_cache);
|
||||
|
||||
if (chd->parent)
|
||||
chd_close(chd->parent);
|
||||
|
||||
/* free our memory */
|
||||
free(chd);
|
||||
}
|
||||
|
@ -1750,6 +1768,41 @@ CHD_EXPORT const chd_header *chd_get_header(chd_file *chd)
|
|||
return &chd->header;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
chd_read_header - read CHD header data
|
||||
from file into the pointed struct
|
||||
-------------------------------------------------*/
|
||||
CHD_EXPORT chd_error chd_read_header(const char *filename, chd_header *header)
|
||||
{
|
||||
chd_error err = CHDERR_NONE;
|
||||
chd_file chd;
|
||||
|
||||
/* punt if NULL */
|
||||
if (filename == NULL || header == NULL)
|
||||
EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
|
||||
|
||||
/* open the file */
|
||||
chd.file = core_fopen(filename);
|
||||
if (chd.file == NULL)
|
||||
EARLY_EXIT(err = CHDERR_FILE_NOT_FOUND);
|
||||
|
||||
/* attempt to read the header */
|
||||
err = header_read(&chd, header);
|
||||
if (err != CHDERR_NONE)
|
||||
EARLY_EXIT(err);
|
||||
|
||||
/* validate the header */
|
||||
err = header_validate(header);
|
||||
if (err != CHDERR_NONE)
|
||||
EARLY_EXIT(err);
|
||||
|
||||
cleanup:
|
||||
if (chd.file != NULL)
|
||||
core_fclose(chd.file);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
CORE DATA READ/WRITE
|
||||
***************************************************************************/
|
||||
|
@ -2124,9 +2177,9 @@ static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
|
|||
static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
size_t bytes;
|
||||
size_t bytes;
|
||||
#else
|
||||
ssize_t bytes;
|
||||
ssize_t bytes;
|
||||
#endif
|
||||
if (chd->file_cache != NULL)
|
||||
{
|
||||
|
@ -2344,13 +2397,33 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
|
|||
return hunk_read_into_memory(chd, blockoffs, dest);
|
||||
|
||||
case COMPRESSION_PARENT:
|
||||
#if 0
|
||||
/* TODO */
|
||||
if (m_parent_missing)
|
||||
if (chd->parent == NULL)
|
||||
return CHDERR_REQUIRES_PARENT;
|
||||
return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
|
||||
#endif
|
||||
return CHDERR_DECOMPRESSION_ERROR;
|
||||
UINT8 units_in_hunk = chd->header.hunkbytes / chd->header.unitbytes;
|
||||
|
||||
/* blockoffs is aligned to units_in_hunk */
|
||||
if (blockoffs % units_in_hunk == 0) {
|
||||
return hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, dest);
|
||||
/* blockoffs is not aligned to units_in_hunk */
|
||||
} else {
|
||||
UINT32 unit_in_hunk = blockoffs % units_in_hunk;
|
||||
UINT8 *buf = malloc(chd->header.hunkbytes);
|
||||
/* Read first half of hunk which contains blockoffs */
|
||||
err = hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, buf);
|
||||
if (err != CHDERR_NONE) {
|
||||
free(buf);
|
||||
return err;
|
||||
}
|
||||
memcpy(dest, buf + unit_in_hunk * chd->header.unitbytes, (units_in_hunk - unit_in_hunk) * chd->header.unitbytes);
|
||||
/* Read second half of hunk which contains blockoffs */
|
||||
err = hunk_read_into_memory(chd->parent, (blockoffs / units_in_hunk) + 1, buf);
|
||||
if (err != CHDERR_NONE) {
|
||||
free(buf);
|
||||
return err;
|
||||
}
|
||||
memcpy(dest + (units_in_hunk - unit_in_hunk) * chd->header.unitbytes, buf, unit_in_hunk * chd->header.unitbytes);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
return CHDERR_NONE;
|
||||
}
|
||||
|
@ -2375,7 +2448,7 @@ static chd_error map_read(chd_file *chd)
|
|||
UINT8 cookie[MAP_ENTRY_SIZE];
|
||||
UINT32 count;
|
||||
chd_error err;
|
||||
int i;
|
||||
UINT32 i;
|
||||
|
||||
/* first allocate memory */
|
||||
chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
|
||||
|
@ -2545,8 +2618,6 @@ static void zlib_codec_free(void *codec)
|
|||
/* deinit the streams */
|
||||
if (data != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
inflateEnd(&data->inflater);
|
||||
|
||||
/* free our fast memory */
|
||||
|
|
|
@ -8,40 +8,37 @@
|
|||
|
||||
***************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libchdr/flac.h>
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#define DR_FLAC_NO_STDIO
|
||||
#include <dr_libs/dr_flac.h>
|
||||
|
||||
/***************************************************************************
|
||||
* FLAC DECODER
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
static FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes);
|
||||
static void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
||||
static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
|
||||
static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void* client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
|
||||
static void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
|
||||
static size_t flac_decoder_read_callback(void *userdata, void *buffer, size_t bytes);
|
||||
static drflac_bool32 flac_decoder_seek_callback(void *userdata, int offset, drflac_seek_origin origin);
|
||||
static void flac_decoder_metadata_callback(void *userdata, drflac_metadata *metadata);
|
||||
static void flac_decoder_write_callback(void *userdata, void *buffer, size_t bytes);
|
||||
|
||||
|
||||
/* getters (valid after reset) */
|
||||
static uint32_t sample_rate(flac_decoder *decoder) { return decoder->sample_rate; }
|
||||
static uint8_t channels(flac_decoder *decoder) { return decoder->channels; }
|
||||
static uint8_t bits_per_sample(flac_decoder *decoder) { return decoder->bits_per_sample; }
|
||||
static uint32_t total_samples(flac_decoder *decoder) { return FLAC__stream_decoder_get_total_samples(decoder->decoder); }
|
||||
static FLAC__StreamDecoderState state(flac_decoder *decoder) { return FLAC__stream_decoder_get_state(decoder->decoder); }
|
||||
static const char *state_string(flac_decoder *decoder) { return FLAC__stream_decoder_get_resolved_state_string(decoder->decoder); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flac_decoder - constructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_init(flac_decoder *decoder)
|
||||
int flac_decoder_init(flac_decoder *decoder)
|
||||
{
|
||||
decoder->decoder = FLAC__stream_decoder_new();
|
||||
decoder->decoder = NULL;
|
||||
decoder->sample_rate = 0;
|
||||
decoder->channels = 0;
|
||||
decoder->bits_per_sample = 0;
|
||||
|
@ -53,6 +50,7 @@ void flac_decoder_init(flac_decoder *decoder)
|
|||
decoder->uncompressed_offset = 0;
|
||||
decoder->uncompressed_length = 0;
|
||||
decoder->uncompressed_swap = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -63,7 +61,8 @@ void flac_decoder_init(flac_decoder *decoder)
|
|||
void flac_decoder_free(flac_decoder* decoder)
|
||||
{
|
||||
if ((decoder != NULL) && (decoder->decoder != NULL))
|
||||
FLAC__stream_decoder_delete(decoder->decoder);
|
||||
drflac_close(decoder->decoder);
|
||||
decoder->decoder = NULL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -75,17 +74,11 @@ void flac_decoder_free(flac_decoder* decoder)
|
|||
static int flac_decoder_internal_reset(flac_decoder* decoder)
|
||||
{
|
||||
decoder->compressed_offset = 0;
|
||||
if (FLAC__stream_decoder_init_stream(decoder->decoder,
|
||||
&flac_decoder_read_callback_static,
|
||||
NULL,
|
||||
&flac_decoder_tell_callback_static,
|
||||
NULL,
|
||||
NULL,
|
||||
&flac_decoder_write_callback_static,
|
||||
&flac_decoder_metadata_callback_static,
|
||||
&flac_decoder_error_callback_static, decoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
||||
return 0;
|
||||
return FLAC__stream_decoder_process_until_end_of_metadata(decoder->decoder);
|
||||
flac_decoder_free(decoder);
|
||||
decoder->decoder = drflac_open_with_metadata(
|
||||
flac_decoder_read_callback, flac_decoder_seek_callback,
|
||||
flac_decoder_metadata_callback, decoder, NULL);
|
||||
return (decoder->decoder != NULL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -114,16 +107,16 @@ int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
|
||||
};
|
||||
memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
|
||||
decoder->custom_header[0x08] = decoder->custom_header[0x0a] = block_size >> 8;
|
||||
decoder->custom_header[0x09] = decoder->custom_header[0x0b] = block_size & 0xff;
|
||||
decoder->custom_header[0x08] = decoder->custom_header[0x0a] = (block_size*num_channels) >> 8;
|
||||
decoder->custom_header[0x09] = decoder->custom_header[0x0b] = (block_size*num_channels) & 0xff;
|
||||
decoder->custom_header[0x12] = sample_rate >> 12;
|
||||
decoder->custom_header[0x13] = sample_rate >> 4;
|
||||
decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
|
||||
|
||||
/* configure the header ahead of the provided buffer */
|
||||
decoder->compressed_start = (const FLAC__byte *)(decoder->custom_header);
|
||||
decoder->compressed_start = (const uint8_t *)(decoder->custom_header);
|
||||
decoder->compressed_length = sizeof(decoder->custom_header);
|
||||
decoder->compressed2_start = (const FLAC__byte *)(buffer);
|
||||
decoder->compressed2_start = (const uint8_t *)(buffer);
|
||||
decoder->compressed2_length = length;
|
||||
return flac_decoder_internal_reset(decoder);
|
||||
}
|
||||
|
@ -143,43 +136,20 @@ int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uin
|
|||
decoder->uncompressed_length = num_samples;
|
||||
decoder->uncompressed_swap = swap_endian;
|
||||
|
||||
#define BUFFER 2352 /* bytes per CD audio sector */
|
||||
int16_t buffer[BUFFER];
|
||||
uint32_t buf_samples = BUFFER / channels(decoder);
|
||||
/* loop until we get everything we want */
|
||||
while (decoder->uncompressed_offset < decoder->uncompressed_length)
|
||||
if (!FLAC__stream_decoder_process_single(decoder->decoder))
|
||||
while (decoder->uncompressed_offset < decoder->uncompressed_length) {
|
||||
uint32_t frames = (num_samples < buf_samples ? num_samples : buf_samples);
|
||||
if (!drflac_read_pcm_frames_s16(decoder->decoder, frames, buffer))
|
||||
return 0;
|
||||
flac_decoder_write_callback(decoder, buffer, frames*sizeof(*buffer)*channels(decoder));
|
||||
num_samples -= frames;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*-------------------------------------------------
|
||||
* decode - decode to an multiple independent
|
||||
* data streams
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_endian)
|
||||
{
|
||||
/* make sure we don't have too many channels */
|
||||
int chans = channels();
|
||||
if (chans > ARRAY_LENGTH(m_uncompressed_start))
|
||||
return false;
|
||||
|
||||
/* configure the uncompressed buffer */
|
||||
memset(m_uncompressed_start, 0, sizeof(m_uncompressed_start));
|
||||
for (int curchan = 0; curchan < chans; curchan++)
|
||||
m_uncompressed_start[curchan] = samples[curchan];
|
||||
m_uncompressed_offset = 0;
|
||||
m_uncompressed_length = num_samples;
|
||||
m_uncompressed_swap = swap_endian;
|
||||
|
||||
/* loop until we get everything we want */
|
||||
while (m_uncompressed_offset < m_uncompressed_length)
|
||||
if (!FLAC__stream_decoder_process_single(m_decoder))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------
|
||||
* finish - finish up the decode
|
||||
*-------------------------------------------------
|
||||
|
@ -188,15 +158,21 @@ bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_end
|
|||
uint32_t flac_decoder_finish(flac_decoder* decoder)
|
||||
{
|
||||
/* get the final decoding position and move forward */
|
||||
FLAC__uint64 position = 0;
|
||||
FLAC__stream_decoder_get_decode_position(decoder->decoder, &position);
|
||||
FLAC__stream_decoder_finish(decoder->decoder);
|
||||
drflac *flac = decoder->decoder;
|
||||
uint64_t position = decoder->compressed_offset;
|
||||
|
||||
/* ugh... there's no function to obtain bytes used in drflac :-/ */
|
||||
position -= DRFLAC_CACHE_L2_LINES_REMAINING(&flac->bs) * sizeof(drflac_cache_t);
|
||||
position -= DRFLAC_CACHE_L1_BITS_REMAINING(&flac->bs) / 8;
|
||||
position -= flac->bs.unalignedByteCount;
|
||||
|
||||
/* adjust position if we provided the header */
|
||||
if (position == 0)
|
||||
return 0;
|
||||
if (decoder->compressed_start == (const FLAC__byte *)(decoder->custom_header))
|
||||
if (decoder->compressed_start == (const uint8_t *)(decoder->custom_header))
|
||||
position -= decoder->compressed_length;
|
||||
|
||||
flac_decoder_free(decoder);
|
||||
return position;
|
||||
}
|
||||
|
||||
|
@ -208,39 +184,31 @@ uint32_t flac_decoder_finish(flac_decoder* decoder)
|
|||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
|
||||
static size_t flac_decoder_read_callback(void *userdata, void *buffer, size_t bytes)
|
||||
{
|
||||
return flac_decoder_read_callback(client_data, buffer, bytes);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes)
|
||||
{
|
||||
flac_decoder* decoder = (flac_decoder*)client_data;
|
||||
|
||||
uint32_t expected = *bytes;
|
||||
flac_decoder* decoder = (flac_decoder*)userdata;
|
||||
uint8_t *dst = buffer;
|
||||
|
||||
/* copy from primary buffer first */
|
||||
uint32_t outputpos = 0;
|
||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length)
|
||||
if (outputpos < bytes && decoder->compressed_offset < decoder->compressed_length)
|
||||
{
|
||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
|
||||
memcpy(&buffer[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
|
||||
uint32_t bytes_to_copy = MIN(bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
|
||||
memcpy(&dst[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
|
||||
outputpos += bytes_to_copy;
|
||||
decoder->compressed_offset += bytes_to_copy;
|
||||
}
|
||||
|
||||
/* once we're out of that, copy from the secondary buffer */
|
||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
|
||||
if (outputpos < bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
|
||||
{
|
||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed2_length - (decoder->compressed_offset - decoder->compressed_length));
|
||||
memcpy(&buffer[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
|
||||
uint32_t bytes_to_copy = MIN(bytes - outputpos, decoder->compressed2_length - (decoder->compressed_offset - decoder->compressed_length));
|
||||
memcpy(&dst[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
|
||||
outputpos += bytes_to_copy;
|
||||
decoder->compressed_offset += bytes_to_copy;
|
||||
}
|
||||
*bytes = outputpos;
|
||||
|
||||
/* return based on whether we ran out of data */
|
||||
return (*bytes < expected) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
return outputpos;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -248,30 +216,18 @@ FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC
|
|||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||
static void flac_decoder_metadata_callback(void *userdata, drflac_metadata *metadata)
|
||||
{
|
||||
flac_decoder *fldecoder;
|
||||
flac_decoder *decoder = userdata;
|
||||
|
||||
/* ignore all but STREAMINFO metadata */
|
||||
if (metadata->type != FLAC__METADATA_TYPE_STREAMINFO)
|
||||
if (metadata->type != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO)
|
||||
return;
|
||||
|
||||
/* parse out the data we care about */
|
||||
fldecoder = (flac_decoder *)(client_data);
|
||||
fldecoder->sample_rate = metadata->data.stream_info.sample_rate;
|
||||
fldecoder->bits_per_sample = metadata->data.stream_info.bits_per_sample;
|
||||
fldecoder->channels = metadata->data.stream_info.channels;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* tell_callback - handle requests to find out
|
||||
* where in the input stream we are
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
|
||||
{
|
||||
*absolute_byte_offset = ((flac_decoder *)client_data)->compressed_offset;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
decoder->sample_rate = metadata->data.streaminfo.sampleRate;
|
||||
decoder->bits_per_sample = metadata->data.streaminfo.bitsPerSample;
|
||||
decoder->channels = metadata->data.streaminfo.channels;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -280,53 +236,67 @@ FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__Stre
|
|||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||
{
|
||||
return flac_decoder_write_callback(client_data, frame, buffer);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void *client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
|
||||
static void flac_decoder_write_callback(void *userdata, void *buffer, size_t bytes)
|
||||
{
|
||||
int sampnum, chan;
|
||||
int shift, blocksize;
|
||||
flac_decoder * decoder = (flac_decoder *)client_data;
|
||||
|
||||
assert(frame->header.channels == channels(decoder));
|
||||
flac_decoder * decoder = (flac_decoder *)userdata;
|
||||
int16_t *sampbuf = (int16_t *)buffer;
|
||||
int sampch = channels(decoder);
|
||||
uint32_t offset = decoder->uncompressed_offset;
|
||||
uint16_t usample;
|
||||
|
||||
/* interleaved case */
|
||||
shift = decoder->uncompressed_swap ? 8 : 0;
|
||||
blocksize = frame->header.blocksize;
|
||||
blocksize = bytes / (sampch * sizeof(sampbuf[0]));
|
||||
if (decoder->uncompressed_start[1] == NULL)
|
||||
{
|
||||
int16_t *dest = decoder->uncompressed_start[0] + decoder->uncompressed_offset * frame->header.channels;
|
||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
||||
for (chan = 0; chan < frame->header.channels; chan++)
|
||||
*dest++ = (int16_t)((((uint16_t)buffer[chan][sampnum]) << shift) | (((uint16_t)buffer[chan][sampnum]) >> shift));
|
||||
int16_t *dest = decoder->uncompressed_start[0] + offset * sampch;
|
||||
for (sampnum = 0; sampnum < blocksize && offset < decoder->uncompressed_length; sampnum++, offset++)
|
||||
for (chan = 0; chan < sampch; chan++) {
|
||||
usample = (uint16_t)*sampbuf++;
|
||||
*dest++ = (int16_t)((usample << shift) | (usample >> shift));
|
||||
}
|
||||
}
|
||||
|
||||
/* non-interleaved case */
|
||||
else
|
||||
{
|
||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
||||
for (chan = 0; chan < frame->header.channels; chan++)
|
||||
for (sampnum = 0; sampnum < blocksize && offset < decoder->uncompressed_length; sampnum++, offset++)
|
||||
for (chan = 0; chan < sampch; chan++) {
|
||||
usample = (uint16_t)*sampbuf++;
|
||||
if (decoder->uncompressed_start[chan] != NULL)
|
||||
decoder->uncompressed_start[chan][decoder->uncompressed_offset] = (int16_t) ( (((uint16_t)(buffer[chan][sampnum])) << shift) | ( ((uint16_t)(buffer[chan][sampnum])) >> shift) );
|
||||
decoder->uncompressed_start[chan][offset] = (int16_t) ((usample << shift) | (usample >> shift));
|
||||
}
|
||||
}
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
decoder->uncompressed_offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void flac_decoder::error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* error_callback - handle errors (ignore them)
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param decoder The decoder.
|
||||
* @param status The status.
|
||||
* @param [in,out] client_data If non-null, information describing the client.
|
||||
|
||||
/*-------------------------------------------------
|
||||
* seek_callback - handle seeks on the output
|
||||
* stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
static drflac_bool32 flac_decoder_seek_callback(void *userdata, int offset, drflac_seek_origin origin)
|
||||
{
|
||||
flac_decoder * decoder = (flac_decoder *)userdata;
|
||||
uint32_t length = decoder->compressed_length + decoder->compressed2_length;
|
||||
|
||||
if (origin == drflac_seek_origin_start) {
|
||||
uint32_t pos = offset;
|
||||
if (pos <= length) {
|
||||
decoder->compressed_offset = pos;
|
||||
return 1;
|
||||
}
|
||||
} else if (origin == drflac_seek_origin_current) {
|
||||
uint32_t pos = decoder->compressed_offset + offset;
|
||||
if (pos <= length) {
|
||||
decoder->compressed_offset = pos;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -181,7 +180,8 @@ uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* b
|
|||
|
||||
enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
int numbits, curnode;
|
||||
int numbits;
|
||||
uint32_t curnode;
|
||||
enum huffman_error error;
|
||||
|
||||
/* bits per entry depends on the maxbits */
|
||||
|
@ -247,7 +247,7 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
|
|||
int last = 0;
|
||||
int count = 0;
|
||||
int index;
|
||||
int curcode;
|
||||
uint32_t curcode;
|
||||
uint8_t rlefullbits = 0;
|
||||
uint32_t temp;
|
||||
enum huffman_error error;
|
||||
|
@ -317,7 +317,7 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
|
|||
|
||||
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
uint32_t lowerweight;
|
||||
uint32_t upperweight;
|
||||
/* compute the number of data items in the histogram */
|
||||
|
@ -381,7 +381,7 @@ static int huffman_tree_node_compare(const void *item1, const void *item2)
|
|||
|
||||
int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight)
|
||||
{
|
||||
int curcode;
|
||||
uint32_t curcode;
|
||||
int nextalloc;
|
||||
int listitems = 0;
|
||||
int maxbits = 0;
|
||||
|
@ -478,7 +478,8 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint
|
|||
|
||||
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder)
|
||||
{
|
||||
int curcode, codelen;
|
||||
uint32_t curcode;
|
||||
int codelen;
|
||||
uint32_t curstart = 0;
|
||||
/* build up a histogram of bit lengths */
|
||||
uint32_t bithisto[33] = { 0 };
|
||||
|
@ -519,7 +520,7 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode
|
|||
|
||||
void huffman_build_lookup_table(struct huffman_decoder* decoder)
|
||||
{
|
||||
int curcode;
|
||||
uint32_t curcode;
|
||||
/* iterate over all codes */
|
||||
for (curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue