mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 11:18:31 +01:00
cleanup: separate some util.h functions
also avoid include useless functions when possible (faster compiles)
This commit is contained in:
parent
f70b9cf7e6
commit
4bc3f1365d
@ -39,7 +39,7 @@
|
||||
|
||||
#include "../src/vgmstream.h"
|
||||
#include "../src/plugins.h"
|
||||
|
||||
#include "../src/util/samples_ops.h"
|
||||
|
||||
#include "../version.h"
|
||||
#ifndef VGMSTREAM_VERSION
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../src/vgmstream.h"
|
||||
#include "../src/plugins.h"
|
||||
#include "../src/util.h"
|
||||
#include "../src/util/samples_ops.h"
|
||||
//todo use <>?
|
||||
#ifdef HAVE_JSON
|
||||
#include "jansson/jansson.h"
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _CODING_H
|
||||
|
||||
#include "../vgmstream.h"
|
||||
#include "../util/reader_get_nibbles.h"
|
||||
//todo remove
|
||||
#include "hca_decoder_clhca.h"
|
||||
|
||||
|
@ -988,6 +988,19 @@ STREAMFILE* open_multifile_streamfile_f(STREAMFILE** sfs, size_t sfs_size) {
|
||||
|
||||
/* **************************************************** */
|
||||
|
||||
/* change pathname's extension to another (or add it if extensionless) */
|
||||
static void swap_extension(char* pathname, /*size_t*/ int pathname_len, const char* swap) {
|
||||
char* extension = (char*)filename_extension(pathname);
|
||||
//todo safeops
|
||||
if (extension[0] == '\0') {
|
||||
strcat(pathname, ".");
|
||||
strcat(pathname, swap);
|
||||
}
|
||||
else {
|
||||
strcpy(extension, swap);
|
||||
}
|
||||
}
|
||||
|
||||
STREAMFILE* open_streamfile(STREAMFILE* sf, const char* pathname) {
|
||||
return sf->open(sf, pathname, STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
99
src/util.c
99
src/util.c
@ -23,86 +23,6 @@ const char* filename_extension(const char* pathname) {
|
||||
return pathname + strlen(pathname);
|
||||
}
|
||||
|
||||
void swap_extension(char* pathname, int pathname_len, const char* swap) {
|
||||
char* extension = (char*)filename_extension(pathname);
|
||||
//todo safeops
|
||||
if (extension[0] == '\0') {
|
||||
strcat(pathname, ".");
|
||||
strcat(pathname, swap);
|
||||
}
|
||||
else {
|
||||
strcpy(extension, swap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* unused */
|
||||
/*
|
||||
void interleave_channel(sample_t * outbuffer, sample_t * inbuffer, int32_t sample_count, int channel_count, int channel_number) {
|
||||
int32_t insample,outsample;
|
||||
|
||||
if (channel_count==1) {
|
||||
memcpy(outbuffer,inbuffer,sizeof(sample)*sample_count);
|
||||
return;
|
||||
}
|
||||
|
||||
for (insample=0,outsample=channel_number;insample<sample_count;insample++,outsample+=channel_count) {
|
||||
outbuffer[outsample]=inbuffer[insample];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* failed attempt at interleave in place */
|
||||
/*
|
||||
void interleave_stereo(sample_t * buffer, int32_t sample_count) {
|
||||
int32_t tomove, belongs;
|
||||
sample_t moving,temp;
|
||||
|
||||
tomove = sample_count;
|
||||
moving = buffer[tomove];
|
||||
|
||||
do {
|
||||
if (tomove<sample_count)
|
||||
belongs = tomove*2;
|
||||
else
|
||||
belongs = (tomove-sample_count)*2+1;
|
||||
|
||||
temp = buffer[belongs];
|
||||
buffer[belongs] = moving;
|
||||
moving = temp;
|
||||
|
||||
tomove = belongs;
|
||||
} while (tomove != sample_count);
|
||||
}
|
||||
*/
|
||||
|
||||
void put_8bit(uint8_t * buf, int8_t i) {
|
||||
buf[0] = i;
|
||||
}
|
||||
|
||||
void put_16bitLE(uint8_t * buf, int16_t i) {
|
||||
buf[0] = (i & 0xFF);
|
||||
buf[1] = i >> 8;
|
||||
}
|
||||
|
||||
void put_32bitLE(uint8_t * buf, int32_t i) {
|
||||
buf[0] = (uint8_t)(i & 0xFF);
|
||||
buf[1] = (uint8_t)((i >> 8) & 0xFF);
|
||||
buf[2] = (uint8_t)((i >> 16) & 0xFF);
|
||||
buf[3] = (uint8_t)((i >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
void put_16bitBE(uint8_t * buf, int16_t i) {
|
||||
buf[0] = i >> 8;
|
||||
buf[1] = (i & 0xFF);
|
||||
}
|
||||
|
||||
void put_32bitBE(uint8_t * buf, int32_t i) {
|
||||
buf[0] = (uint8_t)((i >> 24) & 0xFF);
|
||||
buf[1] = (uint8_t)((i >> 16) & 0xFF);
|
||||
buf[2] = (uint8_t)((i >> 8) & 0xFF);
|
||||
buf[3] = (uint8_t)(i & 0xFF);
|
||||
}
|
||||
|
||||
int round10(int val) {
|
||||
int round_val = val % 10;
|
||||
@ -112,25 +32,6 @@ int round10(int val) {
|
||||
return val + (10 - round_val);
|
||||
}
|
||||
|
||||
void swap_samples_le(sample_t *buf, int count) {
|
||||
/* Windows can't be BE... I think */
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
/* 16b sample in memory: aabb where aa=MSB, bb=LSB */
|
||||
uint8_t b0 = buf[i] & 0xff;
|
||||
uint8_t b1 = buf[i] >> 8;
|
||||
uint8_t *p = (uint8_t*)&(buf[i]);
|
||||
/* 16b sample in buffer: bbaa where bb=LSB, aa=MSB */
|
||||
p[0] = b0;
|
||||
p[1] = b1;
|
||||
/* when endianness is LE, buffer has bbaa already so this function can be skipped */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* length is maximum length of dst. dst will always be null-terminated if
|
||||
* length > 0 */
|
||||
void concatn(int length, char * dst, const char * src) {
|
||||
|
142
src/util.h
142
src/util.h
@ -1,143 +1,15 @@
|
||||
/*
|
||||
* util.h - utility functions
|
||||
*/
|
||||
|
||||
#include "streamtypes.h"
|
||||
|
||||
#ifndef _UTIL_H
|
||||
#define _UTIL_H
|
||||
|
||||
#include "streamtypes.h"
|
||||
#include "util/reader_get.h"
|
||||
#include "util/reader_put.h"
|
||||
|
||||
/* very common functions, so static (inline) in .h as compiler can optimize to avoid some call overhead */
|
||||
|
||||
/* host endian independent multi-byte integer reading */
|
||||
|
||||
static inline int16_t get_16bitBE(const uint8_t* p) {
|
||||
return ((uint16_t)p[0]<<8) | ((uint16_t)p[1]);
|
||||
}
|
||||
|
||||
static inline int16_t get_16bitLE(const uint8_t* p) {
|
||||
return ((uint16_t)p[0]) | ((uint16_t)p[1]<<8);
|
||||
}
|
||||
|
||||
static inline int32_t get_32bitBE(const uint8_t* p) {
|
||||
return ((uint32_t)p[0]<<24) | ((uint32_t)p[1]<<16) | ((uint32_t)p[2]<<8) | ((uint32_t)p[3]);
|
||||
}
|
||||
|
||||
static inline int32_t get_32bitLE(const uint8_t* p) {
|
||||
return ((uint32_t)p[0]) | ((uint32_t)p[1]<<8) | ((uint32_t)p[2]<<16) | ((uint32_t)p[3]<<24);
|
||||
}
|
||||
|
||||
static inline int64_t get_64bitBE(const uint8_t* p) {
|
||||
return (uint64_t)(((uint64_t)p[0]<<56) | ((uint64_t)p[1]<<48) | ((uint64_t)p[2]<<40) | ((uint64_t)p[3]<<32) | ((uint64_t)p[4]<<24) | ((uint64_t)p[5]<<16) | ((uint64_t)p[6]<<8) | ((uint64_t)p[7]));
|
||||
}
|
||||
|
||||
static inline int64_t get_64bitLE(const uint8_t* p) {
|
||||
return (uint64_t)(((uint64_t)p[0]) | ((uint64_t)p[1]<<8) | ((uint64_t)p[2]<<16) | ((uint64_t)p[3]<<24) | ((uint64_t)p[4]<<32) | ((uint64_t)p[5]<<40) | ((uint64_t)p[6]<<48) | ((uint64_t)p[7]<<56));
|
||||
}
|
||||
|
||||
/* alias of the above */
|
||||
static inline int8_t get_s8 (const uint8_t* p) { return ( int8_t)p[0]; }
|
||||
static inline uint8_t get_u8 (const uint8_t* p) { return (uint8_t)p[0]; }
|
||||
static inline int16_t get_s16le(const uint8_t* p) { return ( int16_t)get_16bitLE(p); }
|
||||
static inline uint16_t get_u16le(const uint8_t* p) { return (uint16_t)get_16bitLE(p); }
|
||||
static inline int16_t get_s16be(const uint8_t* p) { return ( int16_t)get_16bitBE(p); }
|
||||
static inline uint16_t get_u16be(const uint8_t* p) { return (uint16_t)get_16bitBE(p); }
|
||||
static inline int32_t get_s32le(const uint8_t* p) { return ( int32_t)get_32bitLE(p); }
|
||||
static inline uint32_t get_u32le(const uint8_t* p) { return (uint32_t)get_32bitLE(p); }
|
||||
static inline int32_t get_s32be(const uint8_t* p) { return ( int32_t)get_32bitBE(p); }
|
||||
static inline uint32_t get_u32be(const uint8_t* p) { return (uint32_t)get_32bitBE(p); }
|
||||
static inline int64_t get_s64le(const uint8_t* p) { return ( int64_t)get_64bitLE(p); }
|
||||
static inline uint64_t get_u64le(const uint8_t* p) { return (uint64_t)get_64bitLE(p); }
|
||||
static inline int64_t get_s64be(const uint8_t* p) { return ( int64_t)get_64bitBE(p); }
|
||||
static inline uint64_t get_u64be(const uint8_t* p) { return (uint64_t)get_64bitBE(p); }
|
||||
|
||||
/* The recommended int-to-float type punning in C is through union, but pointer casting
|
||||
* works too (though less portable due to aliasing rules?). For C++ memcpy seems
|
||||
* recommended. Both work in GCC and VS2015+ (not sure about older, ifdef as needed). */
|
||||
static inline float get_f32be(const uint8_t* p) {
|
||||
union {
|
||||
uint32_t u32;
|
||||
float f32;
|
||||
} temp;
|
||||
temp.u32 = get_u32be(p);
|
||||
return temp.f32;
|
||||
}
|
||||
static inline float get_f32le(const uint8_t* p) {
|
||||
union {
|
||||
uint32_t u32;
|
||||
float f32;
|
||||
} temp;
|
||||
temp.u32 = get_u32le(p);
|
||||
return temp.f32;
|
||||
}
|
||||
static inline double get_d64be(const uint8_t* p) {
|
||||
union {
|
||||
uint64_t u64;
|
||||
double d64;
|
||||
} temp;
|
||||
temp.u64 = get_u64be(p);
|
||||
return temp.d64;
|
||||
}
|
||||
static inline double get_d64le(const uint8_t* p) {
|
||||
union {
|
||||
uint64_t u64;
|
||||
double d64;
|
||||
} temp;
|
||||
temp.u64 = get_u64le(p);
|
||||
return temp.d64;
|
||||
}
|
||||
#if 0
|
||||
static inline float get_f32be_cast(const uint8_t* p) {
|
||||
uint32_t sample_int = get_u32be(p);
|
||||
float* sample_float = (float*)&sample_int;
|
||||
return *sample_float;
|
||||
}
|
||||
static inline float get_f32be_mcpy(const uint8_t* p) {
|
||||
uint32_t sample_int = get_u32be(p);
|
||||
float sample_float;
|
||||
memcpy(&sample_float, &sample_int, sizeof(uint32_t));
|
||||
return sample_float;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void put_8bit(uint8_t* buf, int8_t i);
|
||||
void put_16bitLE(uint8_t* buf, int16_t i);
|
||||
void put_32bitLE(uint8_t* buf, int32_t i);
|
||||
void put_16bitBE(uint8_t* buf, int16_t i);
|
||||
void put_32bitBE(uint8_t* buf, int32_t i);
|
||||
|
||||
/* alias of the above */ //TODO: improve
|
||||
#define put_u8 put_8bit
|
||||
#define put_u16le put_16bitLE
|
||||
#define put_u32le put_32bitLE
|
||||
#define put_u16be put_16bitBE
|
||||
#define put_u32be put_32bitBE
|
||||
#define put_s8 put_8bit
|
||||
#define put_s16le put_16bitLE
|
||||
#define put_s32le put_32bitLE
|
||||
#define put_s16be put_16bitBE
|
||||
#define put_s32be put_32bitBE
|
||||
|
||||
|
||||
/* signed nibbles come up a lot */
|
||||
static int nibble_to_int[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1};
|
||||
|
||||
static inline int get_nibble_signed(uint8_t n, int upper) {
|
||||
/*return ((n&0x70)-(n&0x80))>>4;*/
|
||||
return nibble_to_int[(n >> (upper?4:0)) & 0x0f];
|
||||
}
|
||||
|
||||
static inline int get_high_nibble_signed(uint8_t n) {
|
||||
/*return ((n&0x70)-(n&0x80))>>4;*/
|
||||
return nibble_to_int[n>>4];
|
||||
}
|
||||
|
||||
static inline int get_low_nibble_signed(uint8_t n) {
|
||||
/*return (n&7)-(n&8);*/
|
||||
return nibble_to_int[n&0xf];
|
||||
}
|
||||
|
||||
static inline int clamp16(int32_t val) {
|
||||
if (val > 32767) return 32767;
|
||||
else if (val < -32768) return -32768;
|
||||
@ -177,12 +49,6 @@ int round10(int val);
|
||||
* extension in the original filename or the ending null byte if no extension */
|
||||
const char* filename_extension(const char* pathname);
|
||||
|
||||
/* change pathname's extension to another (or add it if extensionless) */
|
||||
void swap_extension(char* pathname, /*size_t*/ int pathname_len, const char* swap);
|
||||
|
||||
/* swap samples in machine endianness to little endian (useful to write .wav) */
|
||||
void swap_samples_le(sample_t *buf, int count);
|
||||
|
||||
void concatn(int length, char * dst, const char * src);
|
||||
|
||||
#endif
|
||||
|
@ -1,49 +1,49 @@
|
||||
#ifndef _CHANNEL_MAPPING_H
|
||||
#define _CHANNEL_MAPPING_H
|
||||
|
||||
/* standard WAVEFORMATEXTENSIBLE speaker positions */
|
||||
typedef enum {
|
||||
speaker_FL = (1 << 0), /* front left */
|
||||
speaker_FR = (1 << 1), /* front right */
|
||||
speaker_FC = (1 << 2), /* front center */
|
||||
speaker_LFE = (1 << 3), /* low frequency effects */
|
||||
speaker_BL = (1 << 4), /* back left */
|
||||
speaker_BR = (1 << 5), /* back right */
|
||||
speaker_FLC = (1 << 6), /* front left center */
|
||||
speaker_FRC = (1 << 7), /* front right center */
|
||||
speaker_BC = (1 << 8), /* back center */
|
||||
speaker_SL = (1 << 9), /* side left */
|
||||
speaker_SR = (1 << 10), /* side right */
|
||||
|
||||
speaker_TC = (1 << 11), /* top center*/
|
||||
speaker_TFL = (1 << 12), /* top front left */
|
||||
speaker_TFC = (1 << 13), /* top front center */
|
||||
speaker_TFR = (1 << 14), /* top front right */
|
||||
speaker_TBL = (1 << 15), /* top back left */
|
||||
speaker_TBC = (1 << 16), /* top back center */
|
||||
speaker_TBR = (1 << 17), /* top back left */
|
||||
|
||||
} speaker_t;
|
||||
|
||||
/* typical mappings that metas may use to set channel_layout (but plugin must actually use it)
|
||||
* (in order, so 3ch file could be mapped to FL FR FC or FL FR LFE but not LFE FL FR)
|
||||
* not too sure about names but no clear standards */
|
||||
typedef enum {
|
||||
mapping_MONO = speaker_FC,
|
||||
mapping_STEREO = speaker_FL | speaker_FR,
|
||||
mapping_2POINT1 = speaker_FL | speaker_FR | speaker_LFE,
|
||||
mapping_2POINT1_xiph = speaker_FL | speaker_FR | speaker_FC, /* aka 3STEREO? */
|
||||
mapping_QUAD = speaker_FL | speaker_FR | speaker_BL | speaker_BR,
|
||||
mapping_QUAD_surround = speaker_FL | speaker_FR | speaker_FC | speaker_BC,
|
||||
mapping_QUAD_side = speaker_FL | speaker_FR | speaker_SL | speaker_SR,
|
||||
mapping_5POINT0 = speaker_FL | speaker_FR | speaker_LFE | speaker_BL | speaker_BR,
|
||||
mapping_5POINT0_xiph = speaker_FL | speaker_FR | speaker_FC | speaker_BL | speaker_BR,
|
||||
mapping_5POINT0_surround = speaker_FL | speaker_FR | speaker_FC | speaker_SL | speaker_SR,
|
||||
mapping_5POINT1 = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BL | speaker_BR,
|
||||
mapping_5POINT1_surround = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_SL | speaker_SR,
|
||||
mapping_7POINT0 = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BC | speaker_FLC | speaker_FRC,
|
||||
mapping_7POINT1 = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BL | speaker_BR | speaker_FLC | speaker_FRC,
|
||||
mapping_7POINT1_surround = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BL | speaker_BR | speaker_SL | speaker_SR,
|
||||
} channel_mapping_t;
|
||||
|
||||
#endif
|
||||
#ifndef _CHANNEL_MAPPING_H
|
||||
#define _CHANNEL_MAPPING_H
|
||||
|
||||
/* standard WAVEFORMATEXTENSIBLE speaker positions */
|
||||
typedef enum {
|
||||
speaker_FL = (1 << 0), /* front left */
|
||||
speaker_FR = (1 << 1), /* front right */
|
||||
speaker_FC = (1 << 2), /* front center */
|
||||
speaker_LFE = (1 << 3), /* low frequency effects */
|
||||
speaker_BL = (1 << 4), /* back left */
|
||||
speaker_BR = (1 << 5), /* back right */
|
||||
speaker_FLC = (1 << 6), /* front left center */
|
||||
speaker_FRC = (1 << 7), /* front right center */
|
||||
speaker_BC = (1 << 8), /* back center */
|
||||
speaker_SL = (1 << 9), /* side left */
|
||||
speaker_SR = (1 << 10), /* side right */
|
||||
|
||||
speaker_TC = (1 << 11), /* top center*/
|
||||
speaker_TFL = (1 << 12), /* top front left */
|
||||
speaker_TFC = (1 << 13), /* top front center */
|
||||
speaker_TFR = (1 << 14), /* top front right */
|
||||
speaker_TBL = (1 << 15), /* top back left */
|
||||
speaker_TBC = (1 << 16), /* top back center */
|
||||
speaker_TBR = (1 << 17), /* top back left */
|
||||
|
||||
} speaker_t;
|
||||
|
||||
/* typical mappings that metas may use to set channel_layout (but plugin must actually use it)
|
||||
* (in order, so 3ch file could be mapped to FL FR FC or FL FR LFE but not LFE FL FR)
|
||||
* not too sure about names but no clear standards */
|
||||
typedef enum {
|
||||
mapping_MONO = speaker_FC,
|
||||
mapping_STEREO = speaker_FL | speaker_FR,
|
||||
mapping_2POINT1 = speaker_FL | speaker_FR | speaker_LFE,
|
||||
mapping_2POINT1_xiph = speaker_FL | speaker_FR | speaker_FC, /* aka 3STEREO? */
|
||||
mapping_QUAD = speaker_FL | speaker_FR | speaker_BL | speaker_BR,
|
||||
mapping_QUAD_surround = speaker_FL | speaker_FR | speaker_FC | speaker_BC,
|
||||
mapping_QUAD_side = speaker_FL | speaker_FR | speaker_SL | speaker_SR,
|
||||
mapping_5POINT0 = speaker_FL | speaker_FR | speaker_LFE | speaker_BL | speaker_BR,
|
||||
mapping_5POINT0_xiph = speaker_FL | speaker_FR | speaker_FC | speaker_BL | speaker_BR,
|
||||
mapping_5POINT0_surround = speaker_FL | speaker_FR | speaker_FC | speaker_SL | speaker_SR,
|
||||
mapping_5POINT1 = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BL | speaker_BR,
|
||||
mapping_5POINT1_surround = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_SL | speaker_SR,
|
||||
mapping_7POINT0 = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BC | speaker_FLC | speaker_FRC,
|
||||
mapping_7POINT1 = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BL | speaker_BR | speaker_FLC | speaker_FRC,
|
||||
mapping_7POINT1_surround = speaker_FL | speaker_FR | speaker_FC | speaker_LFE | speaker_BL | speaker_BR | speaker_SL | speaker_SR,
|
||||
} channel_mapping_t;
|
||||
|
||||
#endif
|
||||
|
100
src/util/reader_get.h
Normal file
100
src/util/reader_get.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef _READER_GET_H
|
||||
#define _READER_GET_H
|
||||
|
||||
#include "../streamtypes.h"
|
||||
|
||||
/* very common functions, so static (inline) in .h as compiler can optimize to avoid some call overhead */
|
||||
|
||||
/* host endian independent multi-byte integer reading */
|
||||
|
||||
static inline int16_t get_16bitBE(const uint8_t* p) {
|
||||
return ((uint16_t)p[0]<<8) | ((uint16_t)p[1]);
|
||||
}
|
||||
|
||||
static inline int16_t get_16bitLE(const uint8_t* p) {
|
||||
return ((uint16_t)p[0]) | ((uint16_t)p[1]<<8);
|
||||
}
|
||||
|
||||
static inline int32_t get_32bitBE(const uint8_t* p) {
|
||||
return ((uint32_t)p[0]<<24) | ((uint32_t)p[1]<<16) | ((uint32_t)p[2]<<8) | ((uint32_t)p[3]);
|
||||
}
|
||||
|
||||
static inline int32_t get_32bitLE(const uint8_t* p) {
|
||||
return ((uint32_t)p[0]) | ((uint32_t)p[1]<<8) | ((uint32_t)p[2]<<16) | ((uint32_t)p[3]<<24);
|
||||
}
|
||||
|
||||
static inline int64_t get_64bitBE(const uint8_t* p) {
|
||||
return (uint64_t)(((uint64_t)p[0]<<56) | ((uint64_t)p[1]<<48) | ((uint64_t)p[2]<<40) | ((uint64_t)p[3]<<32) | ((uint64_t)p[4]<<24) | ((uint64_t)p[5]<<16) | ((uint64_t)p[6]<<8) | ((uint64_t)p[7]));
|
||||
}
|
||||
|
||||
static inline int64_t get_64bitLE(const uint8_t* p) {
|
||||
return (uint64_t)(((uint64_t)p[0]) | ((uint64_t)p[1]<<8) | ((uint64_t)p[2]<<16) | ((uint64_t)p[3]<<24) | ((uint64_t)p[4]<<32) | ((uint64_t)p[5]<<40) | ((uint64_t)p[6]<<48) | ((uint64_t)p[7]<<56));
|
||||
}
|
||||
|
||||
/* alias of the above */
|
||||
static inline int8_t get_s8 (const uint8_t* p) { return ( int8_t)p[0]; }
|
||||
static inline uint8_t get_u8 (const uint8_t* p) { return (uint8_t)p[0]; }
|
||||
static inline int16_t get_s16le(const uint8_t* p) { return ( int16_t)get_16bitLE(p); }
|
||||
static inline uint16_t get_u16le(const uint8_t* p) { return (uint16_t)get_16bitLE(p); }
|
||||
static inline int16_t get_s16be(const uint8_t* p) { return ( int16_t)get_16bitBE(p); }
|
||||
static inline uint16_t get_u16be(const uint8_t* p) { return (uint16_t)get_16bitBE(p); }
|
||||
static inline int32_t get_s32le(const uint8_t* p) { return ( int32_t)get_32bitLE(p); }
|
||||
static inline uint32_t get_u32le(const uint8_t* p) { return (uint32_t)get_32bitLE(p); }
|
||||
static inline int32_t get_s32be(const uint8_t* p) { return ( int32_t)get_32bitBE(p); }
|
||||
static inline uint32_t get_u32be(const uint8_t* p) { return (uint32_t)get_32bitBE(p); }
|
||||
static inline int64_t get_s64le(const uint8_t* p) { return ( int64_t)get_64bitLE(p); }
|
||||
static inline uint64_t get_u64le(const uint8_t* p) { return (uint64_t)get_64bitLE(p); }
|
||||
static inline int64_t get_s64be(const uint8_t* p) { return ( int64_t)get_64bitBE(p); }
|
||||
static inline uint64_t get_u64be(const uint8_t* p) { return (uint64_t)get_64bitBE(p); }
|
||||
|
||||
/* The recommended int-to-float type punning in C is through union, but pointer casting
|
||||
* works too (though less portable due to aliasing rules?). For C++ memcpy seems
|
||||
* recommended. Both work in GCC and VS2015+ (not sure about older, ifdef as needed). */
|
||||
static inline float get_f32be(const uint8_t* p) {
|
||||
union {
|
||||
uint32_t u32;
|
||||
float f32;
|
||||
} temp;
|
||||
temp.u32 = get_u32be(p);
|
||||
return temp.f32;
|
||||
}
|
||||
static inline float get_f32le(const uint8_t* p) {
|
||||
union {
|
||||
uint32_t u32;
|
||||
float f32;
|
||||
} temp;
|
||||
temp.u32 = get_u32le(p);
|
||||
return temp.f32;
|
||||
}
|
||||
static inline double get_d64be(const uint8_t* p) {
|
||||
union {
|
||||
uint64_t u64;
|
||||
double d64;
|
||||
} temp;
|
||||
temp.u64 = get_u64be(p);
|
||||
return temp.d64;
|
||||
}
|
||||
static inline double get_d64le(const uint8_t* p) {
|
||||
union {
|
||||
uint64_t u64;
|
||||
double d64;
|
||||
} temp;
|
||||
temp.u64 = get_u64le(p);
|
||||
return temp.d64;
|
||||
}
|
||||
#if 0
|
||||
static inline float get_f32be_cast(const uint8_t* p) {
|
||||
uint32_t sample_int = get_u32be(p);
|
||||
float* sample_float = (float*)&sample_int;
|
||||
return *sample_float;
|
||||
}
|
||||
static inline float get_f32be_mcpy(const uint8_t* p) {
|
||||
uint32_t sample_int = get_u32be(p);
|
||||
float sample_float;
|
||||
memcpy(&sample_float, &sample_int, sizeof(uint32_t));
|
||||
return sample_float;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
25
src/util/reader_get_nibbles.h
Normal file
25
src/util/reader_get_nibbles.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _READER_GET_NIBBLES_H
|
||||
#define _READER_GET_NIBBLES_H
|
||||
|
||||
#include "../streamtypes.h"
|
||||
|
||||
/* signed nibbles come up a lot in decoders */
|
||||
|
||||
static int nibble_to_int[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1};
|
||||
|
||||
static inline int get_nibble_signed(uint8_t n, int upper) {
|
||||
/*return ((n&0x70)-(n&0x80))>>4;*/
|
||||
return nibble_to_int[(n >> (upper?4:0)) & 0x0f];
|
||||
}
|
||||
|
||||
static inline int get_high_nibble_signed(uint8_t n) {
|
||||
/*return ((n&0x70)-(n&0x80))>>4;*/
|
||||
return nibble_to_int[n>>4];
|
||||
}
|
||||
|
||||
static inline int get_low_nibble_signed(uint8_t n) {
|
||||
/*return (n&7)-(n&8);*/
|
||||
return nibble_to_int[n&0xf];
|
||||
}
|
||||
|
||||
#endif
|
29
src/util/reader_put.c
Normal file
29
src/util/reader_put.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "reader_put.h"
|
||||
|
||||
void put_8bit(uint8_t * buf, int8_t i) {
|
||||
buf[0] = i;
|
||||
}
|
||||
|
||||
void put_16bitLE(uint8_t * buf, int16_t i) {
|
||||
buf[0] = (i & 0xFF);
|
||||
buf[1] = i >> 8;
|
||||
}
|
||||
|
||||
void put_32bitLE(uint8_t * buf, int32_t i) {
|
||||
buf[0] = (uint8_t)(i & 0xFF);
|
||||
buf[1] = (uint8_t)((i >> 8) & 0xFF);
|
||||
buf[2] = (uint8_t)((i >> 16) & 0xFF);
|
||||
buf[3] = (uint8_t)((i >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
void put_16bitBE(uint8_t * buf, int16_t i) {
|
||||
buf[0] = i >> 8;
|
||||
buf[1] = (i & 0xFF);
|
||||
}
|
||||
|
||||
void put_32bitBE(uint8_t * buf, int32_t i) {
|
||||
buf[0] = (uint8_t)((i >> 24) & 0xFF);
|
||||
buf[1] = (uint8_t)((i >> 16) & 0xFF);
|
||||
buf[2] = (uint8_t)((i >> 8) & 0xFF);
|
||||
buf[3] = (uint8_t)(i & 0xFF);
|
||||
}
|
25
src/util/reader_put.h
Normal file
25
src/util/reader_put.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _READER_PUT_H
|
||||
#define _READER_PUT_H
|
||||
|
||||
#include "../streamtypes.h"
|
||||
|
||||
|
||||
void put_8bit(uint8_t* buf, int8_t i);
|
||||
void put_16bitLE(uint8_t* buf, int16_t i);
|
||||
void put_32bitLE(uint8_t* buf, int32_t i);
|
||||
void put_16bitBE(uint8_t* buf, int16_t i);
|
||||
void put_32bitBE(uint8_t* buf, int32_t i);
|
||||
|
||||
/* alias of the above */ //TODO: improve
|
||||
#define put_u8 put_8bit
|
||||
#define put_u16le put_16bitLE
|
||||
#define put_u32le put_32bitLE
|
||||
#define put_u16be put_16bitBE
|
||||
#define put_u32be put_32bitBE
|
||||
#define put_s8 put_8bit
|
||||
#define put_s16le put_16bitLE
|
||||
#define put_s32le put_32bitLE
|
||||
#define put_s16be put_16bitBE
|
||||
#define put_s32be put_32bitBE
|
||||
|
||||
#endif
|
63
src/util/samples_ops.c
Normal file
63
src/util/samples_ops.c
Normal file
@ -0,0 +1,63 @@
|
||||
#include "samples_ops.h"
|
||||
|
||||
|
||||
void swap_samples_le(sample_t *buf, int count) {
|
||||
/* Windows can't be BE... I think */
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
/* 16b sample in memory: aabb where aa=MSB, bb=LSB */
|
||||
uint8_t b0 = buf[i] & 0xff;
|
||||
uint8_t b1 = buf[i] >> 8;
|
||||
uint8_t *p = (uint8_t*)&(buf[i]);
|
||||
/* 16b sample in buffer: bbaa where bb=LSB, aa=MSB */
|
||||
p[0] = b0;
|
||||
p[1] = b1;
|
||||
/* when endianness is LE, buffer has bbaa already so this function can be skipped */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* unused */
|
||||
/*
|
||||
void interleave_channel(sample_t * outbuffer, sample_t * inbuffer, int32_t sample_count, int channel_count, int channel_number) {
|
||||
int32_t insample,outsample;
|
||||
|
||||
if (channel_count==1) {
|
||||
memcpy(outbuffer,inbuffer,sizeof(sample)*sample_count);
|
||||
return;
|
||||
}
|
||||
|
||||
for (insample=0,outsample=channel_number;insample<sample_count;insample++,outsample+=channel_count) {
|
||||
outbuffer[outsample]=inbuffer[insample];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* failed attempt at interleave in place */
|
||||
/*
|
||||
void interleave_stereo(sample_t * buffer, int32_t sample_count) {
|
||||
int32_t tomove, belongs;
|
||||
sample_t moving,temp;
|
||||
|
||||
tomove = sample_count;
|
||||
moving = buffer[tomove];
|
||||
|
||||
do {
|
||||
if (tomove<sample_count)
|
||||
belongs = tomove*2;
|
||||
else
|
||||
belongs = (tomove-sample_count)*2+1;
|
||||
|
||||
temp = buffer[belongs];
|
||||
buffer[belongs] = moving;
|
||||
moving = temp;
|
||||
|
||||
tomove = belongs;
|
||||
} while (tomove != sample_count);
|
||||
}
|
||||
*/
|
||||
|
9
src/util/samples_ops.h
Normal file
9
src/util/samples_ops.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _SAMPLES_OPS_H
|
||||
#define _SAMPLES_OPS_H
|
||||
|
||||
#include "../streamtypes.h"
|
||||
|
||||
/* swap samples in machine endianness to little endian (useful to write .wav) */
|
||||
void swap_samples_le(sample_t* buf, int count);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user