mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-11 14:07:11 +03:00
update cspot
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-12.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseCodec.h"
|
||||
#include "aacdec.h"
|
||||
|
||||
class AACDecoder : public BaseCodec {
|
||||
private:
|
||||
HAACDecoder aac;
|
||||
int16_t *pcmData;
|
||||
AACFrameInfo frame = {};
|
||||
|
||||
public:
|
||||
AACDecoder();
|
||||
~AACDecoder();
|
||||
bool setup(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
uint8_t *decode(uint8_t *inData, uint32_t inLen, uint32_t &outLen) override;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-12.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseCodec.h"
|
||||
#include "alac_wrapper.h"
|
||||
|
||||
class ALACDecoder : public BaseCodec {
|
||||
private:
|
||||
alac_codec_s* alacCodec;
|
||||
int16_t *pcmData;
|
||||
|
||||
public:
|
||||
ALACDecoder();
|
||||
~ALACDecoder();
|
||||
bool setup(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
uint8_t *decode(uint8_t *inData, uint32_t inLen, uint32_t &outLen) override;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-12.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseCodec.h"
|
||||
#include "BaseContainer.h"
|
||||
#include <memory>
|
||||
|
||||
enum class AudioCodec {
|
||||
UNKNOWN = 0,
|
||||
AAC = 1,
|
||||
MP3 = 2,
|
||||
VORBIS = 3,
|
||||
OPUS = 4,
|
||||
FLAC = 5,
|
||||
};
|
||||
|
||||
class AudioCodecs {
|
||||
public:
|
||||
static std::shared_ptr<BaseCodec> getCodec(AudioCodec type);
|
||||
static std::shared_ptr<BaseCodec> getCodec(BaseContainer *container);
|
||||
static void addCodec(AudioCodec type, const std::shared_ptr<BaseCodec> &codec);
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-12.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseContainer.h"
|
||||
|
||||
class BaseCodec {
|
||||
public:
|
||||
/**
|
||||
* Setup the codec (sample rate, channel count, etc) using the specified container.
|
||||
*/
|
||||
virtual bool setup(BaseContainer *container);
|
||||
/**
|
||||
* Setup the codec manually, using the provided values.
|
||||
*/
|
||||
virtual bool setup(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) = 0;
|
||||
/**
|
||||
* Decode the given sample.
|
||||
*
|
||||
* @param [in] inData encoded data. Should allow nullptr, in which case nullptr should be returned.
|
||||
* @param [in] inLen size of inData, in bytes
|
||||
* @param [out] outLen size of output PCM data, in bytes
|
||||
* @return pointer to decoded raw PCM audio data, allocated inside the codec object; nullptr on failure
|
||||
*/
|
||||
virtual uint8_t *decode(uint8_t *inData, uint32_t inLen, uint32_t &outLen) = 0;
|
||||
/**
|
||||
* Read a single sample from the container, decode it, and return the result.
|
||||
*
|
||||
* @param [in] container media container to read the sample from (the container's codec must match this instance)
|
||||
* @param [out] outLen size of output PCM data, in bytes
|
||||
* @return pointer to decoded raw PCM audio data, allocated inside the codec object; nullptr on failure
|
||||
*/
|
||||
uint8_t *decode(BaseContainer *container, uint32_t &outLen);
|
||||
/**
|
||||
* Last error that occurred, this is a codec-specific value.
|
||||
* This may be set by a codec upon decoding failure.
|
||||
*/
|
||||
int lastErrno = -1;
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef BELL_DISABLE_CODECS
|
||||
#ifndef DECODER_GLOBALS_H
|
||||
#define DECODER_GLOBALS_H
|
||||
|
||||
#define AAC_READBUF_SIZE (4 * AAC_MAINBUF_SIZE * AAC_MAX_NCHANS)
|
||||
#define MP3_READBUF_SIZE (2 * 1024);
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory>
|
||||
#include "aacdec.h"
|
||||
#include "mp3dec.h"
|
||||
|
||||
namespace bell
|
||||
{
|
||||
class DecodersInstance
|
||||
{
|
||||
public:
|
||||
DecodersInstance(){};
|
||||
~DecodersInstance()
|
||||
{
|
||||
MP3FreeDecoder(mp3Decoder);
|
||||
AACFreeDecoder(aacDecoder);
|
||||
};
|
||||
|
||||
HAACDecoder aacDecoder = NULL;
|
||||
HMP3Decoder mp3Decoder = NULL;
|
||||
|
||||
void ensureAAC()
|
||||
{
|
||||
if (aacDecoder == NULL)
|
||||
{
|
||||
aacDecoder = AACInitDecoder();
|
||||
}
|
||||
}
|
||||
|
||||
void ensureMP3()
|
||||
{
|
||||
if (mp3Decoder == NULL)
|
||||
{
|
||||
mp3Decoder = MP3InitDecoder();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern bell::DecodersInstance* decodersInstance;
|
||||
|
||||
void createDecoders();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-14.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseCodec.h"
|
||||
#include "mp3dec.h"
|
||||
|
||||
class MP3Decoder : public BaseCodec {
|
||||
private:
|
||||
HMP3Decoder mp3;
|
||||
int16_t *pcmData;
|
||||
MP3FrameInfo frame = {};
|
||||
|
||||
public:
|
||||
MP3Decoder();
|
||||
~MP3Decoder();
|
||||
bool setup(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
uint8_t *decode(uint8_t *inData, uint32_t inLen, uint32_t &outLen) override;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-14.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseCodec.h"
|
||||
|
||||
struct OpusDecoder;
|
||||
|
||||
class OPUSDecoder : public BaseCodec {
|
||||
private:
|
||||
OpusDecoder *opus;
|
||||
int16_t *pcmData;
|
||||
|
||||
public:
|
||||
OPUSDecoder();
|
||||
~OPUSDecoder();
|
||||
bool setup(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
uint8_t *decode(uint8_t *inData, uint32_t inLen, uint32_t &outLen) override;
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-14.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseCodec.h"
|
||||
#include "ivorbiscodec.h"
|
||||
|
||||
class VorbisDecoder : public BaseCodec {
|
||||
private:
|
||||
vorbis_info *vi = nullptr;
|
||||
vorbis_comment *vc = nullptr;
|
||||
vorbis_dsp_state *vd = nullptr;
|
||||
ogg_packet op = {};
|
||||
int16_t *pcmData;
|
||||
|
||||
public:
|
||||
VorbisDecoder();
|
||||
~VorbisDecoder();
|
||||
bool setup(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
uint8_t *decode(uint8_t *inData, uint32_t inLen, uint32_t &outLen) override;
|
||||
bool setup(BaseContainer *container) override;
|
||||
|
||||
private:
|
||||
void setPacket(uint8_t *inData, uint32_t inLen) const;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-15.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseContainer.h"
|
||||
|
||||
class AudioContainers {
|
||||
public:
|
||||
static std::unique_ptr<BaseContainer> create(const char *mimeType);
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-7.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BinaryReader.h"
|
||||
#include "ByteStream.h"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* Either the media file or the requested position/offset is not loaded yet.
|
||||
*/
|
||||
#define SAMPLE_NOT_LOADED -1
|
||||
/**
|
||||
* The media file does not contain the requested position/offset.
|
||||
*/
|
||||
#define SAMPLE_NOT_FOUND -2
|
||||
/**
|
||||
* The file is not seekable (i.e. doesn't contain an index table).
|
||||
*/
|
||||
#define SAMPLE_NOT_SEEKABLE -3
|
||||
|
||||
enum class AudioCodec;
|
||||
|
||||
class BaseContainer {
|
||||
public:
|
||||
BaseContainer() = default;
|
||||
/**
|
||||
* Feed a new data source to the container.
|
||||
* @param stream ByteStream reading source data
|
||||
* @param position absolute position of the current ByteStream within the source media
|
||||
*/
|
||||
virtual void feed(const std::shared_ptr<bell::ByteStream> &stream, uint32_t position);
|
||||
/**
|
||||
* Try to parse the media provided by the source stream.
|
||||
* @return whether parsing was successful
|
||||
*/
|
||||
virtual bool parse() = 0;
|
||||
/**
|
||||
* Get absolute offset within the source media for the given timestamp.
|
||||
* When seeking to a specified time, the caller should run feed() with a stream
|
||||
* reader starting at the returned offset. Depending on the container type,
|
||||
* the returned offset may not point to the exact time position (i.e. chunks with
|
||||
* headers), so seekTo() should be used afterwards.
|
||||
*
|
||||
* @param timeMs requested timestamp, in milliseconds
|
||||
* @return byte offset within the source media that should be loaded
|
||||
* in order to seek to the requested position; negative value on error
|
||||
*/
|
||||
virtual int32_t getLoadingOffset(uint32_t timeMs) = 0;
|
||||
/**
|
||||
* Try to seek to the specified position (in milliseconds), using the currently
|
||||
* loaded source stream. This method will fail if the source stream does not yield
|
||||
* data for the requested position, or block until the stream loads data for this position.
|
||||
*
|
||||
* @param timeMs requested timestamp, in milliseconds
|
||||
*/
|
||||
virtual bool seekTo(uint32_t timeMs) = 0;
|
||||
/**
|
||||
* Get the current playback position, in milliseconds. May return -1 if the track
|
||||
* is not playing (has ended or not started yet).
|
||||
*/
|
||||
virtual int32_t getCurrentTimeMs() = 0;
|
||||
/**
|
||||
* Read an encoded audio sample from the container, starting at the current position.
|
||||
*
|
||||
* @param [out] len length of the data stored in the returned pointer, in bytes
|
||||
* @return pointer to data allocated inside the container object; should not be freed or changed.
|
||||
* On failure, nullptr is returned, and len is left unchanged.
|
||||
*/
|
||||
virtual uint8_t *readSample(uint32_t &len) = 0;
|
||||
/**
|
||||
* Get optional initialization data for the specified codec. This may be used by a codec,
|
||||
* for containers that contain the setup data.
|
||||
*
|
||||
* @param [out] len length of the setup data
|
||||
* @return ptr to [len] setup data bytes, or nullptr if not available/not supported
|
||||
*/
|
||||
virtual uint8_t *getSetupData(uint32_t &len, AudioCodec matchCodec) = 0;
|
||||
|
||||
public:
|
||||
bool closed = false;
|
||||
bool isSeekable = false;
|
||||
// audio parameters
|
||||
AudioCodec codec = (AudioCodec)0;
|
||||
uint32_t sampleRate = 0;
|
||||
uint8_t channelCount = 0;
|
||||
uint8_t bitDepth = 0;
|
||||
uint32_t durationMs = 0;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<bell::BinaryReader> reader;
|
||||
std::shared_ptr<bell::ByteStream> source;
|
||||
uint32_t pos = 0;
|
||||
uint8_t readUint8();
|
||||
uint16_t readUint16();
|
||||
uint32_t readUint24();
|
||||
uint32_t readUint32();
|
||||
uint64_t readUint64();
|
||||
uint32_t readVarint32();
|
||||
uint32_t readBytes(uint8_t *dst, uint32_t num);
|
||||
uint32_t skipBytes(uint32_t num);
|
||||
uint32_t skipTo(uint32_t offset);
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-8.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class AudioSampleFormat;
|
||||
enum class MP4AObjectType;
|
||||
enum class MP4AProfile;
|
||||
|
||||
typedef struct {
|
||||
/** Absolute offset of mdat header (or moof for fMP4) */
|
||||
uint32_t start;
|
||||
/** Absolute offset of the last mdat byte */
|
||||
uint32_t end;
|
||||
/** Total duration of this fragment */
|
||||
uint32_t duration;
|
||||
} Mpeg4Fragment;
|
||||
|
||||
typedef struct {
|
||||
/** Number of chunks this descriptor applies to */
|
||||
uint16_t count;
|
||||
/** Number of samples in the described chunks */
|
||||
uint32_t samples;
|
||||
uint16_t sampleDescriptionId;
|
||||
} Mpeg4ChunkRange;
|
||||
|
||||
/** Absolute offset of the chunk data */
|
||||
typedef uint32_t Mpeg4ChunkOffset;
|
||||
|
||||
typedef struct {
|
||||
/** Abs. offset of data start in the current chunk */
|
||||
uint32_t start;
|
||||
/** Abs. offset of data end in the current chunk */
|
||||
uint32_t end;
|
||||
/** Abs. offset of the next chunk data, or 0 for last chunk in a fragment */
|
||||
uint32_t nextStart;
|
||||
} Mpeg4Chunk;
|
||||
|
||||
typedef struct {
|
||||
/** Number of samples this descriptor applies to */
|
||||
uint32_t count;
|
||||
/** Duration of the described samples */
|
||||
uint32_t duration;
|
||||
} Mpeg4SampleRange;
|
||||
|
||||
/** Size of a single sample */
|
||||
typedef uint32_t Mpeg4SampleSize;
|
||||
|
||||
/** Flags for a sample */
|
||||
typedef uint32_t SampleFlags;
|
||||
|
||||
/** Default values for samples in the movie/fragment */
|
||||
typedef struct {
|
||||
/** Absolute offset of first mdat byte */
|
||||
uint32_t offset;
|
||||
uint32_t sampleDescriptionId;
|
||||
uint32_t duration;
|
||||
uint32_t size;
|
||||
SampleFlags flags;
|
||||
} SampleDefaults;
|
||||
|
||||
/** Sample Description Table */
|
||||
typedef struct {
|
||||
uint16_t dataReferenceIndex;
|
||||
AudioSampleFormat format;
|
||||
// params for MPEG-4 Elementary Stream Descriptors
|
||||
MP4AObjectType mp4aObjectType;
|
||||
MP4AProfile mp4aProfile;
|
||||
// atom header for unknown descriptors
|
||||
uint32_t dataType;
|
||||
// codec-specific data (either DecoderSpecificInfo or the entire descriptor)
|
||||
uint32_t dataLength;
|
||||
uint8_t *data;
|
||||
} SampleDescription;
|
||||
|
||||
typedef struct {
|
||||
// byte 1 - bits 0:7
|
||||
bool durationIsEmpty : 1;
|
||||
bool defaultBaseIsMoof : 1;
|
||||
bool dummy1 : 6;
|
||||
// byte 2 - bits 0:7
|
||||
uint8_t dummy2 : 8;
|
||||
// byte 3 - bits 0:7
|
||||
bool baseDataOffsetPresent : 1;
|
||||
bool sampleDescriptionIndexPresent : 1;
|
||||
bool dummy3 : 1;
|
||||
bool defaultSampleDurationPresent : 1;
|
||||
bool defaultSampleSizePresent : 1;
|
||||
bool defaultSampleFlagsPresent : 1;
|
||||
bool dummy4 : 2;
|
||||
} TfFlags;
|
||||
|
||||
typedef struct {
|
||||
// byte 1 - bits 0:7
|
||||
uint8_t dummy1 : 8;
|
||||
// byte 2 - bits 0:7
|
||||
bool sampleDurationPresent : 1;
|
||||
bool sampleSizePresent : 1;
|
||||
bool sampleFlagsPresent : 1;
|
||||
bool sampleCompositionTimeOffsetsPresent : 1;
|
||||
bool dummy2 : 4;
|
||||
// byte 3 - bits 0:7
|
||||
bool dataOffsetPresent : 1;
|
||||
bool dummy3 : 1;
|
||||
bool firstSampleFlagsPresent : 1;
|
||||
bool dummy4 : 5;
|
||||
} TrFlags;
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-8.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseContainer.h"
|
||||
#include "Mpeg4Atoms.h"
|
||||
#include <memory>
|
||||
|
||||
class Mpeg4Container : public BaseContainer {
|
||||
public:
|
||||
~Mpeg4Container();
|
||||
/**
|
||||
* Start parsing the MP4 file. This method expects the source to read from 0th byte.
|
||||
* This method leaves pos at first mdat data byte, or mdat header for fMP4 files.
|
||||
*/
|
||||
bool parse() override;
|
||||
int32_t getLoadingOffset(uint32_t timeMs) override;
|
||||
bool seekTo(uint32_t timeMs) override;
|
||||
int32_t getCurrentTimeMs() override;
|
||||
uint8_t *readSample(uint32_t &len) override;
|
||||
uint8_t *getSetupData(uint32_t &len, AudioCodec matchCodec) override;
|
||||
void feed(const std::shared_ptr<bell::ByteStream> &stream, uint32_t position) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Parse a single movie fragment. This method expects the source to read moof data, without the header.
|
||||
* After running, [pos] is left at next mdat header. A new fragment will be created if [pos] does not exist
|
||||
* in [fragments] table.
|
||||
*/
|
||||
bool parseMoof(uint32_t moofSize);
|
||||
bool goToData();
|
||||
// char mediaBrand[5];
|
||||
uint32_t totalDuration;
|
||||
bool totalDurationPresent = false;
|
||||
int8_t audioTrackId = -1;
|
||||
uint32_t timescale = 0;
|
||||
uint32_t sampleSizeMax = 0;
|
||||
uint8_t *sampleData = nullptr;
|
||||
uint32_t sampleDataLen = 0;
|
||||
bool isParsed = false;
|
||||
bool isFragmented = false;
|
||||
/** True if source reads **audio** mdat data bytes, false if source reads atom headers */
|
||||
bool isInData = false;
|
||||
|
||||
private: // data for the entire movie:
|
||||
/** All fragments in the MPEG file */
|
||||
Mpeg4Fragment *fragments;
|
||||
uint16_t fragmentsLen;
|
||||
/** Default sample descriptions for each track */
|
||||
SampleDefaults *sampleDefs;
|
||||
uint32_t sampleDefsLen;
|
||||
/** Track IDs of [sampleDef] items */
|
||||
uint32_t *sampleDefTracks;
|
||||
/** Sample Description Table */
|
||||
SampleDescription *sampleDesc;
|
||||
uint32_t sampleDescLen;
|
||||
|
||||
private: // data changing every fragment:
|
||||
/** Chunks in the current fragment */
|
||||
Mpeg4ChunkRange *chunks;
|
||||
uint32_t chunksLen;
|
||||
/** Absolute chunk offsets in the current fragment */
|
||||
Mpeg4ChunkOffset *chunkOffsets;
|
||||
uint32_t chunkOffsetsLen;
|
||||
/** All sample descriptors in the current fragment */
|
||||
Mpeg4SampleRange *samples;
|
||||
uint32_t samplesLen;
|
||||
/** All sample sizes in the current fragment */
|
||||
Mpeg4SampleSize *sampleSizes;
|
||||
uint32_t sampleSizesLen;
|
||||
|
||||
private: // current status and position within the file
|
||||
/** Currently loaded fragment (ptr) */
|
||||
Mpeg4Fragment *curFragment;
|
||||
/** The chunk currently being processed */
|
||||
Mpeg4Chunk curChunk;
|
||||
/** Size of the current sample (ptr) */
|
||||
Mpeg4SampleSize *curSampleSize;
|
||||
|
||||
private: // Mpeg4Utils.cpp
|
||||
void readAtomHeader(uint32_t &size, uint32_t &type);
|
||||
void freeAll();
|
||||
void freeFragment();
|
||||
SampleDefaults *getSampleDef(uint32_t trackId);
|
||||
void setCurrentFragment();
|
||||
void setCurrentSample();
|
||||
static bool isInFragment(Mpeg4Fragment *f, uint32_t offset);
|
||||
static AudioCodec getCodec(SampleDescription *desc);
|
||||
Mpeg4Fragment *createFragment();
|
||||
int64_t findSample(int64_t byTime, int32_t byPos, uint64_t startTime);
|
||||
|
||||
private: // Mpeg4Parser.cpp
|
||||
/** Populate [chunks] using the Sample-to-chunk Table */
|
||||
void readStsc();
|
||||
/** Populate [chunkOffsets] using the Chunk Offset Table */
|
||||
void readStco();
|
||||
/** Populate [samples] using the Time-to-sample Table */
|
||||
void readStts();
|
||||
/** Populate [sampleSizes] using the Sample Size Table */
|
||||
void readStsz();
|
||||
/** Populate [sampleDesc] using the Sample Description Table */
|
||||
void readStsd();
|
||||
|
||||
private: // Mpeg4ParserFrag.cpp
|
||||
/** Populate [fragments] using the Segment Index Table */
|
||||
void readSidx(uint32_t atomSize);
|
||||
/** Populate [sampleDefs] using Track Extends */
|
||||
void readTrex();
|
||||
/** Populate [sampleDefs] using Track Fragment Header */
|
||||
void readTfhd(uint32_t trafEnd, uint32_t moofOffset);
|
||||
/** Populate [chunks, chunkOffsets, samples, sampleSizes] using Track Fragment Run Table */
|
||||
void readTrun(uint32_t atomSize, uint32_t moofOffset);
|
||||
void allocSampleData();
|
||||
};
|
||||
@@ -0,0 +1,206 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-12.
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class AtomType {
|
||||
/** File Type */
|
||||
ATOM_FTYP = 0x66747970,
|
||||
/** Movie */
|
||||
ATOM_MOOV = 0x6D6F6F76,
|
||||
/** Movie Header */
|
||||
ATOM_MVHD = 0x6D766864,
|
||||
/** Movie Extends */
|
||||
ATOM_MVEX = 0x6D766578,
|
||||
/** Movie Extends Header */
|
||||
ATOM_MEHD = 0x6D656864,
|
||||
/** Track Extends */
|
||||
ATOM_TREX = 0x74726578,
|
||||
/** Track */
|
||||
ATOM_TRAK = 0x7472616B,
|
||||
/** Track Header */
|
||||
ATOM_TKHD = 0x746B6864,
|
||||
/** Edit */
|
||||
ATOM_EDTS = 0x65647473,
|
||||
/** Edit List */
|
||||
ATOM_ELST = 0x656C7374,
|
||||
/** Media */
|
||||
ATOM_MDIA = 0x6D646961,
|
||||
/** Media Header */
|
||||
ATOM_MDHD = 0x6D646864,
|
||||
/** Handler Reference */
|
||||
ATOM_HDLR = 0x68646C72,
|
||||
/** Handler Type - Sound */
|
||||
ATOM_SOUN = 0x736F756E,
|
||||
/** Handler Type - Video */
|
||||
ATOM_VIDE = 0x76696465,
|
||||
/** Handler Type - Subtitle */
|
||||
ATOM_SUBT = 0x73756274,
|
||||
/** Media Information */
|
||||
ATOM_MINF = 0x6D696E66,
|
||||
/** Data Information */
|
||||
ATOM_DINF = 0x64696E66,
|
||||
/** Data Reference */
|
||||
ATOM_DREF = 0x64726566,
|
||||
/** Data Entry Url */
|
||||
ATOM_URL = 0x75726C20,
|
||||
/** Sample Table */
|
||||
ATOM_STBL = 0x7374626C,
|
||||
/** Sample Description */
|
||||
ATOM_STSD = 0x73747364,
|
||||
/** siDecompressionParam */
|
||||
ATOM_WAVE = 0x77617665,
|
||||
/** Format Atom */
|
||||
ATOM_FRMA = 0x66726D61,
|
||||
/** Audio Channel Layout Atom */
|
||||
ATOM_CHAN = 0x6368616E,
|
||||
/** Terminator Atom */
|
||||
ATOM_TERM = 0x00000000,
|
||||
/** MPEG-4 Elementary Stream Descriptor */
|
||||
ATOM_ESDS = 0x65736473,
|
||||
/** Time-to-sample Table */
|
||||
ATOM_STTS = 0x73747473,
|
||||
/** Sync Sample Table */
|
||||
ATOM_STSS = 0x73747373,
|
||||
/** Sample-to-chunk Table */
|
||||
ATOM_STSC = 0x73747363,
|
||||
/** Chunk Offset Table */
|
||||
ATOM_STCO = 0x7374636F,
|
||||
/** Sample Size Table */
|
||||
ATOM_STSZ = 0x7374737A,
|
||||
/** Sound Media Header */
|
||||
ATOM_SMHD = 0x736D6864,
|
||||
/** Segment Index Table */
|
||||
ATOM_SIDX = 0x73696478,
|
||||
/** Movie Fragment */
|
||||
ATOM_MOOF = 0x6D6F6F66,
|
||||
/** Movie Fragment Header */
|
||||
ATOM_MFHD = 0x6D666864,
|
||||
/** Track Fragment */
|
||||
ATOM_TRAF = 0x74726166,
|
||||
/** Track Fragment Header */
|
||||
ATOM_TFHD = 0x74666864,
|
||||
/** Track Fragment Run */
|
||||
ATOM_TRUN = 0x7472756E,
|
||||
/** Media Data */
|
||||
ATOM_MDAT = 0x6D646174,
|
||||
};
|
||||
|
||||
// These formats are the direct sub-children of the stsd atom.
|
||||
// https://mp4ra.org/#/codecs (+additions)
|
||||
enum class AudioSampleFormat {
|
||||
UNDEFINED = 0,
|
||||
A3DS = 0x61336473, // Auro-Cx 3D audio
|
||||
AC3 = 0x61632d33, // AC-3 audio
|
||||
AC4 = 0x61632d34, // AC-4 audio
|
||||
AGSM = 0x6167736d, // GSM
|
||||
ALAC = 0x616c6163, // Apple lossless audio codec
|
||||
ALAW = 0x616c6177, // a-Law
|
||||
CAVS = 0x63617673, // AVS2-P3 codec
|
||||
DRA1 = 0x64726131, // DRA Audio
|
||||
DTS_MINUS = 0x6474732d, // Dependent base layer for DTS layered audio
|
||||
DTS_PLUS = 0x6474732b, // Enhancement layer for DTS layered audio
|
||||
DTSC = 0x64747363, // Core Substream
|
||||
DTSE = 0x64747365, // Extension Substream containing only LBR
|
||||
DTSH = 0x64747368, // Core Substream + Extension Substream
|
||||
DTSL = 0x6474736c, // Extension Substream containing only XLL
|
||||
DTSX = 0x64747378, // DTS-UHD profile 2
|
||||
DTSY = 0x64747379, // DTS-UHD profile 3 or higher
|
||||
DVI = 0x64766920, // DVI (as used in RTP, 4:1 compression)
|
||||
EC3 = 0x65632d33, // Enhanced AC-3 audio
|
||||
ENCA = 0x656e6361, // Encrypted/Protected audio
|
||||
FL32 = 0x666c3332, // 32 bit float
|
||||
FL64 = 0x666c3634, // 64 bit float
|
||||
FLAC = 0x664c6143, // Free Lossless Audio Codec
|
||||
G719 = 0x67373139, // ITU-T Recommendation G.719 (2008)
|
||||
G726 = 0x67373236, // ITU-T Recommendation G.726 (1990)
|
||||
IMA4 = 0x696d6134, // IMA (International Multimedia Assocation, defunct, 4:1)
|
||||
IN24 = 0x696e3234, // 24 bit integer uncompressed
|
||||
IN32 = 0x696e3332, // 32 bit integer uncompressed
|
||||
LPCM = 0x6c70636d, // Uncompressed audio (various integer and float formats)
|
||||
M4AE = 0x6d346165, // MPEG-4 Audio Enhancement
|
||||
MHA1 = 0x6d686131, // MPEG-H Audio (single stream, unencapsulated)
|
||||
MHA2 = 0x6d686132, // MPEG-H Audio (multi-stream, unencapsulated)
|
||||
MHM1 = 0x6d686d31, // MPEG-H Audio (single stream, MHAS encapsulated)
|
||||
MHM2 = 0x6d686d32, // MPEG-H Audio (multi-stream, MHAS encapsulated)
|
||||
MLPA = 0x6d6c7061, // MLP Audio
|
||||
MP4A = 0x6d703461, // MPEG-4 Audio
|
||||
OPUS = 0x4f707573, // Opus audio coding
|
||||
QCLP = 0x51636c70, // Qualcomm PureVoice
|
||||
QDM2 = 0x51444d32, // Qdesign music 2
|
||||
QDMC = 0x51444d43, // Qdesign music 1
|
||||
RAW = 0x72617720, // Uncompressed audio
|
||||
SAMR = 0x73616d72, // Narrowband AMR voice
|
||||
SAWB = 0x73617762, // Wideband AMR voice
|
||||
SAWP = 0x73617770, // Extended AMR-WB (AMR-WB+)
|
||||
SEVC = 0x73657663, // EVRC Voice
|
||||
SEVS = 0x73657673, // Enhanced Voice Services (EVS)
|
||||
SQCP = 0x73716370, // 13K Voice
|
||||
SSMV = 0x73736d76, // SMV Voice
|
||||
TWOS = 0x74776f73, // Uncompressed 16-bit audio
|
||||
ULAW = 0x756c6177, // Samples have been compressed using uLaw 2:1.
|
||||
VDVA = 0x76647661, // DV audio (variable duration per video frame)
|
||||
};
|
||||
|
||||
// These are present in the DecoderConfigDescriptor tag in ESDS (for AudioSampleFormat::FORMAT_MP4A).
|
||||
// Source: https://mp4ra.org/#/codecs
|
||||
enum class MP4AObjectType {
|
||||
UNDEFINED = 0,
|
||||
_13K = 0xE1, // 13K Voice
|
||||
AAC_LC = 0x67, // ISO/IEC 13818-7 (AAC) Low Complexity Profile
|
||||
AAC_MAIN = 0x66, // ISO/IEC 13818-7 (AAC) Main Profile
|
||||
AAC_SSR = 0x68, // ISO/IEC 13818-7 (AAC) Scaleable Sampling Rate Profile
|
||||
AC3 = 0xA5, // AC-3
|
||||
AC3_ENH = 0xA6, // Enhanced AC-3
|
||||
AC4 = 0xAE, // AC-4
|
||||
AURO_CX_3D = 0xAF, // Auro-Cx 3D audio
|
||||
DRA = 0xA7, // DRA Audio
|
||||
DTS_CORE = 0xA9, // Core Substream
|
||||
DTS_CORE_EXT = 0xAA, // Core Substream + Extension Substream
|
||||
DTS_LBR = 0xAC, // Extension Substream containing only LBR
|
||||
DTS_UHD2 = 0xB2, // DTS-UHD profile 2
|
||||
DTS_UHD3 = 0xB3, // DTS-UHD profile 3 or higher
|
||||
DTS_XLL = 0xAB, // Extension Substream containing only XLL
|
||||
EVRC = 0xA0, // EVRC Voice
|
||||
G719 = 0xA8, // ITU G.719 Audio
|
||||
MP4A = 0x40, // ISO/IEC 14496-3 (MPEG-4 Audio)
|
||||
MPEG1 = 0x6B, // ISO/IEC 11172-3 (MPEG-1 Part 3)
|
||||
MPEG2 = 0x69, // ISO/IEC 13818-3 (MPEG-2 Part 3)
|
||||
OPUS = 0xAD, // Opus audio
|
||||
SMV = 0xA1, // SMV Voice
|
||||
VORBIS = 0xDD, // Vorbis
|
||||
};
|
||||
|
||||
// These are present in the DecoderSpecificInfo tag in ESDS (for MP4AObjectType::TYPE_MP4A).
|
||||
// Source: https://wiki.multimedia.cx/index.php/MPEG-4_Audio
|
||||
enum class MP4AProfile {
|
||||
UNDEFINED = 0,
|
||||
AAC_MAIN = 1, // AAC main
|
||||
AAC_LC = 2, // AAC LC
|
||||
AAC_SSR = 3, // AAC SSR
|
||||
AAC_LTP = 4, // AAC LTP
|
||||
SBR = 5, // SBR
|
||||
AAC_SCALABLE = 6, // AAC Scalable
|
||||
TWINVQ = 7, // TwinVQ
|
||||
CELP = 8, // CELP
|
||||
HVXC = 9, // HVXC
|
||||
TTSI = 12, // TTSI
|
||||
MAIN_SYNTHETIC = 13, // Main synthetic
|
||||
WAVETABLE_SYNTHESIS = 14, // Wavetable synthesis
|
||||
GENERAL_MIDI = 15, // General MIDI
|
||||
ALGORITHMIC_SYNTHESIS_AND_AUDIO_FX = 16, // Algorithmic Synthesis and Audio FX
|
||||
ER_AAC_LC = 17, // ER AAC LC
|
||||
ER_AAC_LTP = 19, // ER AAC LTP
|
||||
ER_AAC_SCALABLE = 20, // ER AAC Scalable
|
||||
ER_TWINVQ = 21, // ER TwinVQ
|
||||
ER_BSAC = 22, // ER BSAC
|
||||
ER_AAC_LD = 23, // ER AAC LD
|
||||
ER_CELP = 24, // ER CELP
|
||||
ER_HVXC = 25, // ER HVXC
|
||||
ER_HILN = 26, // ER HILN
|
||||
ER_PARAMETRIC = 27, // ER Parametric
|
||||
SSC = 28, // SSC
|
||||
LAYER_1 = 32, // Layer-1
|
||||
LAYER_2 = 33, // Layer-2
|
||||
LAYER_3 = 34, // Layer-3
|
||||
DST = 35, // DST
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-16.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseContainer.h"
|
||||
|
||||
enum class ElementId;
|
||||
|
||||
class WebmContainer : public BaseContainer {
|
||||
public:
|
||||
~WebmContainer();
|
||||
bool parse() override;
|
||||
int32_t getLoadingOffset(uint32_t timeMs) override;
|
||||
bool seekTo(uint32_t timeMs) override;
|
||||
int32_t getCurrentTimeMs() override;
|
||||
uint8_t *readSample(uint32_t &len) override;
|
||||
uint8_t *getSetupData(uint32_t &len, AudioCodec matchCodec) override;
|
||||
void feed(const std::shared_ptr<bell::ByteStream> &stream, uint32_t position) override;
|
||||
|
||||
private:
|
||||
typedef struct {
|
||||
uint32_t time;
|
||||
uint32_t offset;
|
||||
} CuePoint;
|
||||
|
||||
private:
|
||||
// used while parsing
|
||||
uint32_t esize;
|
||||
ElementId eid;
|
||||
// container parameters
|
||||
char *docType = nullptr;
|
||||
uint8_t audioTrackId = 255;
|
||||
float timescale = 0.0f;
|
||||
char *codecId = nullptr;
|
||||
uint8_t *codecPrivate = nullptr;
|
||||
uint32_t codecPrivateLen = 0;
|
||||
// container state
|
||||
CuePoint *cues = nullptr;
|
||||
uint16_t cuesLen = 0;
|
||||
uint32_t clusterEnd = 0;
|
||||
uint32_t clusterTime = 0;
|
||||
uint32_t currentTime = 0;
|
||||
bool isParsed = false;
|
||||
// buffer
|
||||
uint8_t *sampleData = nullptr;
|
||||
uint32_t sampleLen = 0;
|
||||
// lacing parameters
|
||||
uint32_t *laceSizes = nullptr;
|
||||
uint32_t *laceCurrent = nullptr;
|
||||
uint8_t laceLeft = 0;
|
||||
// set to read the current buffer instead of loading new frames
|
||||
uint16_t readOutFrameSize = 0;
|
||||
|
||||
private:
|
||||
uint32_t readVarNum32(bool raw = false);
|
||||
uint64_t readVarNum64();
|
||||
uint32_t readUint(uint8_t len);
|
||||
uint64_t readUlong(uint8_t len);
|
||||
float readFloat(uint8_t len);
|
||||
void readElem();
|
||||
void parseSegment(uint32_t start);
|
||||
void parseTrack(uint32_t end);
|
||||
void parseCuePoint(uint16_t idx, uint32_t end, uint32_t segmentStart);
|
||||
/**
|
||||
* Continue reading elements until a block is encountered.
|
||||
*
|
||||
* If [untilTime] is set, the method will keep reading until [currentTime]
|
||||
* is less than [untilTime]. Because of how WebM works, [pos] will be one frame later
|
||||
* than the requested time, although the container will report the correct position.
|
||||
*
|
||||
* @return size of the frame pointed by [pos]
|
||||
*/
|
||||
uint32_t readCluster(uint32_t untilTime = 0);
|
||||
/**
|
||||
* Parse a single block within a cluster. This method will populate lacing parameters if needed.
|
||||
* @param end offset of the next byte after this block
|
||||
* @return size of the frame pointed by [pos]
|
||||
*/
|
||||
uint32_t readBlock(uint32_t end);
|
||||
uint8_t *readFrame(uint32_t size, uint32_t &outLen);
|
||||
};
|
||||
@@ -0,0 +1,713 @@
|
||||
// Copyright (c) Kuba Szczodrzyński 2022-1-16.
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class ElementId {
|
||||
/** [sub-elements] Set the EBML characteristics of the data to follow. Each EBML document has to start with this. */
|
||||
EBML = 0x1A45DFA3,
|
||||
/** [u-integer] The version of EBML parser used to create the file. */
|
||||
EBMLVersion = 0x4286,
|
||||
/** [u-integer] The minimum EBML version a parser has to support to read this file. */
|
||||
EBMLReadVersion = 0x42F7,
|
||||
/** [u-integer] The maximum length of the IDs you'll find in this file (4 or less in Matroska). */
|
||||
EBMLMaxIDLength = 0x42F2,
|
||||
/** [u-integer] The maximum length of the sizes you'll find in this file (8 or less in Matroska). This does not
|
||||
override the element size indicated at the beginning of an element. Elements that have an indicated size which is
|
||||
larger than what is allowed by EBMLMaxSizeLength shall be considered invalid. */
|
||||
EBMLMaxSizeLength = 0x42F3,
|
||||
/** [string] A string that describes the type of document that follows this EBML header ('matroska' in our case). */
|
||||
DocType = 0x4282,
|
||||
/** [u-integer] The version of DocType interpreter used to create the file. */
|
||||
DocTypeVersion = 0x4287,
|
||||
/** [u-integer] The minimum DocType version an interpreter has to support to read this file. */
|
||||
DocTypeReadVersion = 0x4285,
|
||||
/** [binary] The CRC is computed on all the data from the last CRC element (or start of the upper level element), up
|
||||
to the CRC element, including other previous CRC elements. All level 1 elements should include a CRC-32. */
|
||||
CRC32 = 0xBF,
|
||||
/** [binary] Used to void damaged data, to avoid unexpected behaviors when using damaged data. The content is
|
||||
discarded. Also used to reserve space in a sub-element for later use. */
|
||||
Void = 0xEC,
|
||||
/** [sub-elements] Contain signature of some (coming) elements in the stream. */
|
||||
SignatureSlot = 0x1B538667,
|
||||
/** [u-integer] Signature algorithm used (1=RSA, 2=elliptic). */
|
||||
SignatureAlgo = 0x7E8A,
|
||||
/** [u-integer] Hash algorithm used (1=SHA1-160, 2=MD5). */
|
||||
SignatureHash = 0x7E9A,
|
||||
/** [binary] The public key to use with the algorithm (in the case of a PKI-based signature). */
|
||||
SignaturePublicKey = 0x7EA5,
|
||||
/** [binary] The signature of the data (until a new. */
|
||||
Signature = 0x7EB5,
|
||||
/** [sub-elements] Contains elements that will be used to compute the signature. */
|
||||
SignatureElements = 0x7E5B,
|
||||
/** [sub-elements] A list consists of a number of consecutive elements that represent one case where data is used in
|
||||
signature. Ex: Cluster|Block|BlockAdditional means that the BlockAdditional of all Blocks in all Clusters is used
|
||||
for encryption. */
|
||||
SignatureElementList = 0x7E7B,
|
||||
/** [binary] An element ID whose data will be used to compute the signature. */
|
||||
SignedElement = 0x6532,
|
||||
|
||||
/* ebml_matroska.xml */
|
||||
/** [master] The Root Element that contains all other Top-Level Elements (Elements defined only at Level 1). A
|
||||
Matroska file is composed of 1 Segment. */
|
||||
Segment = 0x18538067,
|
||||
/** [master] Contains the Segment Position of other Top-Level Elements. */
|
||||
SeekHead = 0x114D9B74,
|
||||
/** [master] Contains a single seek entry to an EBML Element. */
|
||||
Seek = 0x4DBB,
|
||||
/** [binary] The binary ID corresponding to the Element name. */
|
||||
SeekID = 0x53AB,
|
||||
/** [uinteger] The Segment Position of the Element. */
|
||||
SeekPosition = 0x53AC,
|
||||
/** [master] Contains general information about the Segment. */
|
||||
Info = 0x1549A966,
|
||||
/** [binary] A randomly generated unique ID to identify the Segment amongst many others (128 bits). */
|
||||
SegmentUID = 0x73A4,
|
||||
/** [utf-8] A filename corresponding to this Segment. */
|
||||
SegmentFilename = 0x7384,
|
||||
/** [binary] A unique ID to identify the previous Segment of a Linked Segment (128 bits). */
|
||||
PrevUID = 0x3CB923,
|
||||
/** [utf-8] A filename corresponding to the file of the previous Linked Segment. */
|
||||
PrevFilename = 0x3C83AB,
|
||||
/** [binary] A unique ID to identify the next Segment of a Linked Segment (128 bits). */
|
||||
NextUID = 0x3EB923,
|
||||
/** [utf-8] A filename corresponding to the file of the next Linked Segment. */
|
||||
NextFilename = 0x3E83BB,
|
||||
/** [binary] A randomly generated unique ID that all Segments of a Linked Segment **MUST** share (128 bits). */
|
||||
SegmentFamily = 0x4444,
|
||||
/** [master] The mapping between this `Segment` and a segment value in the given Chapter Codec. */
|
||||
ChapterTranslate = 0x6924,
|
||||
/** [binary] The binary value used to represent this Segment in the chapter codec data. The format depends on the
|
||||
ChapProcessCodecID used; see (#chapprocesscodecid-element). */
|
||||
ChapterTranslateID = 0x69A5,
|
||||
/** [uinteger] This `ChapterTranslate` applies to this chapter codec of the given chapter edition(s); see
|
||||
(#chapprocesscodecid-element). */
|
||||
ChapterTranslateCodec = 0x69BF,
|
||||
/** [uinteger] Specify a chapter edition UID on which this `ChapterTranslate` applies. */
|
||||
ChapterTranslateEditionUID = 0x69FC,
|
||||
/** [uinteger] Timestamp scale in nanoseconds (1.000.000 means all timestamps in the Segment are expressed in
|
||||
milliseconds). */
|
||||
TimestampScale = 0x2AD7B1,
|
||||
/** [float] Duration of the Segment in nanoseconds based on TimestampScale. */
|
||||
Duration = 0x4489,
|
||||
/** [date] The date and time that the Segment was created by the muxing application or library. */
|
||||
DateUTC = 0x4461,
|
||||
/** [utf-8] General name of the Segment. */
|
||||
Title = 0x7BA9,
|
||||
/** [utf-8] Muxing application or library (example: "libmatroska-0.4.3"). */
|
||||
MuxingApp = 0x4D80,
|
||||
/** [utf-8] Writing application (example: "mkvmerge-0.3.3"). */
|
||||
WritingApp = 0x5741,
|
||||
/** [master] The Top-Level Element containing the (monolithic) Block structure. */
|
||||
Cluster = 0x1F43B675,
|
||||
/** [uinteger] Absolute timestamp of the cluster (based on TimestampScale). */
|
||||
Timestamp = 0xE7,
|
||||
/** [master] The list of tracks that are not used in that part of the stream. It is useful when using overlay tracks
|
||||
on seeking or to decide what track to use. */
|
||||
SilentTracks = 0x5854,
|
||||
/** [uinteger] One of the track number that are not used from now on in the stream. It could change later if not
|
||||
specified as silent in a further Cluster. */
|
||||
SilentTrackNumber = 0x58D7,
|
||||
/** [uinteger] The Segment Position of the Cluster in the Segment (0 in live streams). It might help to
|
||||
resynchronise offset on damaged streams. */
|
||||
Position = 0xA7,
|
||||
/** [uinteger] Size of the previous Cluster, in octets. Can be useful for backward playing. */
|
||||
PrevSize = 0xAB,
|
||||
/** [binary] Similar to Block, see (#block-structure), but without all the extra information, mostly used to reduced
|
||||
overhead when no extra feature is needed; see (#simpleblock-structure) on SimpleBlock Structure. */
|
||||
SimpleBlock = 0xA3,
|
||||
/** [master] Basic container of information containing a single Block and information specific to that Block. */
|
||||
BlockGroup = 0xA0,
|
||||
/** [binary] Block containing the actual data to be rendered and a timestamp relative to the Cluster Timestamp; see
|
||||
(#block-structure) on Block Structure. */
|
||||
Block = 0xA1,
|
||||
/** [binary] A Block with no data. It **MUST** be stored in the stream at the place the real Block would be in
|
||||
display order. */
|
||||
BlockVirtual = 0xA2,
|
||||
/** [master] Contain additional blocks to complete the main one. An EBML parser that has no knowledge of the Block
|
||||
structure could still see and use/skip these data. */
|
||||
BlockAdditions = 0x75A1,
|
||||
/** [master] Contain the BlockAdditional and some parameters. */
|
||||
BlockMore = 0xA6,
|
||||
/** [uinteger] An ID to identify the BlockAdditional level. If BlockAddIDType of the corresponding block is 0, this
|
||||
value is also the value of BlockAddIDType for the meaning of the content of BlockAdditional. */
|
||||
BlockAddID = 0xEE,
|
||||
/** [binary] Interpreted by the codec as it wishes (using the BlockAddID). */
|
||||
BlockAdditional = 0xA5,
|
||||
/** [uinteger] The duration of the Block (based on TimestampScale). The BlockDuration Element can be useful at the
|
||||
end of a Track to define the duration of the last frame (as there is no subsequent Block available), or when
|
||||
there is a break in a track like for subtitle tracks. */
|
||||
BlockDuration = 0x9B,
|
||||
/** [uinteger] This frame is referenced and has the specified cache priority. In cache only a frame of the same or
|
||||
higher priority can replace this frame. A value of 0 means the frame is not referenced. */
|
||||
ReferencePriority = 0xFA,
|
||||
/** [integer] A timestamp value, relative to the timestamp of the Block in this BlockGroup. This is used to
|
||||
reference other frames necessary to decode this frame. The relative value **SHOULD** correspond to a valid
|
||||
`Block` this `Block` depends on. Historically Matroska Writer didn't write the actual `Block(s)` this `Block`
|
||||
depends on, but *some* `Block` in the past. The value "0" **MAY** also be used to signify this `Block` cannot be
|
||||
decoded on its own, but without knownledge of which `Block` is necessary. In this case, other `ReferenceBlock`
|
||||
**MUST NOT** be found in the same `BlockGroup`. If the `BlockGroup` doesn't have any `ReferenceBlock` element,
|
||||
then the `Block` it contains can be decoded without using any other `Block` data. */
|
||||
ReferenceBlock = 0xFB,
|
||||
/** [integer] The Segment Position of the data that would otherwise be in position of the virtual block. */
|
||||
ReferenceVirtual = 0xFD,
|
||||
/** [binary] The new codec state to use. Data interpretation is private to the codec. This information **SHOULD**
|
||||
always be referenced by a seek entry. */
|
||||
CodecState = 0xA4,
|
||||
/** [integer] Duration in nanoseconds of the silent data added to the Block (padding at the end of the Block for
|
||||
positive value, at the beginning of the Block for negative value). The duration of DiscardPadding is not
|
||||
calculated in the duration of the TrackEntry and **SHOULD** be discarded during playback. */
|
||||
DiscardPadding = 0x75A2,
|
||||
/** [master] Contains slices description. */
|
||||
Slices = 0x8E,
|
||||
/** [master] Contains extra time information about the data contained in the Block. Being able to interpret this
|
||||
Element is not **REQUIRED** for playback. */
|
||||
TimeSlice = 0xE8,
|
||||
/** [uinteger] The reverse number of the frame in the lace (0 is the last frame, 1 is the next to last, etc). Being
|
||||
able to interpret this Element is not **REQUIRED** for playback. */
|
||||
LaceNumber = 0xCC,
|
||||
/** [uinteger] The number of the frame to generate from this lace with this delay (allow you to generate many frames
|
||||
from the same Block/Frame). */
|
||||
FrameNumber = 0xCD,
|
||||
/** [uinteger] The ID of the BlockAdditional Element (0 is the main Block). */
|
||||
BlockAdditionID = 0xCB,
|
||||
/** [uinteger] The (scaled) delay to apply to the Element. */
|
||||
Delay = 0xCE,
|
||||
/** [uinteger] The (scaled) duration to apply to the Element. */
|
||||
SliceDuration = 0xCF,
|
||||
/** [master] Contains information about the last reference frame. See [@?DivXTrickTrack]. */
|
||||
ReferenceFrame = 0xC8,
|
||||
/** [uinteger] The relative offset, in bytes, from the previous BlockGroup element for this Smooth FF/RW video track
|
||||
to the containing BlockGroup element. See [@?DivXTrickTrack]. */
|
||||
ReferenceOffset = 0xC9,
|
||||
/** [uinteger] The timecode of the BlockGroup pointed to by ReferenceOffset. See [@?DivXTrickTrack]. */
|
||||
ReferenceTimestamp = 0xCA,
|
||||
/** [binary] Similar to SimpleBlock, see (#simpleblock-structure), but the data inside the Block are Transformed
|
||||
(encrypt and/or signed). */
|
||||
EncryptedBlock = 0xAF,
|
||||
/** [master] A Top-Level Element of information with many tracks described. */
|
||||
Tracks = 0x1654AE6B,
|
||||
/** [master] Describes a track with all Elements. */
|
||||
TrackEntry = 0xAE,
|
||||
/** [uinteger] The track number as used in the Block Header (using more than 127 tracks is not encouraged, though
|
||||
the design allows an unlimited number). */
|
||||
TrackNumber = 0xD7,
|
||||
/** [uinteger] A unique ID to identify the Track. */
|
||||
TrackUID = 0x73C5,
|
||||
/** [uinteger] The `TrackType` defines the type of each frame found in the Track. The value **SHOULD** be stored on
|
||||
1 octet. */
|
||||
TrackType = 0x83,
|
||||
/** [uinteger] Set to 1 if the track is usable. It is possible to turn a not usable track into a usable track using
|
||||
chapter codecs or control tracks. */
|
||||
FlagEnabled = 0xB9,
|
||||
/** [uinteger] Set if that track (audio, video or subs) **SHOULD** be eligible for automatic selection by the
|
||||
player; see (#default-track-selection) for more details. */
|
||||
FlagDefault = 0x88,
|
||||
/** [uinteger] Applies only to subtitles. Set if that track **SHOULD** be eligible for automatic selection by the
|
||||
player if it matches the user's language preference, even if the user's preferences would normally not enable
|
||||
subtitles with the selected audio track; this can be used for tracks containing only translations of
|
||||
foreign-language audio or onscreen text. See (#default-track-selection) for more details. */
|
||||
FlagForced = 0x55AA,
|
||||
/** [uinteger] Set to 1 if that track is suitable for users with hearing impairments, set to 0 if it is unsuitable
|
||||
for users with hearing impairments. */
|
||||
FlagHearingImpaired = 0x55AB,
|
||||
/** [uinteger] Set to 1 if that track is suitable for users with visual impairments, set to 0 if it is unsuitable
|
||||
for users with visual impairments. */
|
||||
FlagVisualImpaired = 0x55AC,
|
||||
/** [uinteger] Set to 1 if that track contains textual descriptions of video content, set to 0 if that track does
|
||||
not contain textual descriptions of video content. */
|
||||
FlagTextDescriptions = 0x55AD,
|
||||
/** [uinteger] Set to 1 if that track is in the content's original language, set to 0 if it is a translation. */
|
||||
FlagOriginal = 0x55AE,
|
||||
/** [uinteger] Set to 1 if that track contains commentary, set to 0 if it does not contain commentary. */
|
||||
FlagCommentary = 0x55AF,
|
||||
/** [uinteger] Set to 1 if the track **MAY** contain blocks using lacing. When set to 0 all blocks **MUST** have
|
||||
their lacing flags set to No lacing; see (#block-lacing) on Block Lacing. */
|
||||
FlagLacing = 0x9C,
|
||||
/** [uinteger] The minimum number of frames a player **SHOULD** be able to cache during playback. If set to 0, the
|
||||
reference pseudo-cache system is not used. */
|
||||
MinCache = 0x6DE7,
|
||||
/** [uinteger] The maximum cache size necessary to store referenced frames in and the current frame. 0 means no
|
||||
cache is needed. */
|
||||
MaxCache = 0x6DF8,
|
||||
/** [uinteger] Number of nanoseconds (not scaled via TimestampScale) per frame (frame in the Matroska sense -- one
|
||||
Element put into a (Simple)Block). */
|
||||
DefaultDuration = 0x23E383,
|
||||
/** [uinteger] The period in nanoseconds (not scaled by TimestampScale) between two successive fields at the output
|
||||
of the decoding process, see (#defaultdecodedfieldduration) for more information */
|
||||
DefaultDecodedFieldDuration = 0x234E7A,
|
||||
/** [float] DEPRECATED, DO NOT USE. The scale to apply on this track to work at normal speed in relation with other
|
||||
tracks (mostly used to adjust video speed when the audio length differs). */
|
||||
TrackTimestampScale = 0x23314F,
|
||||
/** [integer] A value to add to the Block's Timestamp. This can be used to adjust the playback offset of a track. */
|
||||
TrackOffset = 0x537F,
|
||||
/** [uinteger] The maximum value of BlockAddID ((#blockaddid-element)). A value 0 means there is no BlockAdditions
|
||||
((#blockadditions-element)) for this track. */
|
||||
MaxBlockAdditionID = 0x55EE,
|
||||
/** [master] Contains elements that extend the track format, by adding content either to each frame, with BlockAddID
|
||||
((#blockaddid-element)), or to the track as a whole with BlockAddIDExtraData. */
|
||||
BlockAdditionMapping = 0x41E4,
|
||||
/** [uinteger] If the track format extension needs content beside frames, the value refers to the BlockAddID
|
||||
((#blockaddid-element)), value being described. To keep MaxBlockAdditionID as low as possible, small values
|
||||
**SHOULD** be used. */
|
||||
BlockAddIDValue = 0x41F0,
|
||||
/** [string] A human-friendly name describing the type of BlockAdditional data, as defined by the associated Block
|
||||
Additional Mapping. */
|
||||
BlockAddIDName = 0x41A4,
|
||||
/** [uinteger] Stores the registered identifier of the Block Additional Mapping to define how the BlockAdditional
|
||||
data should be handled. */
|
||||
BlockAddIDType = 0x41E7,
|
||||
/** [binary] Extra binary data that the BlockAddIDType can use to interpret the BlockAdditional data. The
|
||||
interpretation of the binary data depends on the BlockAddIDType value and the corresponding Block Additional
|
||||
Mapping. */
|
||||
BlockAddIDExtraData = 0x41ED,
|
||||
/** [utf-8] A human-readable track name. */
|
||||
Name = 0x536E,
|
||||
/** [string] Specifies the language of the track in the Matroska languages form; see (#language-codes) on language
|
||||
codes. This Element **MUST** be ignored if the LanguageIETF Element is used in the same TrackEntry. */
|
||||
Language = 0x22B59C,
|
||||
/** [string] Specifies the language of the track according to [@!BCP47] and using the IANA Language Subtag Registry
|
||||
[@!IANALangRegistry]. If this Element is used, then any Language Elements used in the same TrackEntry **MUST** be
|
||||
ignored. */
|
||||
LanguageIETF = 0x22B59D,
|
||||
/** [string] An ID corresponding to the codec, see [@!MatroskaCodec] for more info. */
|
||||
CodecID = 0x86,
|
||||
/** [binary] Private data only known to the codec. */
|
||||
CodecPrivate = 0x63A2,
|
||||
/** [utf-8] A human-readable string specifying the codec. */
|
||||
CodecName = 0x258688,
|
||||
/** [uinteger] The UID of an attachment that is used by this codec. */
|
||||
AttachmentLink = 0x7446,
|
||||
/** [utf-8] A string describing the encoding setting used. */
|
||||
CodecSettings = 0x3A9697,
|
||||
/** [string] A URL to find information about the codec used. */
|
||||
CodecInfoURL = 0x3B4040,
|
||||
/** [string] A URL to download about the codec used. */
|
||||
CodecDownloadURL = 0x26B240,
|
||||
/** [uinteger] Set to 1 if the codec can decode potentially damaged data. */
|
||||
CodecDecodeAll = 0xAA,
|
||||
/** [uinteger] Specify that this track is an overlay track for the Track specified (in the u-integer). That means
|
||||
when this track has a gap, see (#silenttracks-element) on SilentTracks, the overlay track **SHOULD** be used
|
||||
instead. The order of multiple TrackOverlay matters, the first one is the one that **SHOULD** be used. If not
|
||||
found it **SHOULD** be the second, etc. */
|
||||
TrackOverlay = 0x6FAB,
|
||||
/** [uinteger] CodecDelay is The codec-built-in delay in nanoseconds. This value **MUST** be subtracted from each
|
||||
block timestamp in order to get the actual timestamp. The value **SHOULD** be small so the muxing of tracks with
|
||||
the same actual timestamp are in the same Cluster. */
|
||||
CodecDelay = 0x56AA,
|
||||
/** [uinteger] After a discontinuity, SeekPreRoll is the duration in nanoseconds of the data the decoder **MUST**
|
||||
decode before the decoded data is valid. */
|
||||
SeekPreRoll = 0x56BB,
|
||||
/** [master] The mapping between this `TrackEntry` and a track value in the given Chapter Codec. */
|
||||
TrackTranslate = 0x6624,
|
||||
/** [binary] The binary value used to represent this `TrackEntry` in the chapter codec data. The format depends on
|
||||
the `ChapProcessCodecID` used; see (#chapprocesscodecid-element). */
|
||||
TrackTranslateTrackID = 0x66A5,
|
||||
/** [uinteger] This `TrackTranslate` applies to this chapter codec of the given chapter edition(s); see
|
||||
(#chapprocesscodecid-element). */
|
||||
TrackTranslateCodec = 0x66BF,
|
||||
/** [uinteger] Specify a chapter edition UID on which this `TrackTranslate` applies. */
|
||||
TrackTranslateEditionUID = 0x66FC,
|
||||
/** [master] Video settings. */
|
||||
Video = 0xE0,
|
||||
/** [uinteger] Specify whether the video frames in this track are interlaced or not. */
|
||||
FlagInterlaced = 0x9A,
|
||||
/** [uinteger] Specify the field ordering of video frames in this track. */
|
||||
FieldOrder = 0x9D,
|
||||
/** [uinteger] Stereo-3D video mode. There are some more details in (#multi-planar-and-3d-videos). */
|
||||
StereoMode = 0x53B8,
|
||||
/** [uinteger] Alpha Video Mode. Presence of this Element indicates that the BlockAdditional Element could contain
|
||||
Alpha data. */
|
||||
AlphaMode = 0x53C0,
|
||||
/** [uinteger] DEPRECATED, DO NOT USE. Bogus StereoMode value used in old versions of libmatroska. */
|
||||
OldStereoMode = 0x53B9,
|
||||
/** [uinteger] Width of the encoded video frames in pixels. */
|
||||
PixelWidth = 0xB0,
|
||||
/** [uinteger] Height of the encoded video frames in pixels. */
|
||||
PixelHeight = 0xBA,
|
||||
/** [uinteger] The number of video pixels to remove at the bottom of the image. */
|
||||
PixelCropBottom = 0x54AA,
|
||||
/** [uinteger] The number of video pixels to remove at the top of the image. */
|
||||
PixelCropTop = 0x54BB,
|
||||
/** [uinteger] The number of video pixels to remove on the left of the image. */
|
||||
PixelCropLeft = 0x54CC,
|
||||
/** [uinteger] The number of video pixels to remove on the right of the image. */
|
||||
PixelCropRight = 0x54DD,
|
||||
/** [uinteger] Width of the video frames to display. Applies to the video frame after cropping (PixelCrop*
|
||||
Elements). */
|
||||
DisplayWidth = 0x54B0,
|
||||
/** [uinteger] Height of the video frames to display. Applies to the video frame after cropping (PixelCrop*
|
||||
Elements). */
|
||||
DisplayHeight = 0x54BA,
|
||||
/** [uinteger] How DisplayWidth & DisplayHeight are interpreted. */
|
||||
DisplayUnit = 0x54B2,
|
||||
/** [uinteger] Specify the possible modifications to the aspect ratio. */
|
||||
AspectRatioType = 0x54B3,
|
||||
/** [binary] Specify the uncompressed pixel format used for the Track's data as a FourCC. This value is similar in
|
||||
scope to the biCompression value of AVI's `BITMAPINFO` [@?AVIFormat]. See the YUV video formats [@?FourCC-YUV]
|
||||
and RGB video formats [@?FourCC-RGB] for common values. */
|
||||
UncompressedFourCC = 0x2EB524,
|
||||
/** [float] Gamma Value. */
|
||||
GammaValue = 0x2FB523,
|
||||
/** [float] Number of frames per second. This value is Informational only. It is intended for constant frame rate
|
||||
streams, and **SHOULD NOT** be used for a variable frame rate TrackEntry. */
|
||||
FrameRate = 0x2383E3,
|
||||
/** [master] Settings describing the colour format. */
|
||||
Colour = 0x55B0,
|
||||
/** [uinteger] The Matrix Coefficients of the video used to derive luma and chroma values from red, green, and blue
|
||||
color primaries. For clarity, the value and meanings for MatrixCoefficients are adopted from Table 4 of ISO/IEC
|
||||
23001-8:2016 or ITU-T H.273. */
|
||||
MatrixCoefficients = 0x55B1,
|
||||
/** [uinteger] Number of decoded bits per channel. A value of 0 indicates that the BitsPerChannel is unspecified. */
|
||||
BitsPerChannel = 0x55B2,
|
||||
/** [uinteger] The amount of pixels to remove in the Cr and Cb channels for every pixel not removed horizontally.
|
||||
Example: For video with 4:2:0 chroma subsampling, the ChromaSubsamplingHorz **SHOULD** be set to 1. */
|
||||
ChromaSubsamplingHorz = 0x55B3,
|
||||
/** [uinteger] The amount of pixels to remove in the Cr and Cb channels for every pixel not removed vertically.
|
||||
Example: For video with 4:2:0 chroma subsampling, the ChromaSubsamplingVert **SHOULD** be set to 1. */
|
||||
ChromaSubsamplingVert = 0x55B4,
|
||||
/** [uinteger] The amount of pixels to remove in the Cb channel for every pixel not removed horizontally. This is
|
||||
additive with ChromaSubsamplingHorz. Example: For video with 4:2:1 chroma subsampling, the ChromaSubsamplingHorz
|
||||
**SHOULD** be set to 1 and CbSubsamplingHorz **SHOULD** be set to 1. */
|
||||
CbSubsamplingHorz = 0x55B5,
|
||||
/** [uinteger] The amount of pixels to remove in the Cb channel for every pixel not removed vertically. This is
|
||||
additive with ChromaSubsamplingVert. */
|
||||
CbSubsamplingVert = 0x55B6,
|
||||
/** [uinteger] How chroma is subsampled horizontally. */
|
||||
ChromaSitingHorz = 0x55B7,
|
||||
/** [uinteger] How chroma is subsampled vertically. */
|
||||
ChromaSitingVert = 0x55B8,
|
||||
/** [uinteger] Clipping of the color ranges. */
|
||||
Range = 0x55B9,
|
||||
/** [uinteger] The transfer characteristics of the video. For clarity, the value and meanings for
|
||||
TransferCharacteristics are adopted from Table 3 of ISO/IEC 23091-4 or ITU-T H.273. */
|
||||
TransferCharacteristics = 0x55BA,
|
||||
/** [uinteger] The colour primaries of the video. For clarity, the value and meanings for Primaries are adopted from
|
||||
Table 2 of ISO/IEC 23091-4 or ITU-T H.273. */
|
||||
Primaries = 0x55BB,
|
||||
/** [uinteger] Maximum brightness of a single pixel (Maximum Content Light Level) in candelas per square meter
|
||||
(cd/m^2^). */
|
||||
MaxCLL = 0x55BC,
|
||||
/** [uinteger] Maximum brightness of a single full frame (Maximum Frame-Average Light Level) in candelas per square
|
||||
meter (cd/m^2^). */
|
||||
MaxFALL = 0x55BD,
|
||||
/** [master] SMPTE 2086 mastering data. */
|
||||
MasteringMetadata = 0x55D0,
|
||||
/** [float] Red X chromaticity coordinate, as defined by CIE 1931. */
|
||||
PrimaryRChromaticityX = 0x55D1,
|
||||
/** [float] Red Y chromaticity coordinate, as defined by CIE 1931. */
|
||||
PrimaryRChromaticityY = 0x55D2,
|
||||
/** [float] Green X chromaticity coordinate, as defined by CIE 1931. */
|
||||
PrimaryGChromaticityX = 0x55D3,
|
||||
/** [float] Green Y chromaticity coordinate, as defined by CIE 1931. */
|
||||
PrimaryGChromaticityY = 0x55D4,
|
||||
/** [float] Blue X chromaticity coordinate, as defined by CIE 1931. */
|
||||
PrimaryBChromaticityX = 0x55D5,
|
||||
/** [float] Blue Y chromaticity coordinate, as defined by CIE 1931. */
|
||||
PrimaryBChromaticityY = 0x55D6,
|
||||
/** [float] White X chromaticity coordinate, as defined by CIE 1931. */
|
||||
WhitePointChromaticityX = 0x55D7,
|
||||
/** [float] White Y chromaticity coordinate, as defined by CIE 1931. */
|
||||
WhitePointChromaticityY = 0x55D8,
|
||||
/** [float] Maximum luminance. Represented in candelas per square meter (cd/m^2^). */
|
||||
LuminanceMax = 0x55D9,
|
||||
/** [float] Minimum luminance. Represented in candelas per square meter (cd/m^2^). */
|
||||
LuminanceMin = 0x55DA,
|
||||
/** [master] Describes the video projection details. Used to render spherical, VR videos or flipping videos
|
||||
horizontally/vertically. */
|
||||
Projection = 0x7670,
|
||||
/** [uinteger] Describes the projection used for this video track. */
|
||||
ProjectionType = 0x7671,
|
||||
/** [binary] Private data that only applies to a specific projection. * If `ProjectionType` equals 0
|
||||
(Rectangular), then this element must not be present. * If `ProjectionType` equals 1 (Equirectangular),
|
||||
then this element must be present and contain the same binary data that would be stored inside an ISOBMFF
|
||||
Equirectangular Projection Box ('equi'). * If `ProjectionType` equals 2 (Cubemap), then this element must be
|
||||
present and contain the same binary data that would be stored inside an ISOBMFF Cubemap Projection Box
|
||||
('cbmp'). * If `ProjectionType` equals 3 (Mesh), then this element must be present and contain the same binary
|
||||
data that would be stored inside an ISOBMFF Mesh Projection Box ('mshp'). */
|
||||
ProjectionPrivate = 0x7672,
|
||||
/** [float] Specifies a yaw rotation to the projection. Value represents a clockwise rotation, in degrees, around
|
||||
the up vector. This rotation must be applied before any `ProjectionPosePitch` or `ProjectionPoseRoll` rotations.
|
||||
The value of this element **MUST** be in the -180 to 180 degree range, both included. Setting
|
||||
`ProjectionPoseYaw` to 180 or -180 degrees, with the `ProjectionPoseRoll` and `ProjectionPosePitch` set to 0
|
||||
degrees flips the image horizontally. */
|
||||
ProjectionPoseYaw = 0x7673,
|
||||
/** [float] Specifies a pitch rotation to the projection. Value represents a counter-clockwise rotation, in
|
||||
degrees, around the right vector. This rotation must be applied after the `ProjectionPoseYaw` rotation and before
|
||||
the `ProjectionPoseRoll` rotation. The value of this element **MUST** be in the -90 to 90 degree range, both
|
||||
included. */
|
||||
ProjectionPosePitch = 0x7674,
|
||||
/** [float] Specifies a roll rotation to the projection. Value represents a counter-clockwise rotation, in degrees,
|
||||
around the forward vector. This rotation must be applied after the `ProjectionPoseYaw` and `ProjectionPosePitch`
|
||||
rotations. The value of this element **MUST** be in the -180 to 180 degree range, both included. Setting
|
||||
`ProjectionPoseRoll` to 180 or -180 degrees, the `ProjectionPoseYaw` to 180 or -180 degrees with
|
||||
`ProjectionPosePitch` set to 0 degrees flips the image vertically. Setting `ProjectionPoseRoll` to 180 or -180
|
||||
degrees, with the `ProjectionPoseYaw` and `ProjectionPosePitch` set to 0 degrees flips the image horizontally and
|
||||
vertically. */
|
||||
ProjectionPoseRoll = 0x7675,
|
||||
/** [master] Audio settings. */
|
||||
Audio = 0xE1,
|
||||
/** [float] Sampling frequency in Hz. */
|
||||
SamplingFrequency = 0xB5,
|
||||
/** [float] Real output sampling frequency in Hz (used for SBR techniques). */
|
||||
OutputSamplingFrequency = 0x78B5,
|
||||
/** [uinteger] Numbers of channels in the track. */
|
||||
Channels = 0x9F,
|
||||
/** [binary] Table of horizontal angles for each successive channel. */
|
||||
ChannelPositions = 0x7D7B,
|
||||
/** [uinteger] Bits per sample, mostly used for PCM. */
|
||||
BitDepth = 0x6264,
|
||||
/** [master] Operation that needs to be applied on tracks to create this virtual track. For more details look at
|
||||
(#track-operation). */
|
||||
TrackOperation = 0xE2,
|
||||
/** [master] Contains the list of all video plane tracks that need to be combined to create this 3D track */
|
||||
TrackCombinePlanes = 0xE3,
|
||||
/** [master] Contains a video plane track that need to be combined to create this 3D track */
|
||||
TrackPlane = 0xE4,
|
||||
/** [uinteger] The trackUID number of the track representing the plane. */
|
||||
TrackPlaneUID = 0xE5,
|
||||
/** [uinteger] The kind of plane this track corresponds to. */
|
||||
TrackPlaneType = 0xE6,
|
||||
/** [master] Contains the list of all tracks whose Blocks need to be combined to create this virtual track */
|
||||
TrackJoinBlocks = 0xE9,
|
||||
/** [uinteger] The trackUID number of a track whose blocks are used to create this virtual track. */
|
||||
TrackJoinUID = 0xED,
|
||||
/** [uinteger] The TrackUID of the Smooth FF/RW video in the paired EBML structure corresponding to this video
|
||||
track. See [@?DivXTrickTrack]. */
|
||||
TrickTrackUID = 0xC0,
|
||||
/** [binary] The SegmentUID of the Segment containing the track identified by TrickTrackUID. See [@?DivXTrickTrack].
|
||||
*/
|
||||
TrickTrackSegmentUID = 0xC1,
|
||||
/** [uinteger] Set to 1 if this video track is a Smooth FF/RW track. If set to 1, MasterTrackUID and
|
||||
MasterTrackSegUID should must be present and BlockGroups for this track must contain ReferenceFrame structures.
|
||||
Otherwise, TrickTrackUID and TrickTrackSegUID must be present if this track has a corresponding Smooth FF/RW
|
||||
track. See [@?DivXTrickTrack]. */
|
||||
TrickTrackFlag = 0xC6,
|
||||
/** [uinteger] The TrackUID of the video track in the paired EBML structure that corresponds to this Smooth FF/RW
|
||||
track. See [@?DivXTrickTrack]. */
|
||||
TrickMasterTrackUID = 0xC7,
|
||||
/** [binary] The SegmentUID of the Segment containing the track identified by MasterTrackUID. See
|
||||
[@?DivXTrickTrack]. */
|
||||
TrickMasterTrackSegmentUID = 0xC4,
|
||||
/** [master] Settings for several content encoding mechanisms like compression or encryption. */
|
||||
ContentEncodings = 0x6D80,
|
||||
/** [master] Settings for one content encoding like compression or encryption. */
|
||||
ContentEncoding = 0x6240,
|
||||
/** [uinteger] Tells when this modification was used during encoding/muxing starting with 0 and counting upwards.
|
||||
The decoder/demuxer has to start with the highest order number it finds and work its way down. This value has to
|
||||
be unique over all ContentEncodingOrder Elements in the TrackEntry that contains this ContentEncodingOrder
|
||||
element. */
|
||||
ContentEncodingOrder = 0x5031,
|
||||
/** [uinteger] A bit field that describes which Elements have been modified in this way. Values (big-endian) can be
|
||||
OR'ed. */
|
||||
ContentEncodingScope = 0x5032,
|
||||
/** [uinteger] A value describing what kind of transformation is applied. */
|
||||
ContentEncodingType = 0x5033,
|
||||
/** [master] Settings describing the compression used. This Element **MUST** be present if the value of
|
||||
ContentEncodingType is 0 and absent otherwise. Each block **MUST** be decompressable even if no previous block is
|
||||
available in order not to prevent seeking. */
|
||||
ContentCompression = 0x5034,
|
||||
/** [uinteger] The compression algorithm used. */
|
||||
ContentCompAlgo = 0x4254,
|
||||
/** [binary] Settings that might be needed by the decompressor. For Header Stripping (`ContentCompAlgo`=3), the
|
||||
bytes that were removed from the beginning of each frames of the track. */
|
||||
ContentCompSettings = 0x4255,
|
||||
/** [master] Settings describing the encryption used. This Element **MUST** be present if the value of
|
||||
`ContentEncodingType` is 1 (encryption) and **MUST** be ignored otherwise. */
|
||||
ContentEncryption = 0x5035,
|
||||
/** [uinteger] The encryption algorithm used. The value "0" means that the contents have not been encrypted. */
|
||||
ContentEncAlgo = 0x47E1,
|
||||
/** [binary] For public key algorithms this is the ID of the public key the the data was encrypted with. */
|
||||
ContentEncKeyID = 0x47E2,
|
||||
/** [master] Settings describing the encryption algorithm used. If `ContentEncAlgo` != 5 this **MUST** be ignored.
|
||||
*/
|
||||
ContentEncAESSettings = 0x47E7,
|
||||
/** [uinteger] The AES cipher mode used in the encryption. */
|
||||
AESSettingsCipherMode = 0x47E8,
|
||||
/** [binary] A cryptographic signature of the contents. */
|
||||
ContentSignature = 0x47E3,
|
||||
/** [binary] This is the ID of the private key the data was signed with. */
|
||||
ContentSigKeyID = 0x47E4,
|
||||
/** [uinteger] The algorithm used for the signature. */
|
||||
ContentSigAlgo = 0x47E5,
|
||||
/** [uinteger] The hash algorithm used for the signature. */
|
||||
ContentSigHashAlgo = 0x47E6,
|
||||
/** [master] A Top-Level Element to speed seeking access. All entries are local to the Segment. */
|
||||
Cues = 0x1C53BB6B,
|
||||
/** [master] Contains all information relative to a seek point in the Segment. */
|
||||
CuePoint = 0xBB,
|
||||
/** [uinteger] Absolute timestamp according to the Segment time base. */
|
||||
CueTime = 0xB3,
|
||||
/** [master] Contain positions for different tracks corresponding to the timestamp. */
|
||||
CueTrackPositions = 0xB7,
|
||||
/** [uinteger] The track for which a position is given. */
|
||||
CueTrack = 0xF7,
|
||||
/** [uinteger] The Segment Position of the Cluster containing the associated Block. */
|
||||
CueClusterPosition = 0xF1,
|
||||
/** [uinteger] The relative position inside the Cluster of the referenced SimpleBlock or BlockGroup with 0 being the
|
||||
first possible position for an Element inside that Cluster. */
|
||||
CueRelativePosition = 0xF0,
|
||||
/** [uinteger] The duration of the block according to the Segment time base. If missing the track's DefaultDuration
|
||||
does not apply and no duration information is available in terms of the cues. */
|
||||
CueDuration = 0xB2,
|
||||
/** [uinteger] Number of the Block in the specified Cluster. */
|
||||
CueBlockNumber = 0x5378,
|
||||
/** [uinteger] The Segment Position of the Codec State corresponding to this Cue Element. 0 means that the data is
|
||||
taken from the initial Track Entry. */
|
||||
CueCodecState = 0xEA,
|
||||
/** [master] The Clusters containing the referenced Blocks. */
|
||||
CueReference = 0xDB,
|
||||
/** [uinteger] Timestamp of the referenced Block. */
|
||||
CueRefTime = 0x96,
|
||||
/** [uinteger] The Segment Position of the Cluster containing the referenced Block. */
|
||||
CueRefCluster = 0x97,
|
||||
/** [uinteger] Number of the referenced Block of Track X in the specified Cluster. */
|
||||
CueRefNumber = 0x535F,
|
||||
/** [uinteger] The Segment Position of the Codec State corresponding to this referenced Element. 0 means that the
|
||||
data is taken from the initial Track Entry. */
|
||||
CueRefCodecState = 0xEB,
|
||||
/** [master] Contain attached files. */
|
||||
Attachments = 0x1941A469,
|
||||
/** [master] An attached file. */
|
||||
AttachedFile = 0x61A7,
|
||||
/** [utf-8] A human-friendly name for the attached file. */
|
||||
FileDescription = 0x467E,
|
||||
/** [utf-8] Filename of the attached file. */
|
||||
FileName = 0x466E,
|
||||
/** [string] MIME type of the file. */
|
||||
FileMimeType = 0x4660,
|
||||
/** [binary] The data of the file. */
|
||||
FileData = 0x465C,
|
||||
/** [uinteger] Unique ID representing the file, as random as possible. */
|
||||
FileUID = 0x46AE,
|
||||
/** [binary] A binary value that a track/codec can refer to when the attachment is needed. */
|
||||
FileReferral = 0x4675,
|
||||
/** [uinteger] The timecode at which this optimized font attachment comes into context, based on the Segment
|
||||
TimecodeScale. This element is reserved for future use and if written must be the segment start time. See
|
||||
[@?DivXWorldFonts]. */
|
||||
FileUsedStartTime = 0x4661,
|
||||
/** [uinteger] The timecode at which this optimized font attachment goes out of context, based on the Segment
|
||||
TimecodeScale. This element is reserved for future use and if written must be the segment end time. See
|
||||
[@?DivXWorldFonts]. */
|
||||
FileUsedEndTime = 0x4662,
|
||||
/** [master] A system to define basic menus and partition data. For more detailed information, look at the Chapters
|
||||
explanation in (#chapters). */
|
||||
Chapters = 0x1043A770,
|
||||
/** [master] Contains all information about a Segment edition. */
|
||||
EditionEntry = 0x45B9,
|
||||
/** [uinteger] A unique ID to identify the edition. It's useful for tagging an edition. */
|
||||
EditionUID = 0x45BC,
|
||||
/** [uinteger] Set to 1 if an edition is hidden. Hidden editions **SHOULD NOT** be available to the user interface
|
||||
(but still to Control Tracks; see (#chapter-flags) on Chapter flags). */
|
||||
EditionFlagHidden = 0x45BD,
|
||||
/** [uinteger] Set to 1 if the edition **SHOULD** be used as the default one. */
|
||||
EditionFlagDefault = 0x45DB,
|
||||
/** [uinteger] Set to 1 if the chapters can be defined multiple times and the order to play them is enforced; see
|
||||
(#editionflagordered). */
|
||||
EditionFlagOrdered = 0x45DD,
|
||||
/** [master] Contains the atom information to use as the chapter atom (apply to all tracks). */
|
||||
ChapterAtom = 0xB6,
|
||||
/** [uinteger] A unique ID to identify the Chapter. */
|
||||
ChapterUID = 0x73C4,
|
||||
/** [utf-8] A unique string ID to identify the Chapter. Use for WebVTT cue identifier storage [@!WebVTT]. */
|
||||
ChapterStringUID = 0x5654,
|
||||
/** [uinteger] Timestamp of the start of Chapter (not scaled). */
|
||||
ChapterTimeStart = 0x91,
|
||||
/** [uinteger] Timestamp of the end of Chapter (timestamp excluded, not scaled). The value **MUST** be greater than
|
||||
or equal to the `ChapterTimeStart` of the same `ChapterAtom`. */
|
||||
ChapterTimeEnd = 0x92,
|
||||
/** [uinteger] Set to 1 if a chapter is hidden. Hidden chapters **SHOULD NOT** be available to the user interface
|
||||
(but still to Control Tracks; see (#chapterflaghidden) on Chapter flags). */
|
||||
ChapterFlagHidden = 0x98,
|
||||
/** [uinteger] Set to 1 if the chapter is enabled. It can be enabled/disabled by a Control Track. When disabled, the
|
||||
movie **SHOULD** skip all the content between the TimeStart and TimeEnd of this chapter; see (#chapter-flags) on
|
||||
Chapter flags. */
|
||||
ChapterFlagEnabled = 0x4598,
|
||||
/** [binary] The SegmentUID of another Segment to play during this chapter. */
|
||||
ChapterSegmentUID = 0x6E67,
|
||||
/** [uinteger] The EditionUID to play from the Segment linked in ChapterSegmentUID. If ChapterSegmentEditionUID is
|
||||
undeclared, then no Edition of the linked Segment is used; see (#medium-linking) on medium-linking Segments. */
|
||||
ChapterSegmentEditionUID = 0x6EBC,
|
||||
/** [uinteger] Specify the physical equivalent of this ChapterAtom like "DVD" (60) or "SIDE" (50); see
|
||||
(#physical-types) for a complete list of values. */
|
||||
ChapterPhysicalEquiv = 0x63C3,
|
||||
/** [master] List of tracks on which the chapter applies. If this Element is not present, all tracks apply */
|
||||
ChapterTrack = 0x8F,
|
||||
/** [uinteger] UID of the Track to apply this chapter to. In the absence of a control track, choosing this chapter
|
||||
will select the listed Tracks and deselect unlisted tracks. Absence of this Element indicates that the Chapter
|
||||
**SHOULD** be applied to any currently used Tracks. */
|
||||
ChapterTrackUID = 0x89,
|
||||
/** [master] Contains all possible strings to use for the chapter display. */
|
||||
ChapterDisplay = 0x80,
|
||||
/** [utf-8] Contains the string to use as the chapter atom. */
|
||||
ChapString = 0x85,
|
||||
/** [string] A language corresponding to the string, in the bibliographic ISO-639-2 form [@!ISO639-2]. This Element
|
||||
**MUST** be ignored if a ChapLanguageIETF Element is used within the same ChapterDisplay Element. */
|
||||
ChapLanguage = 0x437C,
|
||||
/** [string] Specifies a language corresponding to the ChapString in the format defined in [@!BCP47] and using the
|
||||
IANA Language Subtag Registry [@!IANALangRegistry]. If a ChapLanguageIETF Element is used, then any ChapLanguage
|
||||
and ChapCountry Elements used in the same ChapterDisplay **MUST** be ignored. */
|
||||
ChapLanguageIETF = 0x437D,
|
||||
/** [string] A country corresponding to the string, using the same 2 octets country-codes as in Internet domains
|
||||
[@!IANADomains] based on [@!ISO3166-1] alpha-2 codes. This Element **MUST** be ignored if a ChapLanguageIETF
|
||||
Element is used within the same ChapterDisplay Element. */
|
||||
ChapCountry = 0x437E,
|
||||
/** [master] Contains all the commands associated to the Atom. */
|
||||
ChapProcess = 0x6944,
|
||||
/** [uinteger] Contains the type of the codec used for the processing. A value of 0 means native Matroska processing
|
||||
(to be defined), a value of 1 means the DVD command set is used; see (#menu-features) on DVD menus. More codec
|
||||
IDs can be added later. */
|
||||
ChapProcessCodecID = 0x6955,
|
||||
/** [binary] Some optional data attached to the ChapProcessCodecID information. For ChapProcessCodecID = 1, it
|
||||
is the "DVD level" equivalent; see (#menu-features) on DVD menus. */
|
||||
ChapProcessPrivate = 0x450D,
|
||||
/** [master] Contains all the commands associated to the Atom. */
|
||||
ChapProcessCommand = 0x6911,
|
||||
/** [uinteger] Defines when the process command **SHOULD** be handled */
|
||||
ChapProcessTime = 0x6922,
|
||||
/** [binary] Contains the command information. The data **SHOULD** be interpreted depending on the
|
||||
ChapProcessCodecID value. For ChapProcessCodecID = 1, the data correspond to the binary DVD cell pre/post
|
||||
commands; see (#menu-features) on DVD menus. */
|
||||
ChapProcessData = 0x6933,
|
||||
/** [master] Element containing metadata describing Tracks, Editions, Chapters, Attachments, or the Segment as a
|
||||
whole. A list of valid tags can be found in [@!MatroskaTags]. */
|
||||
Tags = 0x1254C367,
|
||||
/** [master] A single metadata descriptor. */
|
||||
Tag = 0x7373,
|
||||
/** [master] Specifies which other elements the metadata represented by the Tag applies to. If empty or not present,
|
||||
then the Tag describes everything in the Segment. */
|
||||
Targets = 0x63C0,
|
||||
/** [uinteger] A number to indicate the logical level of the target. */
|
||||
TargetTypeValue = 0x68CA,
|
||||
/** [string] An informational string that can be used to display the logical level of the target like "ALBUM",
|
||||
"TRACK", "MOVIE", "CHAPTER", etc ; see Section 6.4 of [@!MatroskaTags]. */
|
||||
TargetType = 0x63CA,
|
||||
/** [uinteger] A unique ID to identify the Track(s) the tags belong to. */
|
||||
TagTrackUID = 0x63C5,
|
||||
/** [uinteger] A unique ID to identify the EditionEntry(s) the tags belong to. */
|
||||
TagEditionUID = 0x63C9,
|
||||
/** [uinteger] A unique ID to identify the Chapter(s) the tags belong to. */
|
||||
TagChapterUID = 0x63C4,
|
||||
/** [uinteger] A unique ID to identify the Attachment(s) the tags belong to. */
|
||||
TagAttachmentUID = 0x63C6,
|
||||
/** [master] Contains general information about the target. */
|
||||
SimpleTag = 0x67C8,
|
||||
/** [utf-8] The name of the Tag that is going to be stored. */
|
||||
TagName = 0x45A3,
|
||||
/** [string] Specifies the language of the tag specified, in the Matroska languages form; see (#language-codes) on
|
||||
language codes. This Element **MUST** be ignored if the TagLanguageIETF Element is used within the same SimpleTag
|
||||
Element. */
|
||||
TagLanguage = 0x447A,
|
||||
/** [string] Specifies the language used in the TagString according to [@!BCP47] and using the IANA Language Subtag
|
||||
Registry [@!IANALangRegistry]. If this Element is used, then any TagLanguage Elements used in the same SimpleTag
|
||||
**MUST** be ignored. */
|
||||
TagLanguageIETF = 0x447B,
|
||||
/** [uinteger] A boolean value to indicate if this is the default/original language to use for the given tag. */
|
||||
TagDefault = 0x4484,
|
||||
/** [uinteger] A variant of the TagDefault element with a bogus Element ID; see (#tagdefault-element). */
|
||||
TagDefaultBogus = 0x44B4,
|
||||
/** [utf-8] The value of the Tag. */
|
||||
TagString = 0x4487,
|
||||
/** [binary] The values of the Tag, if it is binary. Note that this cannot be used in the same SimpleTag as
|
||||
TagString. */
|
||||
TagBinary = 0x4485,
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef AC101AUDIOSINK_H
|
||||
#define AC101AUDIOSINK_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "ac101.h"
|
||||
#include "adac.h"
|
||||
|
||||
class AC101AudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
AC101AudioSink();
|
||||
~AC101AudioSink();
|
||||
void volumeChanged(uint16_t volume);
|
||||
private:
|
||||
adac_s *dac;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef BUFFEREDAUDIOSINK_H
|
||||
#define BUFFEREDAUDIOSINK_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "AudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class BufferedAudioSink : public AudioSink
|
||||
{
|
||||
public:
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes) override;
|
||||
bool setParams(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
protected:
|
||||
void startI2sFeed(size_t buf_size = 4096 * 8);
|
||||
void feedPCMFramesInternal(const void *pvItem, size_t xItemSize);
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef ES8311AUDIOSINK_H
|
||||
#define ES8311AUDIOSINK_H
|
||||
|
||||
#include "driver/i2s.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c.h"
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class ES8311AudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
ES8311AudioSink();
|
||||
~ES8311AudioSink();
|
||||
void writeReg(uint8_t reg_add, uint8_t data);
|
||||
void volumeChanged(uint16_t volume);
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifndef ES8388AUDIOSINK_H
|
||||
#define ES8388AUDIOSINK_H
|
||||
|
||||
#include "driver/i2s.h"
|
||||
#include <driver/i2c.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#define ES8388_ADDR 0x20
|
||||
|
||||
#define ACK_CHECK_EN 0x1
|
||||
|
||||
/* ES8388 register */
|
||||
#define ES8388_CONTROL1 0x00
|
||||
#define ES8388_CONTROL2 0x01
|
||||
#define ES8388_CHIPPOWER 0x02
|
||||
#define ES8388_ADCPOWER 0x03
|
||||
#define ES8388_DACPOWER 0x04
|
||||
#define ES8388_CHIPLOPOW1 0x05
|
||||
#define ES8388_CHIPLOPOW2 0x06
|
||||
#define ES8388_ANAVOLMANAG 0x07
|
||||
#define ES8388_MASTERMODE 0x08
|
||||
|
||||
/* ADC */
|
||||
#define ES8388_ADCCONTROL1 0x09
|
||||
#define ES8388_ADCCONTROL2 0x0a
|
||||
#define ES8388_ADCCONTROL3 0x0b
|
||||
#define ES8388_ADCCONTROL4 0x0c
|
||||
#define ES8388_ADCCONTROL5 0x0d
|
||||
#define ES8388_ADCCONTROL6 0x0e
|
||||
#define ES8388_ADCCONTROL7 0x0f
|
||||
#define ES8388_ADCCONTROL8 0x10
|
||||
#define ES8388_ADCCONTROL9 0x11
|
||||
#define ES8388_ADCCONTROL10 0x12
|
||||
#define ES8388_ADCCONTROL11 0x13
|
||||
#define ES8388_ADCCONTROL12 0x14
|
||||
#define ES8388_ADCCONTROL13 0x15
|
||||
#define ES8388_ADCCONTROL14 0x16
|
||||
|
||||
/* DAC */
|
||||
#define ES8388_DACCONTROL1 0x17
|
||||
#define ES8388_DACCONTROL2 0x18
|
||||
#define ES8388_DACCONTROL3 0x19
|
||||
#define ES8388_DACCONTROL4 0x1a
|
||||
#define ES8388_DACCONTROL5 0x1b
|
||||
#define ES8388_DACCONTROL6 0x1c
|
||||
#define ES8388_DACCONTROL7 0x1d
|
||||
#define ES8388_DACCONTROL8 0x1e
|
||||
#define ES8388_DACCONTROL9 0x1f
|
||||
#define ES8388_DACCONTROL10 0x20
|
||||
#define ES8388_DACCONTROL11 0x21
|
||||
#define ES8388_DACCONTROL12 0x22
|
||||
#define ES8388_DACCONTROL13 0x23
|
||||
#define ES8388_DACCONTROL14 0x24
|
||||
#define ES8388_DACCONTROL15 0x25
|
||||
#define ES8388_DACCONTROL16 0x26
|
||||
#define ES8388_DACCONTROL17 0x27
|
||||
#define ES8388_DACCONTROL18 0x28
|
||||
#define ES8388_DACCONTROL19 0x29
|
||||
#define ES8388_DACCONTROL20 0x2a
|
||||
#define ES8388_DACCONTROL21 0x2b
|
||||
#define ES8388_DACCONTROL22 0x2c
|
||||
#define ES8388_DACCONTROL23 0x2d
|
||||
#define ES8388_DACCONTROL24 0x2e
|
||||
#define ES8388_DACCONTROL25 0x2f
|
||||
#define ES8388_DACCONTROL26 0x30
|
||||
#define ES8388_DACCONTROL27 0x31
|
||||
#define ES8388_DACCONTROL28 0x32
|
||||
#define ES8388_DACCONTROL29 0x33
|
||||
#define ES8388_DACCONTROL30 0x34
|
||||
|
||||
class ES8388AudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
ES8388AudioSink();
|
||||
~ES8388AudioSink();
|
||||
|
||||
bool begin(int sda = -1, int scl = -1, uint32_t frequency = 400000U);
|
||||
|
||||
enum ES8388_OUT
|
||||
{
|
||||
ES_MAIN, // this is the DAC output volume (both outputs)
|
||||
ES_OUT1, // this is the additional gain for OUT1
|
||||
ES_OUT2 // this is the additional gain for OUT2
|
||||
};
|
||||
|
||||
void mute(const ES8388_OUT out, const bool muted);
|
||||
void volume(const ES8388_OUT out, const uint8_t vol);
|
||||
|
||||
void writeReg(uint8_t reg_add, uint8_t data);
|
||||
private:
|
||||
i2c_config_t i2c_config;
|
||||
i2c_port_t i2c_port = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef ES9018AUDIOSINK_H
|
||||
#define ES9018AUDIOSINK_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class ES9018AudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
ES9018AudioSink();
|
||||
~ES9018AudioSink();
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef INTERNALAUDIOSINK_H
|
||||
#define INTERNALAUDIOSINK_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class InternalAudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
InternalAudioSink();
|
||||
~InternalAudioSink();
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PCM5102AUDIOSINK_H
|
||||
#define PCM5102AUDIOSINK_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class PCM5102AudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
PCM5102AudioSink();
|
||||
~PCM5102AudioSink();
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef SPDIFAUDIOSINK_H
|
||||
#define SPDIFAUDIOSINK_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class SPDIFAudioSink : public BufferedAudioSink
|
||||
{
|
||||
private:
|
||||
uint8_t spdifPin;
|
||||
public:
|
||||
explicit SPDIFAudioSink(uint8_t spdifPin);
|
||||
~SPDIFAudioSink() override;
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes) override;
|
||||
bool setParams(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef TAS5711AUDIOSINK_H
|
||||
#define TAS5711AUDIOSINK_H
|
||||
|
||||
|
||||
#include "driver/i2s.h"
|
||||
#include <driver/i2c.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "BufferedAudioSink.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class TAS5711AudioSink : public BufferedAudioSink
|
||||
{
|
||||
public:
|
||||
TAS5711AudioSink();
|
||||
~TAS5711AudioSink();
|
||||
|
||||
|
||||
void writeReg(uint8_t reg, uint8_t value);
|
||||
private:
|
||||
i2c_config_t i2c_config;
|
||||
i2c_port_t i2c_port = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
176
components/spotify/cspot/bell/include/audio/sinks/esp/ac101.h
Normal file
176
components/spotify/cspot/bell/include/audio/sinks/esp/ac101.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
|
||||
* it is free of charge, to any person obtaining a copy of this software and associated
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AC101_H__
|
||||
#define __AC101_H__
|
||||
|
||||
#include "esp_types.h"
|
||||
|
||||
#define AC101_ADDR 0x1a /*!< Device address*/
|
||||
|
||||
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
|
||||
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
|
||||
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
|
||||
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
|
||||
#define ACK_VAL 0x0 /*!< I2C ack value */
|
||||
#define NACK_VAL 0x1 /*!< I2C nack value */
|
||||
|
||||
#define CHIP_AUDIO_RS 0x00
|
||||
#define PLL_CTRL1 0x01
|
||||
#define PLL_CTRL2 0x02
|
||||
#define SYSCLK_CTRL 0x03
|
||||
#define MOD_CLK_ENA 0x04
|
||||
#define MOD_RST_CTRL 0x05
|
||||
#define I2S_SR_CTRL 0x06
|
||||
#define I2S1LCK_CTRL 0x10
|
||||
#define I2S1_SDOUT_CTRL 0x11
|
||||
#define I2S1_SDIN_CTRL 0x12
|
||||
#define I2S1_MXR_SRC 0x13
|
||||
#define I2S1_VOL_CTRL1 0x14
|
||||
#define I2S1_VOL_CTRL2 0x15
|
||||
#define I2S1_VOL_CTRL3 0x16
|
||||
#define I2S1_VOL_CTRL4 0x17
|
||||
#define I2S1_MXR_GAIN 0x18
|
||||
#define ADC_DIG_CTRL 0x40
|
||||
#define ADC_VOL_CTRL 0x41
|
||||
#define HMIC_CTRL1 0x44
|
||||
#define HMIC_CTRL2 0x45
|
||||
#define HMIC_STATUS 0x46
|
||||
#define DAC_DIG_CTRL 0x48
|
||||
#define DAC_VOL_CTRL 0x49
|
||||
#define DAC_MXR_SRC 0x4c
|
||||
#define DAC_MXR_GAIN 0x4d
|
||||
#define ADC_ANA_CTRL 0x50
|
||||
#define ADC_SRC 0x51
|
||||
#define ADC_SRCBST_CTRL 0x52
|
||||
#define OMIXER_DACA_CTRL 0x53
|
||||
#define OMIXER_SR 0x54
|
||||
#define OMIXER_BST1_CTRL 0x55
|
||||
#define HPOUT_CTRL 0x56
|
||||
#define SPKOUT_CTRL 0x58
|
||||
#define AC_DAC_DAPCTRL 0xa0
|
||||
#define AC_DAC_DAPHHPFC 0xa1
|
||||
#define AC_DAC_DAPLHPFC 0xa2
|
||||
#define AC_DAC_DAPLHAVC 0xa3
|
||||
#define AC_DAC_DAPLLAVC 0xa4
|
||||
#define AC_DAC_DAPRHAVC 0xa5
|
||||
#define AC_DAC_DAPRLAVC 0xa6
|
||||
#define AC_DAC_DAPHGDEC 0xa7
|
||||
#define AC_DAC_DAPLGDEC 0xa8
|
||||
#define AC_DAC_DAPHGATC 0xa9
|
||||
#define AC_DAC_DAPLGATC 0xaa
|
||||
#define AC_DAC_DAPHETHD 0xab
|
||||
#define AC_DAC_DAPLETHD 0xac
|
||||
#define AC_DAC_DAPHGKPA 0xad
|
||||
#define AC_DAC_DAPLGKPA 0xae
|
||||
#define AC_DAC_DAPHGOPA 0xaf
|
||||
#define AC_DAC_DAPLGOPA 0xb0
|
||||
#define AC_DAC_DAPOPT 0xb1
|
||||
#define DAC_DAP_ENA 0xb5
|
||||
|
||||
typedef enum{
|
||||
SAMPLE_RATE_8000 = 0x0000,
|
||||
SAMPLE_RATE_11052 = 0x1000,
|
||||
SAMPLE_RATE_12000 = 0x2000,
|
||||
SAMPLE_RATE_16000 = 0x3000,
|
||||
SAMPLE_RATE_22050 = 0x4000,
|
||||
SAMPLE_RATE_24000 = 0x5000,
|
||||
SAMPLE_RATE_32000 = 0x6000,
|
||||
SAMPLE_RATE_44100 = 0x7000,
|
||||
SAMPLE_RATE_48000 = 0x8000,
|
||||
SAMPLE_RATE_96000 = 0x9000,
|
||||
SAMPLE_RATE_192000 = 0xa000,
|
||||
} ac_adda_fs_i2s1_t;
|
||||
|
||||
typedef enum{
|
||||
BCLK_DIV_1 = 0x0,
|
||||
BCLK_DIV_2 = 0x1,
|
||||
BCLK_DIV_4 = 0x2,
|
||||
BCLK_DIV_6 = 0x3,
|
||||
BCLK_DIV_8 = 0x4,
|
||||
BCLK_DIV_12 = 0x5,
|
||||
BCLK_DIV_16 = 0x6,
|
||||
BCLK_DIV_24 = 0x7,
|
||||
BCLK_DIV_32 = 0x8,
|
||||
BCLK_DIV_48 = 0x9,
|
||||
BCLK_DIV_64 = 0xa,
|
||||
BCLK_DIV_96 = 0xb,
|
||||
BCLK_DIV_128 = 0xc,
|
||||
BCLK_DIV_192 = 0xd,
|
||||
} ac_i2s1_bclk_div_t;
|
||||
|
||||
typedef enum{
|
||||
LRCK_DIV_16 =0x0,
|
||||
LRCK_DIV_32 =0x1,
|
||||
LRCK_DIV_64 =0x2,
|
||||
LRCK_DIV_128 =0x3,
|
||||
LRCK_DIV_256 =0x4,
|
||||
} ac_i2s1_lrck_div_t;
|
||||
|
||||
typedef enum {
|
||||
BIT_LENGTH_8_BITS = 0x00,
|
||||
BIT_LENGTH_16_BITS = 0x01,
|
||||
BIT_LENGTH_20_BITS = 0x02,
|
||||
BIT_LENGTH_24_BITS = 0x03,
|
||||
} ac_bits_length_t;
|
||||
|
||||
typedef enum {
|
||||
AC_MODE_MIN = -1,
|
||||
AC_MODE_SLAVE = 0x00,
|
||||
AC_MODE_MASTER = 0x01,
|
||||
AC_MODE_MAX,
|
||||
} ac_mode_sm_t;
|
||||
|
||||
typedef enum {
|
||||
AC_MODULE_MIN = -1,
|
||||
AC_MODULE_ADC = 0x01,
|
||||
AC_MODULE_DAC = 0x02,
|
||||
AC_MODULE_ADC_DAC = 0x03,
|
||||
AC_MODULE_LINE = 0x04,
|
||||
AC_MODULE_MAX
|
||||
} ac_module_t;
|
||||
|
||||
typedef enum{
|
||||
SRC_MIC1 = 1,
|
||||
SRC_MIC2 = 2,
|
||||
SRC_LINEIN = 3,
|
||||
}ac_output_mixer_source_t;
|
||||
|
||||
typedef enum {
|
||||
GAIN_N45DB = 0,
|
||||
GAIN_N30DB = 1,
|
||||
GAIN_N15DB = 2,
|
||||
GAIN_0DB = 3,
|
||||
GAIN_15DB = 4,
|
||||
GAIN_30DB = 5,
|
||||
GAIN_45DB = 6,
|
||||
GAIN_60DB = 7,
|
||||
} ac_output_mixer_gain_t;
|
||||
|
||||
typedef struct {
|
||||
ac_i2s1_bclk_div_t bclk_div; /*!< bits clock divide */
|
||||
ac_i2s1_lrck_div_t lclk_div; /*!< WS clock divide */
|
||||
} ac_i2s_clock_t;
|
||||
|
||||
#endif
|
||||
28
components/spotify/cspot/bell/include/audio/sinks/esp/adac.h
Normal file
28
components/spotify/cspot/bell/include/audio/sinks/esp/adac.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Squeezelite for esp32
|
||||
*
|
||||
* (c) Sebastien 2019
|
||||
* Philippe G. 2019, philippe_44@outlook.com
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/i2s.h"
|
||||
|
||||
typedef enum { ADAC_ON = 0, ADAC_STANDBY, ADAC_OFF } adac_power_e;
|
||||
|
||||
struct adac_s {
|
||||
bool (*init)(int i2c_port_num, int i2s_num, i2s_config_t *config);
|
||||
void (*deinit)(void);
|
||||
void (*power)(adac_power_e mode);
|
||||
void (*speaker)(bool active);
|
||||
void (*headset)(bool active);
|
||||
void (*volume)(unsigned left, unsigned right);
|
||||
};
|
||||
|
||||
extern struct adac_s dac_tas57xx;
|
||||
extern struct adac_s dac_a1s;
|
||||
extern struct adac_s dac_external;
|
||||
121
components/spotify/cspot/bell/include/audio/sinks/esp/es8311.h
Normal file
121
components/spotify/cspot/bell/include/audio/sinks/esp/es8311.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* ES8311.h -- ES8311 ALSA SoC Audio Codec
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* Based on ES8374.h by David Yang
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _ES8311_H
|
||||
#define _ES8311_H
|
||||
#include "driver/i2c.h"
|
||||
#include "esxxx_common.h"
|
||||
|
||||
/*
|
||||
* ES8311_REGISTER NAME_REG_REGISTER ADDRESS
|
||||
*/
|
||||
#define ES8311_RESET_REG00 0x00 /*reset digital,csm,clock manager etc.*/
|
||||
|
||||
/*
|
||||
* Clock Scheme Register definition
|
||||
*/
|
||||
#define ES8311_CLK_MANAGER_REG01 0x01 /* select clk src for mclk, enable clock for codec */
|
||||
#define ES8311_CLK_MANAGER_REG02 0x02 /* clk divider and clk multiplier */
|
||||
#define ES8311_CLK_MANAGER_REG03 0x03 /* adc fsmode and osr */
|
||||
#define ES8311_CLK_MANAGER_REG04 0x04 /* dac osr */
|
||||
#define ES8311_CLK_MANAGER_REG05 0x05 /* clk divier for adc and dac */
|
||||
#define ES8311_CLK_MANAGER_REG06 0x06 /* bclk inverter and divider */
|
||||
#define ES8311_CLK_MANAGER_REG07 0x07 /* tri-state, lrck divider */
|
||||
#define ES8311_CLK_MANAGER_REG08 0x08 /* lrck divider */
|
||||
#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */
|
||||
#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */
|
||||
#define ES8311_SYSTEM_REG0B 0x0B /* system */
|
||||
#define ES8311_SYSTEM_REG0C 0x0C /* system */
|
||||
#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */
|
||||
#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */
|
||||
#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */
|
||||
#define ES8311_SYSTEM_REG10 0x10 /* system */
|
||||
#define ES8311_SYSTEM_REG11 0x11 /* system */
|
||||
#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */
|
||||
#define ES8311_SYSTEM_REG13 0x13 /* system */
|
||||
#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */
|
||||
#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */
|
||||
#define ES8311_ADC_REG16 0x16 /* ADC */
|
||||
#define ES8311_ADC_REG17 0x17 /* ADC, volume */
|
||||
#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */
|
||||
#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */
|
||||
#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */
|
||||
#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */
|
||||
#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */
|
||||
#define ES8311_DAC_REG31 0x31 /* DAC, mute */
|
||||
#define ES8311_DAC_REG32 0x32 /* DAC, volume */
|
||||
#define ES8311_DAC_REG33 0x33 /* DAC, offset */
|
||||
#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */
|
||||
#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */
|
||||
#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */
|
||||
#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */
|
||||
#define ES8311_GP_REG45 0x45 /* GP CONTROL */
|
||||
#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */
|
||||
#define ES8311_CHD2_REGFE 0xFE /* CHIP ID2 */
|
||||
#define ES8311_CHVER_REGFF 0xFF /* VERSION */
|
||||
#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */
|
||||
|
||||
#define ES8311_MAX_REGISTER 0xFF
|
||||
|
||||
|
||||
typedef struct {
|
||||
ESCodecMode esMode;
|
||||
i2c_port_t i2c_port_num;
|
||||
i2c_config_t i2c_cfg;
|
||||
DacOutput dacOutput;
|
||||
AdcInput adcInput;
|
||||
} Es8311Config;
|
||||
|
||||
|
||||
#define AUDIO_CODEC_ES8311_DEFAULT(){ \
|
||||
.esMode = ES_MODE_SLAVE, \
|
||||
.i2c_port_num = I2C_NUM_0, \
|
||||
.i2c_cfg = { \
|
||||
.mode = I2C_MODE_MASTER, \
|
||||
.sda_io_num = IIC_DATA, \
|
||||
.scl_io_num = IIC_CLK, \
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,\
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,\
|
||||
.master.clk_speed = 100000\
|
||||
}, \
|
||||
.adcInput = ADC_INPUT_LINPUT1_RINPUT1,\
|
||||
.dacOutput = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT1 | DAC_OUTPUT_ROUT2,\
|
||||
};
|
||||
|
||||
int Es8311Init(Es8311Config *cfg);
|
||||
void Es8311Uninit();
|
||||
esp_err_t Es8311GetRef(bool flag);
|
||||
esp_err_t Es7243Init(void);
|
||||
|
||||
int Es7243ReadReg(uint8_t regAdd);
|
||||
|
||||
int Es8311ConfigFmt(ESCodecModule mode, ESCodecI2SFmt fmt);
|
||||
int Es8311I2sConfigClock(ESCodecI2sClock cfg);
|
||||
int Es8311SetBitsPerSample(ESCodecModule mode, BitsLength bitPerSample);
|
||||
|
||||
int Es8311Start(ESCodecModule mode);
|
||||
int Es8311Stop(ESCodecModule mode);
|
||||
|
||||
int Es8311SetVoiceVolume(int volume);
|
||||
int Es8311GetVoiceVolume(int *volume);
|
||||
int Es8311SetVoiceMute(int enable);
|
||||
int Es8311GetVoiceMute(int *mute);
|
||||
int Es8311SetMicGain(MicGain gain);
|
||||
|
||||
int Es8311ConfigAdcInput(AdcInput input);
|
||||
int Es8311ConfigDacOutput(DacOutput output);
|
||||
|
||||
int ES8311WriteReg(uint8_t regAdd, uint8_t data);
|
||||
|
||||
void Es8311ReadAll();
|
||||
int Es8311ReadReg(uint8_t regAdd);
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
#ifndef __ESCODEC_COMMON_H__
|
||||
#define __ESCODEC_COMMON_H__
|
||||
|
||||
typedef enum BitsLength {
|
||||
BIT_LENGTH_MIN = -1,
|
||||
BIT_LENGTH_16BITS = 0x03,
|
||||
BIT_LENGTH_18BITS = 0x02,
|
||||
BIT_LENGTH_20BITS = 0x01,
|
||||
BIT_LENGTH_24BITS = 0x00,
|
||||
BIT_LENGTH_32BITS = 0x04,
|
||||
BIT_LENGTH_MAX,
|
||||
} BitsLength;
|
||||
|
||||
typedef enum {
|
||||
SAMPLE_RATE_MIN = -1,
|
||||
SAMPLE_RATE_16K,
|
||||
SAMPLE_RATE_32K,
|
||||
SAMPLE_RATE_44_1K,
|
||||
SAMPLE_RATE_MAX,
|
||||
} SampleRate;
|
||||
|
||||
typedef enum {
|
||||
MclkDiv_MIN = -1,
|
||||
MclkDiv_1 = 1,
|
||||
MclkDiv_2 = 2,
|
||||
MclkDiv_3 = 3,
|
||||
MclkDiv_4 = 4,
|
||||
MclkDiv_6 = 5,
|
||||
MclkDiv_8 = 6,
|
||||
MclkDiv_9 = 7,
|
||||
MclkDiv_11 = 8,
|
||||
MclkDiv_12 = 9,
|
||||
MclkDiv_16 = 10,
|
||||
MclkDiv_18 = 11,
|
||||
MclkDiv_22 = 12,
|
||||
MclkDiv_24 = 13,
|
||||
MclkDiv_33 = 14,
|
||||
MclkDiv_36 = 15,
|
||||
MclkDiv_44 = 16,
|
||||
MclkDiv_48 = 17,
|
||||
MclkDiv_66 = 18,
|
||||
MclkDiv_72 = 19,
|
||||
MclkDiv_5 = 20,
|
||||
MclkDiv_10 = 21,
|
||||
MclkDiv_15 = 22,
|
||||
MclkDiv_17 = 23,
|
||||
MclkDiv_20 = 24,
|
||||
MclkDiv_25 = 25,
|
||||
MclkDiv_30 = 26,
|
||||
MclkDiv_32 = 27,
|
||||
MclkDiv_34 = 28,
|
||||
MclkDiv_7 = 29,
|
||||
MclkDiv_13 = 30,
|
||||
MclkDiv_14 = 31,
|
||||
MclkDiv_MAX,
|
||||
} SclkDiv;
|
||||
|
||||
typedef enum {
|
||||
LclkDiv_MIN = -1,
|
||||
LclkDiv_128 = 0,
|
||||
LclkDiv_192 = 1,
|
||||
LclkDiv_256 = 2,
|
||||
LclkDiv_384 = 3,
|
||||
LclkDiv_512 = 4,
|
||||
LclkDiv_576 = 5,
|
||||
LclkDiv_768 = 6,
|
||||
LclkDiv_1024 = 7,
|
||||
LclkDiv_1152 = 8,
|
||||
LclkDiv_1408 = 9,
|
||||
LclkDiv_1536 = 10,
|
||||
LclkDiv_2112 = 11,
|
||||
LclkDiv_2304 = 12,
|
||||
|
||||
LclkDiv_125 = 16,
|
||||
LclkDiv_136 = 17,
|
||||
LclkDiv_250 = 18,
|
||||
LclkDiv_272 = 19,
|
||||
LclkDiv_375 = 20,
|
||||
LclkDiv_500 = 21,
|
||||
LclkDiv_544 = 22,
|
||||
LclkDiv_750 = 23,
|
||||
LclkDiv_1000 = 24,
|
||||
LclkDiv_1088 = 25,
|
||||
LclkDiv_1496 = 26,
|
||||
LclkDiv_1500 = 27,
|
||||
LclkDiv_MAX,
|
||||
} LclkDiv;
|
||||
|
||||
typedef enum {
|
||||
ADC_INPUT_MIN = -1,
|
||||
ADC_INPUT_LINPUT1_RINPUT1 = 0x00,
|
||||
ADC_INPUT_MIC1 = 0x05,
|
||||
ADC_INPUT_MIC2 = 0x06,
|
||||
ADC_INPUT_LINPUT2_RINPUT2 = 0x50,
|
||||
ADC_INPUT_DIFFERENCE = 0xf0,
|
||||
ADC_INPUT_MAX,
|
||||
} AdcInput;
|
||||
|
||||
typedef enum {
|
||||
DAC_OUTPUT_MIN = -1,
|
||||
DAC_OUTPUT_LOUT1 = 0x04,
|
||||
DAC_OUTPUT_LOUT2 = 0x08,
|
||||
DAC_OUTPUT_SPK = 0x09,
|
||||
DAC_OUTPUT_ROUT1 = 0x10,
|
||||
DAC_OUTPUT_ROUT2 = 0x20,
|
||||
DAC_OUTPUT_ALL = 0x3c,
|
||||
DAC_OUTPUT_MAX,
|
||||
} DacOutput;
|
||||
|
||||
typedef enum {
|
||||
D2SE_PGA_GAIN_MIN = -1,
|
||||
D2SE_PGA_GAIN_DIS = 0,
|
||||
D2SE_PGA_GAIN_EN = 1,
|
||||
D2SE_PGA_GAIN_MAX = 2,
|
||||
} D2SEPGA;
|
||||
|
||||
typedef enum {
|
||||
MIC_GAIN_MIN = -1,
|
||||
MIC_GAIN_0DB = 0,
|
||||
MIC_GAIN_3DB = 3,
|
||||
MIC_GAIN_6DB = 6,
|
||||
MIC_GAIN_9DB = 9,
|
||||
MIC_GAIN_12DB = 12,
|
||||
MIC_GAIN_15DB = 15,
|
||||
MIC_GAIN_18DB = 18,
|
||||
MIC_GAIN_21DB = 21,
|
||||
MIC_GAIN_24DB = 24,
|
||||
#if defined CONFIG_CODEC_CHIP_IS_ES8311
|
||||
MIC_GAIN_30DB = 30,
|
||||
MIC_GAIN_36DB = 36,
|
||||
MIC_GAIN_42DB = 42,
|
||||
#endif
|
||||
MIC_GAIN_MAX,
|
||||
} MicGain;
|
||||
|
||||
typedef enum {
|
||||
ES_MODULE_MIN = -1,
|
||||
ES_MODULE_ADC = 0x01,
|
||||
ES_MODULE_DAC = 0x02,
|
||||
ES_MODULE_ADC_DAC = 0x03,
|
||||
ES_MODULE_LINE = 0x04,
|
||||
ES_MODULE_MAX
|
||||
} ESCodecModule;
|
||||
|
||||
typedef enum {
|
||||
ES_MODE_MIN = -1,
|
||||
ES_MODE_SLAVE = 0x00,
|
||||
ES_MODE_MASTER = 0x01,
|
||||
ES_MODE_MAX,
|
||||
} ESCodecMode;
|
||||
|
||||
typedef enum {
|
||||
ES_ = -1,
|
||||
ES_I2S_NORMAL = 0,
|
||||
ES_I2S_LEFT = 1,
|
||||
ES_I2S_RIGHT = 2,
|
||||
ES_I2S_DSP = 3,
|
||||
ES_I2S_MAX
|
||||
} ESCodecI2SFmt;
|
||||
|
||||
typedef struct {
|
||||
SclkDiv sclkDiv;
|
||||
LclkDiv lclkDiv;
|
||||
} ESCodecI2sClock;
|
||||
|
||||
#endif //__ESCODEC_COMMON_H__
|
||||
@@ -0,0 +1,124 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "AudioSink.h"
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
#include <BellTask.h>
|
||||
#include <unistd.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#define PCM_DEVICE "default"
|
||||
|
||||
template <typename T, int SIZE>
|
||||
class RingbufferPointer
|
||||
{
|
||||
typedef std::unique_ptr<T> TPointer;
|
||||
|
||||
public:
|
||||
explicit RingbufferPointer()
|
||||
{
|
||||
// create objects
|
||||
for (int i = 0; i < SIZE; i++)
|
||||
{
|
||||
buf_[i] = std::make_unique<T>();
|
||||
}
|
||||
}
|
||||
|
||||
bool push(TPointer &item)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (full())
|
||||
return false;
|
||||
|
||||
std::swap(buf_[head_], item);
|
||||
|
||||
if (full_)
|
||||
tail_ = (tail_ + 1) % max_size_;
|
||||
|
||||
head_ = (head_ + 1) % max_size_;
|
||||
full_ = head_ == tail_;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pop(TPointer &item)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (empty())
|
||||
return false;
|
||||
|
||||
std::swap(buf_[tail_], item);
|
||||
|
||||
full_ = false;
|
||||
tail_ = (tail_ + 1) % max_size_;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
head_ = tail_;
|
||||
full_ = false;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (!full_ && (head_ == tail_));
|
||||
}
|
||||
|
||||
bool full() const
|
||||
{
|
||||
return full_;
|
||||
}
|
||||
|
||||
int capacity() const
|
||||
{
|
||||
return max_size_;
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
int size = max_size_;
|
||||
|
||||
if (!full_)
|
||||
{
|
||||
if (head_ >= tail_)
|
||||
size = head_ - tail_;
|
||||
else
|
||||
size = max_size_ + head_ - tail_;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
private:
|
||||
TPointer buf_[SIZE];
|
||||
|
||||
std::mutex mutex_;
|
||||
int head_ = 0;
|
||||
int tail_ = 0;
|
||||
const int max_size_ = SIZE;
|
||||
bool full_ = 0;
|
||||
};
|
||||
|
||||
class ALSAAudioSink : public AudioSink, public bell::Task
|
||||
{
|
||||
public:
|
||||
ALSAAudioSink();
|
||||
~ALSAAudioSink();
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes);
|
||||
void runTask();
|
||||
|
||||
private:
|
||||
RingbufferPointer<std::vector<uint8_t>, 3> ringbuffer;
|
||||
unsigned int pcm;
|
||||
snd_pcm_t *pcm_handle;
|
||||
snd_pcm_hw_params_t *params;
|
||||
snd_pcm_uframes_t frames;
|
||||
int buff_size;
|
||||
std::vector<uint8_t> buff;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "AudioSink.h"
|
||||
|
||||
class NamedPipeAudioSink : public AudioSink
|
||||
{
|
||||
public:
|
||||
NamedPipeAudioSink();
|
||||
~NamedPipeAudioSink();
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes);
|
||||
|
||||
private:
|
||||
std::ofstream namedPipeFile;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "portaudio.h"
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include "AudioSink.h"
|
||||
|
||||
class PortAudioSink : public AudioSink
|
||||
{
|
||||
public:
|
||||
PortAudioSink();
|
||||
~PortAudioSink() override;
|
||||
void feedPCMFrames(const uint8_t *buffer, size_t bytes) override;
|
||||
bool setParams(uint32_t sampleRate, uint8_t channelCount, uint8_t bitDepth) override;
|
||||
|
||||
private:
|
||||
PaStream *stream = nullptr;
|
||||
};
|
||||
Reference in New Issue
Block a user