Skip to content

Commit

Permalink
fully support metadata when decoding FLAC data
Browse files Browse the repository at this point in the history
  • Loading branch information
russaa committed Jul 11, 2020
1 parent 23608b8 commit 1154c27
Show file tree
Hide file tree
Showing 3 changed files with 773 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ EMCC_MAX_OPT_LEVEL_ASMJS_FASTCOMP:=$(EMCC_MAX_OPT_LEVEL) -g4
EMCC_MAX_OPT_LEVEL_ASMJS_LLVM:=$(EMCC_MAX_OPT_LEVEL) -g3
EMCC_MAX_OPT_LEVEL_WASM:=$(EMCC_MAX_OPT_LEVEL) -g4
EMCC_MIN_OPT_LEVEL:=-O3
EMCC_OPTS_GENERAL:=--emit-symbol-map -s USE_OGG=1 -s NO_EXIT_RUNTIME=1 -s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 -s RESERVED_FUNCTION_POINTERS=5 -s ALLOW_MEMORY_GROWTH=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall","cwrap","getValue","setValue"]' -s EXPORTED_FUNCTIONS='["_FLAC__stream_encoder_set_verify","_FLAC__stream_encoder_get_verify","_FLAC__stream_encoder_get_verify_decoder_state","_FLAC__stream_encoder_set_compression_level","_FLAC__stream_encoder_set_blocksize","_FLAC__stream_encoder_new","_FLAC__stream_encoder_set_channels","_FLAC__stream_encoder_set_bits_per_sample","_FLAC__stream_encoder_set_sample_rate","_FLAC__stream_encoder_set_total_samples_estimate","_FLAC__stream_decoder_new","_FLAC__stream_decoder_set_md5_checking","_FLAC__stream_encoder_init_stream","_FLAC__stream_encoder_init_ogg_stream","_FLAC__stream_encoder_set_ogg_serial_number","_FLAC__stream_decoder_set_ogg_serial_number","_FLAC__stream_decoder_init_stream","_FLAC__stream_decoder_init_ogg_stream","_FLAC__stream_encoder_process","_FLAC__stream_encoder_process_interleaved","_FLAC__stream_decoder_process_single","_FLAC__stream_decoder_process_until_end_of_stream","_FLAC__stream_decoder_process_until_end_of_metadata","_FLAC__stream_decoder_get_state","_FLAC__stream_encoder_get_state","_FLAC__stream_decoder_get_md5_checking","_FLAC__stream_encoder_finish","_FLAC__stream_decoder_finish","_FLAC__stream_decoder_reset","_FLAC__stream_encoder_delete","_FLAC__stream_decoder_delete"]'
EMCC_OPTS_GENERAL:=--emit-symbol-map -s USE_OGG=1 -s NO_EXIT_RUNTIME=1 -s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 -s RESERVED_FUNCTION_POINTERS=5 -s ALLOW_MEMORY_GROWTH=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall","cwrap","getValue","setValue"]' -s EXPORTED_FUNCTIONS='["_FLAC__stream_decoder_delete","_FLAC__stream_decoder_finish","_FLAC__stream_decoder_get_md5_checking","_FLAC__stream_decoder_get_state","_FLAC__stream_decoder_init_ogg_stream","_FLAC__stream_decoder_init_stream","_FLAC__stream_decoder_new","_FLAC__stream_decoder_process_single","_FLAC__stream_decoder_process_until_end_of_metadata","_FLAC__stream_decoder_process_until_end_of_stream","_FLAC__stream_decoder_reset","_FLAC__stream_decoder_set_md5_checking","_FLAC__stream_decoder_set_metadata_ignore","_FLAC__stream_decoder_set_metadata_ignore_all","_FLAC__stream_decoder_set_metadata_ignore_application","_FLAC__stream_decoder_set_metadata_respond","_FLAC__stream_decoder_set_metadata_respond_all","_FLAC__stream_decoder_set_metadata_respond_application","_FLAC__stream_decoder_set_ogg_serial_number","_FLAC__stream_encoder_delete","_FLAC__stream_encoder_finish","_FLAC__stream_encoder_get_state","_FLAC__stream_encoder_get_verify","_FLAC__stream_encoder_get_verify_decoder_state","_FLAC__stream_encoder_init_ogg_stream","_FLAC__stream_encoder_init_stream","_FLAC__stream_encoder_new","_FLAC__stream_encoder_process","_FLAC__stream_encoder_process_interleaved","_FLAC__stream_encoder_set_bits_per_sample","_FLAC__stream_encoder_set_blocksize","_FLAC__stream_encoder_set_channels","_FLAC__stream_encoder_set_compression_level","_FLAC__stream_encoder_set_metadata","_FLAC__stream_encoder_set_ogg_serial_number","_FLAC__stream_encoder_set_sample_rate","_FLAC__stream_encoder_set_total_samples_estimate","_FLAC__stream_encoder_set_verify"]'
EMCC_OPTS_ASMJS_DEFAULT:=$(EMCC_OPTS_GENERAL) -s WASM=0
EMCC_OPTS_WASM_LLVM:=-s "-mnontrapping-fptoint"
EMCC_OPTS_WASM_FASTCOMP:=-s "BINARYEN_TRAP_MODE='clamp'"
Expand Down
303 changes: 292 additions & 11 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export type FLAC__StreamDecoderErrorStatus = 0 | 1 | 2 | 3;
*
* @property {boolean} [analyseSubframes] for decoding: include subframes metadata in write-callback metadata, DEFAULT: false
* @property {boolean} [analyseResiduals] for decoding: include residual data in subframes metadata in write-callback metadata, NOTE {@link #analyseSubframes} muste also be enabled, DEFAULT: false
* @property {boolean} [enableRawStreamMetadata] for encoding and decoding: enable receiving raw STREAMINFO metadata as second argument in the metadata-callback, DEFAULT: false
* @property {boolean} [enableRawMetadata] DEBUG option for decoding: enable receiving raw metadata for unknown metadata types in second argument in the metadata-callback, DEFAULT: false
* @see Flac#setOptions
* @see Flac~metadata_callback_fn
* @see Flac#FLAC__stream_decoder_set_metadata_respond_all
Expand All @@ -62,19 +62,20 @@ export interface CodingOptions {
*/
analyseResiduals?: boolean;
/**
* for encoding and decoding: enable receiving raw STREAMINFO metadata as second argument in the metadata-callback, DEFAULT: false
* DEBUG option for decoding: enable receiving raw metadata for unknown metadata types in second argument in the metadata-callback, DEFAULT: false
*/
enableRawStreamMetadata?: boolean;
enableRawMetadata?: boolean;
}
/**
* FLAC raw metadata
*
* @property {FLAC__MetadataType} type the type of the metadata
* @property {boolean} isLast if it is the last block of metadata
* @property {number} length the length of the metadata block (bytes)
* @property {Uint8Array} raw the raw (binary) metadata
* @property {StreamMetadata | PaddingMetadata | ApplicationMetadata | SeekTableMetadata | CueSheetMetadata | PictureMetadata} [data] the metadata (omitted for unknown metadata types)
* @property {Uint8Array} [raw] raw metadata (for debugging: enable via {@link Flac#setOptions})
*/
export interface RawMetadata {
export interface MetadataBlock {
/**
* the type of the metadata
*/
Expand All @@ -88,10 +89,290 @@ export interface RawMetadata {
*/
length: number;
/**
* the raw (binary) metadata
* the metadata (omitted for unknown metadata types)
*/
raw: Uint8Array;
data?: StreamMetadata | PaddingMetadata | ApplicationMetadata | SeekTableMetadata | CueSheetMetadata | PictureMetadata;
/**
* raw metadata (for debugging: enable via {@link Flac#setOptions})
*/
raw?: Uint8Array;
}
/**
* FLAC padding metadata block
*
* @property {number} dummy Conceptually this is an empty struct since we don't store the padding bytes. Empty structs are not allowed by some C compilers, hence the dummy.
* @see Flac.FLAC__MetadataType#FLAC__METADATA_TYPE_PADDING
*/
export interface PaddingMetadata {
/**
* Conceptually this is an empty struct since we don't store the padding bytes. Empty structs are not allowed by some C compilers, hence the dummy.
*/
dummy: number;
}
/**
* FLAC application metadata block
*
* NOTE the application meta data type is not really supported, i.e. the
* (binary) data is only a pointer to the memory heap.
*
* @property {number} id the application ID
* @property {number} data (pointer)
* @see Flac.FLAC__MetadataType#FLAC__METADATA_TYPE_APPLICATION
* @see {@link https://xiph.org/flac/format.html#metadata_block_application|application block format specification}
*/
export interface ApplicationMetadata {
/**
* the application ID
*/
id: number;
/**
* (pointer)
*/
data: number;
}
/**
* FLAC seek table metadata block
*
* <p>
* From the format specification:
*
* The seek points must be sorted by ascending sample number.
*
* Each seek point's sample number must be the first sample of the target frame.
*
* Each seek point's sample number must be unique within the table
*
* Existence of a SEEKTABLE block implies a correct setting of total_samples in the stream_info block.
*
* Behavior is undefined when more than one SEEKTABLE block is present in a stream.
*
* @property {number} num_points the number of seek points
* @property {Array<SeekPoint>} points the seek points
* @see Flac.FLAC__MetadataType#FLAC__METADATA_TYPE_SEEKTABLE
*/
export interface SeekTableMetadata {
/**
* the number of seek points
*/
num_points: number;
/**
* the seek points
*/
points: Array<SeekPoint>;
}
/**
* FLAC seek point data
*
* @property {number} sample_number The sample number of the target frame. NOTE <code>-1</code> for a placeholder point.
* @property {number} stream_offset The offset, in bytes, of the target frame with respect to beginning of the first frame.
* @property {number} frame_samples The number of samples in the target frame.
* @see Flac.SeekTableMetadata
*/
export interface SeekPoint {
/**
* The sample number of the target frame. NOTE <code>-1</code> for a placeholder point.
*/
sample_number: number;
/**
* The offset, in bytes, of the target frame with respect to beginning of the first frame.
*/
stream_offset: number;
/**
* The number of samples in the target frame.
*/
frame_samples: number;
}
/**
* FLAC vorbis comment metadata block
*
* @property {string} vendor_string the vendor string
* @property {number} num_comments the number of comments
* @property {Array<string>} comments the comments
* @see Flac.FLAC__MetadataType#FLAC__METADATA_TYPE_VORBIS_COMMENT
*/
export interface VorbisCommentMetadata {
/**
* the vendor string
*/
vendor_string: string;
/**
* the number of comments
*/
num_comments: number;
/**
* the comments
*/
comments: Array<string>;
}
/**
* FLAC cue sheet metadata block
*
* @property {string} media_catalog_number Media catalog number, in ASCII printable characters 0x20-0x7e. In general, the media catalog number may be 0 to 128 bytes long.
* @property {number} lead_in The number of lead-in samples.
* @property {boolean} is_cd true if CUESHEET corresponds to a Compact Disc, else false.
* @property {number} num_tracks The number of tracks.
* @property {Array<CueSheetTrack>} tracks the tracks
* @see Flac.FLAC__MetadataType#FLAC__METADATA_TYPE_CUESHEET
*/
export interface CueSheetMetadata {
/**
* Media catalog number, in ASCII printable characters 0x20-0x7e. In general, the media catalog number may be 0 to 128 bytes long.
*/
media_catalog_number: string;
/**
* The number of lead-in samples.
*/
lead_in: number;
/**
* true if CUESHEET corresponds to a Compact Disc, else false.
*/
is_cd: boolean;
/**
* The number of tracks.
*/
num_tracks: number;
/**
* the tracks
*/
tracks: Array<CueSheetTrack>;
}
/**
* FLAC cue sheet track data
*
* @property {number} offset Track offset in samples, relative to the beginning of the FLAC audio stream.
* @property {number} number The track number.
* @property {string} isrc Track ISRC. This is a 12-digit alphanumeric code.
* @property {"AUDIO" | "NON_AUDIO"} type The track type: audio or non-audio.
* @property {boolean} pre_emphasis The pre-emphasis flag
* @property {number} num_indices The number of track index points.
* @property {CueSheetTracIndex} indices The track index points.
* @see Flac.CueSheetMetadata
*/
export interface CueSheetTrack {
/**
* Track offset in samples, relative to the beginning of the FLAC audio stream.
*/
offset: number;
/**
* The track number.
*/
number: number;
/**
* Track ISRC. This is a 12-digit alphanumeric code.
*/
isrc: string;
/**
* The track type: audio or non-audio.
*/
type: "AUDIO" | "NON_AUDIO";
/**
* The pre-emphasis flag
*/
pre_emphasis: boolean;
/**
* The number of track index points.
*/
num_indices: number;
/**
* The track index points.
*/
indices: CueSheetTracIndex;
}
/**
* FLAC track index data for cue sheet metadata
*
* @property {number} offset Offset in samples, relative to the track offset, of the index point.
* @property {number} number The index point number.
* @see Flac.CueSheetTrack
*/
export interface CueSheetTracIndex {
/**
* Offset in samples, relative to the track offset, of the index point.
*/
offset: number;
/**
* The index point number.
*/
number: number;
}
/**
* FLAC picture metadata block
*
* @property {FLAC__StreamMetadata_Picture_Type} type The kind of picture stored.
* @property {string} mime_type Picture data's MIME type, in ASCII printable characters 0x20-0x7e, NUL terminated. For best compatibility with players, use picture data of MIME type image/jpeg or image/png. A MIME type of '–>' is also allowed, in which case the picture data should be a complete URL.
* @property {string} description Picture's description.
* @property {number} width Picture's width in pixels.
* @property {number} height Picture's height in pixels.
* @property {number} depth Picture's color depth in bits-per-pixel.
* @property {number} colors For indexed palettes (like GIF), picture's number of colors (the number of palette entries), or 0 for non-indexed (i.e. 2^depth).
* @property {number} data_length Length of binary picture data in bytes.
* @property {Uint8Array} data Binary picture data.
*/
export interface PictureMetadata {
/**
* The kind of picture stored.
*/
type: FLAC__StreamMetadata_Picture_Type;
/**
* Picture data's MIME type, in ASCII printable characters 0x20-0x7e, NUL terminated. For best compatibility with players, use picture data of MIME type image/jpeg or image/png. A MIME type of '–>' is also allowed, in which case the picture data should be a complete URL.
*/
mime_type: string;
/**
* Picture's description.
*/
description: string;
/**
* Picture's width in pixels.
*/
width: number;
/**
* Picture's height in pixels.
*/
height: number;
/**
* Picture's color depth in bits-per-pixel.
*/
depth: number;
/**
* For indexed palettes (like GIF), picture's number of colors (the number of palette entries), or 0 for non-indexed (i.e. 2^depth).
*/
colors: number;
/**
* Length of binary picture data in bytes.
*/
data_length: number;
/**
* Binary picture data.
*/
data: Uint8Array;
}
/**
* An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag).
*
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER"} 0 Other
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD"} 1 32x32 pixels 'file icon' (PNG only)
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON"} 2 Other file icon
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER"} 3 Cover (front)
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER"} 4 Cover (back)
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE"} 5 Leaflet page
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA"} 6 Media (e.g. label side of CD)
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST"} 7 Lead artist/lead performer/soloist
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST"} 8 Artist/performer
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR"} 9 Conductor
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_BAND"} 10 Band/Orchestra
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER"} 11 Composer
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST"} 12 Lyricist/text writer
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION"} 13 Recording Location
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING"} 14 During recording
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE"} 15 During performance
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE"} 16 Movie/video screen capture
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_FISH"} 17 A bright coloured fish
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION"} 18 Illustration
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE"} 19 Band/artist logotype
* @property {"FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE"} 20 Publisher/Studio logotype
* @see Flac.PictureMetadata
*/
export type FLAC__StreamMetadata_Picture_Type = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;
/**
* An enumeration of the available metadata block types.
*
Expand All @@ -104,7 +385,7 @@ export interface RawMetadata {
* @property {"FLAC__METADATA_TYPE_PICTURE"} 6 PICTURE block
* @property {"FLAC__METADATA_TYPE_UNDEFINED"} 7 marker to denote beginning of undefined type range; this number will increase as new metadata types are added
* @property {"FLAC__MAX_METADATA_TYPE"} 126 No type will ever be greater than this. There is not enough room in the protocol block.
* @see Flac.RawMetadata
* @see Flac.MetadataBlock
* @see {@link https://xiph.org/flac/format.html|FLAC format documentation}
*/
export type FLAC__MetadataType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 126;
Expand Down Expand Up @@ -445,14 +726,14 @@ export type encoder_write_callback_fn = (data: Uint8Array, numberOfBytes: number
* For other metadata types {@link Flac.FLAC__MetadataType} they need to be enabled,
* see e.g. {@link Flac#FLAC__stream_decoder_set_metadata_respond}
*
* @param {StreamMetadata | undefined} metadata the FLAC meta data (currently only STREAMINFO is supported, for other types, only raw metadata is returned)
* @param {RawMetadata} [rawMetadata] raw meta data (NOTE raw STREAMINFO metadata needs be enabled via coding options)
* @param {StreamMetadata | undefined} metadata the FLAC meta data, NOTE only STREAMINFO is returned in first argument, for other types use 2nd argument's <code>metadataBlock.data<code>
* @param {MetadataBlock} metadataBlock the detailed meta data block
* @see Flac#init_decoder_stream
* @see Flac#init_encoder_stream
* @see Flac.CodingOptions
* @see Flac#FLAC__stream_decoder_set_metadata_respond_all
*/
export type metadata_callback_fn = (metadata: StreamMetadata | undefined, rawMetadata?: RawMetadata) => void;
export type metadata_callback_fn = (metadata: StreamMetadata | undefined, metadataBlock: MetadataBlock) => void;
/**
* FLAC meta data
*
Expand Down
Loading

0 comments on commit 1154c27

Please sign in to comment.