add FLAC__metadata_get_cuesheet() and FLAC__metadata_object_cuesheet_calculate_cddb_id()
This commit is contained in:
parent
91018c8ef7
commit
7cfac0b146
@ -127,13 +127,15 @@
|
|||||||
<li>
|
<li>
|
||||||
libFLAC:
|
libFLAC:
|
||||||
<ul>
|
<ul>
|
||||||
<li>(none)</li>
|
<li><b>Added</b> FLAC__metadata_object_cuesheet_calculate_cddb_id()</li>
|
||||||
|
<li><b>Added</b> FLAC__metadata_get_cuesheet()</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
libFLAC++:
|
libFLAC++:
|
||||||
<ul>
|
<ul>
|
||||||
<li>(none)</li>
|
<li><b>Added</b> FLAC::Metadata::CueSheet::calculate_cddb_id()</li>
|
||||||
|
<li><b>Added</b> FLAC::Metadata::get_cuesheet()</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@ -777,6 +777,9 @@ namespace FLAC {
|
|||||||
|
|
||||||
//! See FLAC__metadata_object_cuesheet_is_legal()
|
//! See FLAC__metadata_object_cuesheet_is_legal()
|
||||||
bool is_legal(bool check_cd_da_subset = false, const char **violation = 0) const;
|
bool is_legal(bool check_cd_da_subset = false, const char **violation = 0) const;
|
||||||
|
|
||||||
|
//! See FLAC__metadata_object_cuesheet_calculate_cddb_id()
|
||||||
|
FLAC__uint32 calculate_cddb_id() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Opaque metadata block for storing unknown types.
|
/** Opaque metadata block for storing unknown types.
|
||||||
@ -859,6 +862,10 @@ namespace FLAC {
|
|||||||
FLACPP_API bool get_tags(const char *filename, VorbisComment *&tags);
|
FLACPP_API bool get_tags(const char *filename, VorbisComment *&tags);
|
||||||
FLACPP_API bool get_tags(const char *filename, VorbisComment &tags);
|
FLACPP_API bool get_tags(const char *filename, VorbisComment &tags);
|
||||||
|
|
||||||
|
//! See FLAC__metadata_get_cuesheet().
|
||||||
|
FLACPP_API bool get_cuesheet(const char *filename, CueSheet *&cuesheet);
|
||||||
|
FLACPP_API bool get_cuesheet(const char *filename, CueSheet &cuesheet);
|
||||||
|
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,15 +124,15 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* \brief
|
* \brief
|
||||||
* The level 0 interface consists of individual routines to read the
|
* The level 0 interface consists of individual routines to read the
|
||||||
* STREAMINFO and VORBIS_COMMENT blocks, requiring only a filename.
|
* STREAMINFO, VORBIS_COMMENT, and CUESHEET blocks, requiring only a filename.
|
||||||
*
|
*
|
||||||
* It skips any ID3v2 tag at the head of the file.
|
* They try to skip any ID3v2 tag at the head of the file.
|
||||||
*
|
*
|
||||||
* \{
|
* \{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Read the STREAMINFO metadata block of the given FLAC file. This function
|
/** Read the STREAMINFO metadata block of the given FLAC file. This function
|
||||||
* will skip any ID3v2 tag at the head of the file.
|
* will try to skip any ID3v2 tag at the head of the file.
|
||||||
*
|
*
|
||||||
* \param filename The path to the FLAC file to read.
|
* \param filename The path to the FLAC file to read.
|
||||||
* \param streaminfo A pointer to space for the STREAMINFO block. Since
|
* \param streaminfo A pointer to space for the STREAMINFO block. Since
|
||||||
@ -151,7 +151,7 @@ extern "C" {
|
|||||||
FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo);
|
FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo);
|
||||||
|
|
||||||
/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This
|
/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This
|
||||||
* function will skip any ID3v2 tag at the head of the file.
|
* function will try to skip any ID3v2 tag at the head of the file.
|
||||||
*
|
*
|
||||||
* \param filename The path to the FLAC file to read.
|
* \param filename The path to the FLAC file to read.
|
||||||
* \param tags The address where the returned pointer will be
|
* \param tags The address where the returned pointer will be
|
||||||
@ -159,7 +159,7 @@ FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__St
|
|||||||
* the caller using FLAC__metadata_object_delete().
|
* the caller using FLAC__metadata_object_delete().
|
||||||
* \assert
|
* \assert
|
||||||
* \code filename != NULL \endcode
|
* \code filename != NULL \endcode
|
||||||
* \code streaminfo != NULL \endcode
|
* \code tags != NULL \endcode
|
||||||
* \retval FLAC__bool
|
* \retval FLAC__bool
|
||||||
* \c true if a valid VORBIS_COMMENT block was read from \a filename,
|
* \c true if a valid VORBIS_COMMENT block was read from \a filename,
|
||||||
* and \a *tags will be set to the address of the tag structure.
|
* and \a *tags will be set to the address of the tag structure.
|
||||||
@ -169,6 +169,25 @@ FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__St
|
|||||||
*/
|
*/
|
||||||
FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags);
|
FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags);
|
||||||
|
|
||||||
|
/** Read the CUESHEET metadata block of the given FLAC file. This
|
||||||
|
* function will try to skip any ID3v2 tag at the head of the file.
|
||||||
|
*
|
||||||
|
* \param filename The path to the FLAC file to read.
|
||||||
|
* \param cuesheet The address where the returned pointer will be
|
||||||
|
* stored. The \a cuesheet object must be deleted by
|
||||||
|
* the caller using FLAC__metadata_object_delete().
|
||||||
|
* \assert
|
||||||
|
* \code filename != NULL \endcode
|
||||||
|
* \code cuesheet != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c true if a valid CUESHEET block was read from \a filename,
|
||||||
|
* and \a *cuesheet will be set to the address of the tag structure.
|
||||||
|
* Returns \c false if there was a memory allocation error, a file
|
||||||
|
* decoder error, or the file contained no CUESHEET block, and
|
||||||
|
* \a *cuesheet will be set to \c NULL.
|
||||||
|
*/
|
||||||
|
FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet);
|
||||||
|
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
|
|
||||||
@ -1849,6 +1868,20 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMeta
|
|||||||
*/
|
*/
|
||||||
FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation);
|
FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation);
|
||||||
|
|
||||||
|
/* @@@@ add to unit tests */
|
||||||
|
/** Calculate and return the CDDB/freedb ID for a cue sheet. The function
|
||||||
|
* assumes the cue sheet corresponds to a CD; the result is undefined
|
||||||
|
* if the cuesheet's is_cd bit is not set.
|
||||||
|
*
|
||||||
|
* \param object A pointer to an existing CUESHEET object.
|
||||||
|
* \assert
|
||||||
|
* \code object != NULL \endcode
|
||||||
|
* \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
|
||||||
|
* \retval FLAC__uint32
|
||||||
|
* The unsigned integer representation of the CDDB/freedb ID
|
||||||
|
*/
|
||||||
|
FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object);
|
||||||
|
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1007,6 +1007,12 @@ namespace FLAC {
|
|||||||
return (bool)::FLAC__metadata_object_cuesheet_is_legal(object_, check_cd_da_subset, violation);
|
return (bool)::FLAC__metadata_object_cuesheet_is_legal(object_, check_cd_da_subset, violation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLAC__uint32 CueSheet::calculate_cddb_id() const
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(is_valid());
|
||||||
|
return ::FLAC__metadata_object_cuesheet_calculate_cddb_id(object_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Unknown
|
// Unknown
|
||||||
@ -1088,6 +1094,36 @@ namespace FLAC {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLACPP_API bool get_cuesheet(const char *filename, CueSheet *&cuesheet)
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(0 != filename);
|
||||||
|
|
||||||
|
::FLAC__StreamMetadata *object;
|
||||||
|
|
||||||
|
cuesheet = 0;
|
||||||
|
|
||||||
|
if(::FLAC__metadata_get_cuesheet(filename, &object)) {
|
||||||
|
cuesheet = new CueSheet(object, /*copy=*/false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLACPP_API bool get_cuesheet(const char *filename, CueSheet &cuesheet)
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(0 != filename);
|
||||||
|
|
||||||
|
::FLAC__StreamMetadata *object;
|
||||||
|
|
||||||
|
if(::FLAC__metadata_get_cuesheet(filename, &object)) {
|
||||||
|
cuesheet.assign(object, /*copy=*/false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
//
|
//
|
||||||
|
@ -153,113 +153,91 @@ static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecode
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FLAC__bool got_error;
|
FLAC__bool got_error;
|
||||||
FLAC__bool got_object;
|
|
||||||
FLAC__StreamMetadata *object;
|
FLAC__StreamMetadata *object;
|
||||||
} level0_client_data;
|
} level0_client_data;
|
||||||
|
|
||||||
FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo)
|
static FLAC__StreamMetadata *get_one_metadata_block_(const char *filename, FLAC__MetadataType type)
|
||||||
{
|
{
|
||||||
level0_client_data cd;
|
level0_client_data cd;
|
||||||
FLAC__FileDecoder *decoder;
|
FLAC__FileDecoder *decoder;
|
||||||
|
|
||||||
|
FLAC__ASSERT(0 != filename);
|
||||||
|
|
||||||
|
cd.got_error = false;
|
||||||
|
cd.object = 0;
|
||||||
|
|
||||||
|
decoder = FLAC__file_decoder_new();
|
||||||
|
|
||||||
|
if(0 == decoder)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FLAC__file_decoder_set_md5_checking(decoder, false);
|
||||||
|
FLAC__file_decoder_set_filename(decoder, filename);
|
||||||
|
FLAC__file_decoder_set_metadata_ignore_all(decoder);
|
||||||
|
FLAC__file_decoder_set_metadata_respond(decoder, type);
|
||||||
|
FLAC__file_decoder_set_write_callback(decoder, write_callback_);
|
||||||
|
FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_);
|
||||||
|
FLAC__file_decoder_set_error_callback(decoder, error_callback_);
|
||||||
|
FLAC__file_decoder_set_client_data(decoder, &cd);
|
||||||
|
|
||||||
|
if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK || cd.got_error) {
|
||||||
|
FLAC__file_decoder_finish(decoder);
|
||||||
|
FLAC__file_decoder_delete(decoder);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!FLAC__file_decoder_process_until_end_of_metadata(decoder) || cd.got_error) {
|
||||||
|
FLAC__file_decoder_finish(decoder);
|
||||||
|
FLAC__file_decoder_delete(decoder);
|
||||||
|
if(0 != cd.object)
|
||||||
|
FLAC__metadata_object_delete(cd.object);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLAC__file_decoder_finish(decoder);
|
||||||
|
FLAC__file_decoder_delete(decoder);
|
||||||
|
|
||||||
|
return cd.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo)
|
||||||
|
{
|
||||||
|
FLAC__StreamMetadata *object;
|
||||||
|
|
||||||
FLAC__ASSERT(0 != filename);
|
FLAC__ASSERT(0 != filename);
|
||||||
FLAC__ASSERT(0 != streaminfo);
|
FLAC__ASSERT(0 != streaminfo);
|
||||||
|
|
||||||
decoder = FLAC__file_decoder_new();
|
object = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_STREAMINFO);
|
||||||
|
|
||||||
if(0 == decoder)
|
if (object) {
|
||||||
return false;
|
|
||||||
|
|
||||||
cd.got_error = false;
|
|
||||||
cd.got_object = false;
|
|
||||||
cd.object = 0;
|
|
||||||
|
|
||||||
FLAC__file_decoder_set_md5_checking(decoder, false);
|
|
||||||
FLAC__file_decoder_set_filename(decoder, filename);
|
|
||||||
FLAC__file_decoder_set_metadata_ignore_all(decoder);
|
|
||||||
FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
|
|
||||||
FLAC__file_decoder_set_write_callback(decoder, write_callback_);
|
|
||||||
FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_);
|
|
||||||
FLAC__file_decoder_set_error_callback(decoder, error_callback_);
|
|
||||||
FLAC__file_decoder_set_client_data(decoder, &cd);
|
|
||||||
|
|
||||||
if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK || cd.got_error) {
|
|
||||||
FLAC__file_decoder_finish(decoder);
|
|
||||||
FLAC__file_decoder_delete(decoder);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!FLAC__file_decoder_process_until_end_of_metadata(decoder) || cd.got_error) {
|
|
||||||
FLAC__file_decoder_finish(decoder);
|
|
||||||
FLAC__file_decoder_delete(decoder);
|
|
||||||
if(0 != cd.object)
|
|
||||||
FLAC__metadata_object_delete(cd.object);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FLAC__file_decoder_finish(decoder);
|
|
||||||
FLAC__file_decoder_delete(decoder);
|
|
||||||
|
|
||||||
if(cd.got_object) {
|
|
||||||
/* can just copy the contents since STREAMINFO has no internal structure */
|
/* can just copy the contents since STREAMINFO has no internal structure */
|
||||||
*streaminfo = *(cd.object);
|
*streaminfo = *object;
|
||||||
|
FLAC__metadata_object_delete(object);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 != cd.object)
|
|
||||||
FLAC__metadata_object_delete(cd.object);
|
|
||||||
|
|
||||||
return cd.got_object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags)
|
FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags)
|
||||||
{
|
{
|
||||||
level0_client_data cd;
|
|
||||||
FLAC__FileDecoder *decoder;
|
|
||||||
|
|
||||||
FLAC__ASSERT(0 != filename);
|
FLAC__ASSERT(0 != filename);
|
||||||
FLAC__ASSERT(0 != tags);
|
FLAC__ASSERT(0 != tags);
|
||||||
|
|
||||||
decoder = FLAC__file_decoder_new();
|
*tags = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||||
|
|
||||||
if(0 == decoder)
|
return 0 != *tags;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
*tags = 0;
|
FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet)
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(0 != filename);
|
||||||
|
FLAC__ASSERT(0 != cuesheet);
|
||||||
|
|
||||||
cd.got_error = false;
|
*cuesheet = get_one_metadata_block_(filename, FLAC__METADATA_TYPE_CUESHEET);
|
||||||
cd.got_object = false;
|
|
||||||
cd.object = 0;
|
|
||||||
|
|
||||||
FLAC__file_decoder_set_md5_checking(decoder, false);
|
return 0 != *cuesheet;
|
||||||
FLAC__file_decoder_set_filename(decoder, filename);
|
|
||||||
FLAC__file_decoder_set_metadata_ignore_all(decoder);
|
|
||||||
FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
|
||||||
FLAC__file_decoder_set_write_callback(decoder, write_callback_);
|
|
||||||
FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_);
|
|
||||||
FLAC__file_decoder_set_error_callback(decoder, error_callback_);
|
|
||||||
FLAC__file_decoder_set_client_data(decoder, &cd);
|
|
||||||
|
|
||||||
if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK || cd.got_error) {
|
|
||||||
FLAC__file_decoder_finish(decoder);
|
|
||||||
FLAC__file_decoder_delete(decoder);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!FLAC__file_decoder_process_until_end_of_metadata(decoder) || cd.got_error) {
|
|
||||||
FLAC__file_decoder_finish(decoder);
|
|
||||||
FLAC__file_decoder_delete(decoder);
|
|
||||||
if(0 != cd.object)
|
|
||||||
FLAC__metadata_object_delete(cd.object);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FLAC__file_decoder_finish(decoder);
|
|
||||||
FLAC__file_decoder_delete(decoder);
|
|
||||||
|
|
||||||
if(cd.got_object)
|
|
||||||
*tags = cd.object;
|
|
||||||
|
|
||||||
return cd.got_object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||||
@ -278,11 +256,9 @@ void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMeta
|
|||||||
* we assume we only get here when the one metadata block we were
|
* we assume we only get here when the one metadata block we were
|
||||||
* looking for was passed to us
|
* looking for was passed to us
|
||||||
*/
|
*/
|
||||||
if(!cd->got_object) {
|
if(!cd->got_error && 0 == cd->object) {
|
||||||
if(0 == (cd->object = FLAC__metadata_object_clone(metadata)))
|
if(0 == (cd->object = FLAC__metadata_object_clone(metadata)))
|
||||||
cd->got_error = true;
|
cd->got_error = true;
|
||||||
else
|
|
||||||
cd->got_object = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,3 +1470,49 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMe
|
|||||||
|
|
||||||
return FLAC__format_cuesheet_is_legal(&object->data.cue_sheet, check_cd_da_subset, violation);
|
return FLAC__format_cuesheet_is_legal(&object->data.cue_sheet, check_cd_da_subset, violation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FLAC__uint64 get_index_01_offset_(const FLAC__StreamMetadata_CueSheet *cs, unsigned track)
|
||||||
|
{
|
||||||
|
if (track >= (cs->num_tracks-1) || cs->tracks[track].num_indices < 1)
|
||||||
|
return 0;
|
||||||
|
else if (cs->tracks[track].indices[0].number == 1)
|
||||||
|
return cs->tracks[track].indices[0].offset + cs->tracks[track].offset + cs->lead_in;
|
||||||
|
else if (cs->tracks[track].num_indices < 2)
|
||||||
|
return 0;
|
||||||
|
else if (cs->tracks[track].indices[1].number == 1)
|
||||||
|
return cs->tracks[track].indices[1].offset + cs->tracks[track].offset + cs->lead_in;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FLAC__uint32 cddb_add_digits_(FLAC__uint32 x)
|
||||||
|
{
|
||||||
|
FLAC__uint32 n = 0;
|
||||||
|
while (x) {
|
||||||
|
n += (x%10);
|
||||||
|
x /= 10;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object)
|
||||||
|
{
|
||||||
|
const FLAC__StreamMetadata_CueSheet *cs;
|
||||||
|
|
||||||
|
FLAC__ASSERT(0 != object);
|
||||||
|
FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET);
|
||||||
|
|
||||||
|
cs = &object->data.cue_sheet;
|
||||||
|
|
||||||
|
if (cs->num_tracks < 2) /* need at least one real track and the lead-out track */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
FLAC__uint32 i, length, sum = 0;
|
||||||
|
for (i = 0; i < (cs->num_tracks-1); i++) /* -1 to avoid counting the lead-out */
|
||||||
|
sum += cddb_add_digits_((FLAC__uint32)(get_index_01_offset_(cs, i) / 44100));
|
||||||
|
length = (FLAC__uint32)((cs->tracks[cs->num_tracks-1].offset+cs->lead_in) / 44100) - (FLAC__uint32)(get_index_01_offset_(cs, 0) / 44100);
|
||||||
|
|
||||||
|
return (sum % 0xFF) << 24 | length << 8 | (FLAC__uint32)(cs->num_tracks-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -471,10 +471,11 @@ void OurFileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
|
|||||||
printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
|
printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool generate_file_()
|
static bool generate_file_(FLAC__bool include_cuesheet)
|
||||||
{
|
{
|
||||||
::FLAC__StreamMetadata streaminfo, vorbiscomment, padding;
|
::FLAC__StreamMetadata streaminfo, vorbiscomment, *cuesheet, padding;
|
||||||
::FLAC__StreamMetadata *metadata[1];
|
::FLAC__StreamMetadata *metadata[3];
|
||||||
|
unsigned i = 0, n = 0;
|
||||||
|
|
||||||
printf("generating FLAC file for test\n");
|
printf("generating FLAC file for test\n");
|
||||||
|
|
||||||
@ -497,7 +498,7 @@ static bool generate_file_()
|
|||||||
{
|
{
|
||||||
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
|
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
|
||||||
vorbiscomment.is_last = false;
|
vorbiscomment.is_last = false;
|
||||||
vorbiscomment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
|
vorbiscomment.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
|
||||||
vorbiscomment.length = (4 + vendor_string_length) + 4;
|
vorbiscomment.length = (4 + vendor_string_length) + 4;
|
||||||
vorbiscomment.data.vorbis_comment.vendor_string.length = vendor_string_length;
|
vorbiscomment.data.vorbis_comment.vendor_string.length = vendor_string_length;
|
||||||
vorbiscomment.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1);
|
vorbiscomment.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1);
|
||||||
@ -506,23 +507,42 @@ static bool generate_file_()
|
|||||||
vorbiscomment.data.vorbis_comment.comments = 0;
|
vorbiscomment.data.vorbis_comment.comments = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (0 == (cuesheet = ::FLAC__metadata_object_new(::FLAC__METADATA_TYPE_CUESHEET)))
|
||||||
|
return die_("priming our metadata");
|
||||||
|
cuesheet->is_last = false;
|
||||||
|
strcpy(cuesheet->data.cue_sheet.media_catalog_number, "bogo-MCN");
|
||||||
|
cuesheet->data.cue_sheet.lead_in = 123;
|
||||||
|
cuesheet->data.cue_sheet.is_cd = false;
|
||||||
|
if (!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, 0))
|
||||||
|
return die_("priming our metadata");
|
||||||
|
cuesheet->data.cue_sheet.tracks[0].number = 1;
|
||||||
|
if (!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, 0, 0))
|
||||||
|
return die_("priming our metadata");
|
||||||
|
}
|
||||||
|
|
||||||
padding.is_last = true;
|
padding.is_last = true;
|
||||||
padding.type = ::FLAC__METADATA_TYPE_PADDING;
|
padding.type = ::FLAC__METADATA_TYPE_PADDING;
|
||||||
padding.length = 1234;
|
padding.length = 1234;
|
||||||
|
|
||||||
metadata[0] = &padding;
|
metadata[n++] = &vorbiscomment;
|
||||||
|
if (include_cuesheet)
|
||||||
|
metadata[n++] = cuesheet;
|
||||||
|
metadata[n++] = &padding;
|
||||||
|
|
||||||
FLAC::Metadata::StreamInfo s(&streaminfo);
|
FLAC::Metadata::StreamInfo s(&streaminfo);
|
||||||
FLAC::Metadata::VorbisComment v(&vorbiscomment);
|
FLAC::Metadata::VorbisComment v(&vorbiscomment);
|
||||||
|
FLAC::Metadata::CueSheet c(cuesheet, /*copy=*/false);
|
||||||
FLAC::Metadata::Padding p(&padding);
|
FLAC::Metadata::Padding p(&padding);
|
||||||
if(
|
if(
|
||||||
!insert_to_our_metadata_(&s, 0, /*copy=*/true) ||
|
!insert_to_our_metadata_(&s, i++, /*copy=*/true) ||
|
||||||
!insert_to_our_metadata_(&v, 1, /*copy=*/true) ||
|
!insert_to_our_metadata_(&v, i++, /*copy=*/true) ||
|
||||||
!insert_to_our_metadata_(&p, 2, /*copy=*/true)
|
(include_cuesheet && !insert_to_our_metadata_(&v, i++, /*copy=*/true)) ||
|
||||||
|
!insert_to_our_metadata_(&p, i++, /*copy=*/true)
|
||||||
)
|
)
|
||||||
return die_("priming our metadata");
|
return die_("priming our metadata");
|
||||||
|
|
||||||
if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, 1))
|
if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, n))
|
||||||
return die_("creating the encoded file");
|
return die_("creating the encoded file");
|
||||||
|
|
||||||
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
|
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
|
||||||
@ -594,7 +614,7 @@ static bool test_level_0_()
|
|||||||
|
|
||||||
printf("\n\n++++++ testing level 0 interface\n");
|
printf("\n\n++++++ testing level 0 interface\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!test_file_(flacfile_, /*ignore_metadata=*/true))
|
if(!test_file_(flacfile_, /*ignore_metadata=*/true))
|
||||||
@ -651,6 +671,38 @@ static bool test_level_0_()
|
|||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
printf("testing FLAC::Metadata::get_cuesheet(CueSheet *&)... ");
|
||||||
|
|
||||||
|
FLAC::Metadata::CueSheet *cuesheet = 0;
|
||||||
|
|
||||||
|
if(!FLAC::Metadata::get_cuesheet(flacfile_, cuesheet))
|
||||||
|
return die_("during FLAC::Metadata::get_cuesheet()");
|
||||||
|
|
||||||
|
/* check to see if some basic data matches (c.f. generate_file_()) */
|
||||||
|
if(cuesheet->get_lead_in() != 123)
|
||||||
|
return die_("mismatch in cuesheet->get_lead_in()");
|
||||||
|
|
||||||
|
printf("OK\n");
|
||||||
|
|
||||||
|
delete cuesheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
printf("testing FLAC::Metadata::get_cuesheet(CueSheet &)... ");
|
||||||
|
|
||||||
|
FLAC::Metadata::CueSheet cuesheet;
|
||||||
|
|
||||||
|
if(!FLAC::Metadata::get_cuesheet(flacfile_, cuesheet))
|
||||||
|
return die_("during FLAC::Metadata::get_cuesheet()");
|
||||||
|
|
||||||
|
/* check to see if some basic data matches (c.f. generate_file_()) */
|
||||||
|
if(cuesheet.get_lead_in() != 123)
|
||||||
|
return die_("mismatch in cuesheet.get_lead_in()");
|
||||||
|
|
||||||
|
printf("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
if(!remove_file_(flacfile_))
|
if(!remove_file_(flacfile_))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -675,7 +727,7 @@ static bool test_level_1_()
|
|||||||
{
|
{
|
||||||
printf("simple iterator on read-only file\n");
|
printf("simple iterator on read-only file\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!change_stats_(flacfile_, /*read_only=*/true))
|
if(!change_stats_(flacfile_, /*read_only=*/true))
|
||||||
@ -1340,7 +1392,7 @@ static bool test_level_2_(bool filename_based)
|
|||||||
|
|
||||||
printf("generate read-only file\n");
|
printf("generate read-only file\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!change_stats_(flacfile_, /*read_only=*/true))
|
if(!change_stats_(flacfile_, /*read_only=*/true))
|
||||||
@ -1895,7 +1947,7 @@ static bool test_level_2_misc_()
|
|||||||
|
|
||||||
printf("generate file\n");
|
printf("generate file\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
printf("create chain\n");
|
printf("create chain\n");
|
||||||
|
@ -478,10 +478,11 @@ static void decoder_error_callback_(const FLAC__FileDecoder *decoder, FLAC__Stre
|
|||||||
printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
|
printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FLAC__bool generate_file_()
|
static FLAC__bool generate_file_(FLAC__bool include_cuesheet)
|
||||||
{
|
{
|
||||||
FLAC__StreamMetadata streaminfo, vorbiscomment, padding;
|
FLAC__StreamMetadata streaminfo, vorbiscomment, *cuesheet, padding;
|
||||||
FLAC__StreamMetadata *metadata[1];
|
FLAC__StreamMetadata *metadata[3];
|
||||||
|
unsigned i = 0, n = 0;
|
||||||
|
|
||||||
printf("generating FLAC file for test\n");
|
printf("generating FLAC file for test\n");
|
||||||
|
|
||||||
@ -513,20 +514,38 @@ static FLAC__bool generate_file_()
|
|||||||
vorbiscomment.data.vorbis_comment.comments = 0;
|
vorbiscomment.data.vorbis_comment.comments = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (0 == (cuesheet = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET)))
|
||||||
|
return die_("priming our metadata");
|
||||||
|
cuesheet->is_last = false;
|
||||||
|
strcpy(cuesheet->data.cue_sheet.media_catalog_number, "bogo-MCN");
|
||||||
|
cuesheet->data.cue_sheet.lead_in = 123;
|
||||||
|
cuesheet->data.cue_sheet.is_cd = false;
|
||||||
|
if (!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, 0))
|
||||||
|
return die_("priming our metadata");
|
||||||
|
cuesheet->data.cue_sheet.tracks[0].number = 1;
|
||||||
|
if (!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, 0, 0))
|
||||||
|
return die_("priming our metadata");
|
||||||
|
}
|
||||||
|
|
||||||
padding.is_last = true;
|
padding.is_last = true;
|
||||||
padding.type = FLAC__METADATA_TYPE_PADDING;
|
padding.type = FLAC__METADATA_TYPE_PADDING;
|
||||||
padding.length = 1234;
|
padding.length = 1234;
|
||||||
|
|
||||||
metadata[0] = &padding;
|
metadata[n++] = &vorbiscomment;
|
||||||
|
if (include_cuesheet)
|
||||||
|
metadata[n++] = cuesheet;
|
||||||
|
metadata[n++] = &padding;
|
||||||
|
|
||||||
if(
|
if(
|
||||||
!insert_to_our_metadata_(&streaminfo, 0, /*copy=*/true) ||
|
!insert_to_our_metadata_(&streaminfo, i++, /*copy=*/true) ||
|
||||||
!insert_to_our_metadata_(&vorbiscomment, 1, /*copy=*/true) ||
|
!insert_to_our_metadata_(&vorbiscomment, i++, /*copy=*/true) ||
|
||||||
!insert_to_our_metadata_(&padding, 2, /*copy=*/true)
|
(include_cuesheet && !insert_to_our_metadata_(cuesheet, i++, /*copy=*/false)) ||
|
||||||
|
!insert_to_our_metadata_(&padding, i++, /*copy=*/true)
|
||||||
)
|
)
|
||||||
return die_("priming our metadata");
|
return die_("priming our metadata");
|
||||||
|
|
||||||
if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, 1))
|
if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, n))
|
||||||
return die_("creating the encoded file");
|
return die_("creating the encoded file");
|
||||||
|
|
||||||
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
|
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
|
||||||
@ -605,10 +624,11 @@ static FLAC__bool test_level_0_()
|
|||||||
{
|
{
|
||||||
FLAC__StreamMetadata streaminfo;
|
FLAC__StreamMetadata streaminfo;
|
||||||
FLAC__StreamMetadata *tags = 0;
|
FLAC__StreamMetadata *tags = 0;
|
||||||
|
FLAC__StreamMetadata *cuesheet = 0;
|
||||||
|
|
||||||
printf("\n\n++++++ testing level 0 interface\n");
|
printf("\n\n++++++ testing level 0 interface\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!test_file_(flacfile_, decoder_metadata_callback_null_))
|
if(!test_file_(flacfile_, decoder_metadata_callback_null_))
|
||||||
@ -646,6 +666,19 @@ static FLAC__bool test_level_0_()
|
|||||||
|
|
||||||
FLAC__metadata_object_delete(tags);
|
FLAC__metadata_object_delete(tags);
|
||||||
|
|
||||||
|
printf("testing FLAC__metadata_get_cuesheet()... ");
|
||||||
|
|
||||||
|
if(!FLAC__metadata_get_cuesheet(flacfile_, &cuesheet))
|
||||||
|
return die_("during FLAC__metadata_get_cuesheet()");
|
||||||
|
|
||||||
|
/* check to see if some basic data matches (c.f. generate_file_()) */
|
||||||
|
if(cuesheet->data.cue_sheet.lead_in != 123)
|
||||||
|
return die_("mismatch in cuesheet->data.vorbis_comment.num_comments");
|
||||||
|
|
||||||
|
printf("OK\n");
|
||||||
|
|
||||||
|
FLAC__metadata_object_delete(cuesheet);
|
||||||
|
|
||||||
if(!remove_file_(flacfile_))
|
if(!remove_file_(flacfile_))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -668,7 +701,7 @@ static FLAC__bool test_level_1_()
|
|||||||
|
|
||||||
printf("simple iterator on read-only file\n");
|
printf("simple iterator on read-only file\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!change_stats_(flacfile_, /*read_only=*/true))
|
if(!change_stats_(flacfile_, /*read_only=*/true))
|
||||||
@ -1327,7 +1360,7 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based)
|
|||||||
|
|
||||||
printf("generate read-only file\n");
|
printf("generate read-only file\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!change_stats_(flacfile_, /*read_only=*/true))
|
if(!change_stats_(flacfile_, /*read_only=*/true))
|
||||||
@ -1840,7 +1873,7 @@ static FLAC__bool test_level_2_misc_()
|
|||||||
|
|
||||||
printf("generate file\n");
|
printf("generate file\n");
|
||||||
|
|
||||||
if(!generate_file_())
|
if(!generate_file_(/*include_cuesheet=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
printf("create chain\n");
|
printf("create chain\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user