2016-06-28 09:20:37 +02:00
|
|
|
#ifndef _clHCA_H
|
|
|
|
#define _clHCA_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2018-09-01 20:28:00 +02:00
|
|
|
/* Must pass at least 8 bytes of data to this function.
|
|
|
|
* Returns <0 on non-match, or header size on success. */
|
|
|
|
int clHCA_isOurFile(const void *data, unsigned int size);
|
2016-06-28 09:20:37 +02:00
|
|
|
|
|
|
|
/* The opaque state structure. */
|
|
|
|
typedef struct clHCA clHCA;
|
|
|
|
|
2018-09-01 20:28:00 +02:00
|
|
|
/* In case you wish to allocate and reset the structure on your own. */
|
2016-06-28 09:20:37 +02:00
|
|
|
int clHCA_sizeof();
|
2018-09-01 20:28:00 +02:00
|
|
|
void clHCA_clear(clHCA *);
|
2016-06-30 04:56:20 +02:00
|
|
|
void clHCA_done(clHCA *);
|
2016-06-28 09:20:37 +02:00
|
|
|
|
|
|
|
/* Or you could let the library allocate it. */
|
2018-09-01 20:28:00 +02:00
|
|
|
clHCA * clHCA_new();
|
2016-06-28 09:20:37 +02:00
|
|
|
void clHCA_delete(clHCA *);
|
|
|
|
|
2018-09-01 20:28:00 +02:00
|
|
|
/* Parses the HCA header. Must be called before any decoding may be performed,
|
|
|
|
* and size must be at least headerSize long. The recommended way is to detect
|
|
|
|
* the header length with clHCA_isOurFile, then read data and call this.
|
|
|
|
* May be called multiple times to reset decoder state.
|
|
|
|
* Returns 0 on success, <0 on failure. */
|
|
|
|
int clHCA_DecodeHeader(clHCA *, void *data, unsigned int size);
|
2016-06-28 09:20:37 +02:00
|
|
|
|
|
|
|
typedef struct clHCA_stInfo {
|
|
|
|
unsigned int version;
|
2018-09-01 20:28:00 +02:00
|
|
|
unsigned int headerSize;
|
2016-06-28 09:20:37 +02:00
|
|
|
unsigned int samplingRate;
|
|
|
|
unsigned int channelCount;
|
|
|
|
unsigned int blockSize;
|
|
|
|
unsigned int blockCount;
|
2018-09-02 16:00:58 +02:00
|
|
|
unsigned int encoderDelay; /* samples appended to the beginning */
|
|
|
|
unsigned int encoderPadding; /* samples appended to the end */
|
2016-06-30 04:56:20 +02:00
|
|
|
unsigned int loopEnabled;
|
2018-08-29 20:48:35 +02:00
|
|
|
unsigned int loopStartBlock;
|
|
|
|
unsigned int loopEndBlock;
|
|
|
|
unsigned int loopStartDelay; /* samples in block before loop starts */
|
|
|
|
unsigned int loopEndPadding; /* samples in block after loop ends */
|
2018-09-01 20:28:00 +02:00
|
|
|
unsigned int samplesPerBlock; /* should be 1024 */
|
2016-06-30 04:56:20 +02:00
|
|
|
const char *comment;
|
2018-09-02 16:00:58 +02:00
|
|
|
unsigned int encryptionEnabled; /* requires keycode */
|
2018-09-01 20:28:00 +02:00
|
|
|
|
|
|
|
/* Derived sample formulas:
|
|
|
|
* - sample count: blockCount*samplesPerBlock - encoderDelay - encoderPadding;
|
|
|
|
* - loop start sample = loopStartBlock*samplesPerBlock - encoderDelay + loopStartDelay
|
|
|
|
* - loop end sample = loopEndBlock*samplesPerBlock - encoderDelay + (samplesPerBlock - info.loopEndPadding)
|
|
|
|
*/
|
2016-06-28 09:20:37 +02:00
|
|
|
} clHCA_stInfo;
|
|
|
|
|
2018-09-01 20:28:00 +02:00
|
|
|
/* Retrieves header information for decoding and playback (it's the caller's responsability
|
|
|
|
* to apply looping, encoder delay/skip samples, etc). May be called after clHCA_DecodeHeader.
|
|
|
|
* Returns 0 on success, <0 on failure. */
|
2016-06-28 09:20:37 +02:00
|
|
|
int clHCA_getInfo(clHCA *, clHCA_stInfo *out);
|
|
|
|
|
2018-09-01 20:28:00 +02:00
|
|
|
/* Decodes a single frame, from data after headerSize. Should be called after
|
|
|
|
* clHCA_DecodeHeader and size must be at least blockSize long.
|
|
|
|
* Returns 0 on success, <0 on failure. */
|
|
|
|
int clHCA_DecodeBlock(clHCA *, void *data, unsigned int size);
|
|
|
|
|
|
|
|
/* Extracts signed and clipped 16 bit samples into sample buffer.
|
|
|
|
* May be called after clHCA_DecodeBlock, and will return the same data until
|
|
|
|
* next decode. Buffer must be at least (samplesPerBlock*channels) long. */
|
|
|
|
void clHCA_ReadSamples16(clHCA *, signed short * outSamples);
|
|
|
|
|
2018-09-02 16:00:58 +02:00
|
|
|
/* Sets a 64 bit encryption key, to properly decode blocks. This may be called
|
|
|
|
* multiple times to change the key, before or after clHCA_DecodeHeader.
|
|
|
|
* Key is ignored if the file is not encrypted. */
|
|
|
|
void clHCA_SetKey(clHCA *, unsigned long long keycode);
|
|
|
|
|
|
|
|
/* Tests a single frame for validity, mainly to test if current key is correct.
|
|
|
|
* Returns <0 on incorrect block (wrong key), 0 on silent block (not useful to determine)
|
|
|
|
* and >0 if block is correct (the closer to 1 the more likely).
|
|
|
|
* Incorrect keys may give a few valid frames, so it's best to test a number of them
|
|
|
|
* and select the key with scores closer to 1. */
|
|
|
|
int clHCA_TestBlock(clHCA *hca, void *data, unsigned int size);
|
2018-09-01 20:28:00 +02:00
|
|
|
|
2016-06-28 09:20:37 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|