mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Add support for AIFF-C files.
This commit is contained in:
parent
be33389884
commit
3b8c7d4e3a
@ -265,7 +265,7 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
|
||||
return new MP4::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WMA" || ext == "ASF")
|
||||
return new ASF::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "AIF" || ext == "AIFF")
|
||||
if(ext == "AIF" || ext == "AIFF" || ext == "AFC" || ext == "AIFC")
|
||||
return new RIFF::AIFF::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WAV")
|
||||
return new RIFF::WAV::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
|
@ -38,16 +38,17 @@ public:
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
sampleWidth(0),
|
||||
sampleFrames(0)
|
||||
{
|
||||
|
||||
}
|
||||
sampleFrames(0) {}
|
||||
|
||||
int length;
|
||||
int bitrate;
|
||||
int sampleRate;
|
||||
int channels;
|
||||
int sampleWidth;
|
||||
|
||||
ByteVector compressionType;
|
||||
String compressionName;
|
||||
|
||||
uint sampleFrames;
|
||||
};
|
||||
|
||||
@ -96,12 +97,31 @@ TagLib::uint RIFF::AIFF::Properties::sampleFrames() const
|
||||
return d->sampleFrames;
|
||||
}
|
||||
|
||||
bool RIFF::AIFF::Properties::isAiffC() const
|
||||
{
|
||||
return (!d->compressionType.isEmpty());
|
||||
}
|
||||
|
||||
ByteVector RIFF::AIFF::Properties::compressionType() const
|
||||
{
|
||||
return d->compressionType;
|
||||
}
|
||||
|
||||
String RIFF::AIFF::Properties::compressionName() const
|
||||
{
|
||||
return d->compressionName;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::AIFF::Properties::read(const ByteVector &data)
|
||||
{
|
||||
if(data.size() < 18) {
|
||||
debug("RIFF::AIFF::Properties::read() - \"COMM\" chunk is too short for AIFF.");
|
||||
return;
|
||||
}
|
||||
|
||||
d->channels = data.toShort(0U);
|
||||
d->sampleFrames = data.toUInt(2U);
|
||||
d->sampleWidth = data.toShort(6U);
|
||||
@ -109,4 +129,9 @@ void RIFF::AIFF::Properties::read(const ByteVector &data)
|
||||
d->sampleRate = (int)sampleRate;
|
||||
d->bitrate = (int)((sampleRate * d->sampleWidth * d->channels) / 1000.0);
|
||||
d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0;
|
||||
|
||||
if(data.size() >= 23) {
|
||||
d->compressionType = data.mid(18, 4);
|
||||
d->compressionName = String(data.mid(23, static_cast<uchar>(data[22])));
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,30 @@ namespace TagLib {
|
||||
int sampleWidth() const;
|
||||
uint sampleFrames() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the file is in AIFF-C format, false if AIFF format.
|
||||
*/
|
||||
bool isAiffC() const;
|
||||
|
||||
/*!
|
||||
* Returns the compression type of the AIFF-C file. For example, "NONE" for
|
||||
* not compressed, "ACE2" for ACE 2-to-1.
|
||||
*
|
||||
* If the file is in AIFF format, always returns an empty vector.
|
||||
*
|
||||
* \see isAiffC()
|
||||
*/
|
||||
ByteVector compressionType() const;
|
||||
|
||||
/*!
|
||||
* Returns the concrete compression name of the AIFF-C file.
|
||||
*
|
||||
* If the file is in AIFF format, always returns an empty string.
|
||||
*
|
||||
* \see isAiffC()
|
||||
*/
|
||||
String compressionName() const;
|
||||
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
|
BIN
tests/data/alaw.aifc
Normal file
BIN
tests/data/alaw.aifc
Normal file
Binary file not shown.
BIN
tests/data/segfault.aif
Normal file
BIN
tests/data/segfault.aif
Normal file
Binary file not shown.
@ -13,6 +13,8 @@ class TestAIFF : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestAIFF);
|
||||
CPPUNIT_TEST(testReading);
|
||||
CPPUNIT_TEST(testAiffCProperties);
|
||||
CPPUNIT_TEST(testReading);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -27,6 +29,24 @@ public:
|
||||
delete f;
|
||||
}
|
||||
|
||||
void testAiffCProperties()
|
||||
{
|
||||
ScopedFileCopy copy("alaw", ".aifc");
|
||||
string filename = copy.fileName();
|
||||
|
||||
RIFF::AIFF::File *f = new RIFF::AIFF::File(filename.c_str());
|
||||
CPPUNIT_ASSERT(f->audioProperties()->isAiffC());
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("ALAW"), f->audioProperties()->compressionType());
|
||||
CPPUNIT_ASSERT_EQUAL(String("SGI CCITT G.711 A-law"), f->audioProperties()->compressionName());
|
||||
delete f;
|
||||
}
|
||||
|
||||
void testFuzzedFiles()
|
||||
{
|
||||
RIFF::AIFF::File f(TEST_FILE_PATH_C("segfault.aif"));
|
||||
CPPUNIT_ASSERT(!f.isValid());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestAIFF);
|
||||
|
Loading…
x
Reference in New Issue
Block a user