From 4bdece1af7ece65b31ed3be346845e65ce9ce9f8 Mon Sep 17 00:00:00 2001 From: Zeugma440 Date: Thu, 1 Dec 2022 22:46:13 +0100 Subject: [PATCH] New bit depth audio data property --- ATL.test/IO/AudioData/AudioData.cs | 128 ++++++++++++----------- ATL.test/IO/HighLevel.cs | 1 + ATL/AudioData/AudioFileIO.cs | 5 + ATL/AudioData/IO/AA.cs | 3 + ATL/AudioData/IO/AAC.cs | 3 + ATL/AudioData/IO/AC3.cs | 3 + ATL/AudioData/IO/AIFF.cs | 21 ++-- ATL/AudioData/IO/Ape.cs | 7 +- ATL/AudioData/IO/CAF.cs | 7 +- ATL/AudioData/IO/DSF.cs | 7 +- ATL/AudioData/IO/DTS.cs | 5 +- ATL/AudioData/IO/DummyReader.cs | 4 + ATL/AudioData/IO/FLAC.cs | 1 + ATL/AudioData/IO/GYM.cs | 1 + ATL/AudioData/IO/IT.cs | 1 + ATL/AudioData/IO/MIDI.cs | 1 + ATL/AudioData/IO/MOD.cs | 1 + ATL/AudioData/IO/MP4.cs | 1 + ATL/AudioData/IO/MPEGaudio.cs | 1 + ATL/AudioData/IO/MPEGplus.cs | 1 + ATL/AudioData/IO/Ogg.cs | 4 + ATL/AudioData/IO/OptimFROG.cs | 6 ++ ATL/AudioData/IO/PSF.cs | 1 + ATL/AudioData/IO/S3M.cs | 1 + ATL/AudioData/IO/SPC.cs | 1 + ATL/AudioData/IO/TAK.cs | 10 +- ATL/AudioData/IO/TTA.cs | 5 +- ATL/AudioData/IO/TwinVQ.cs | 1 + ATL/AudioData/IO/VGM.cs | 1 + ATL/AudioData/IO/WAV.cs | 36 ++----- ATL/AudioData/IO/WAVPack.cs | 35 ++----- ATL/AudioData/IO/WMA.cs | 7 +- ATL/AudioData/IO/XM.cs | 1 + ATL/AudioData/Interfaces/IAudioDataIO.cs | 8 ++ ATL/Entities/Track.cs | 6 ++ 35 files changed, 173 insertions(+), 152 deletions(-) diff --git a/ATL.test/IO/AudioData/AudioData.cs b/ATL.test/IO/AudioData/AudioData.cs index 99abdc3b..defa49c6 100644 --- a/ATL.test/IO/AudioData/AudioData.cs +++ b/ATL.test/IO/AudioData/AudioData.cs @@ -20,6 +20,7 @@ private void testGenericAudio( string resource, int duration, int bitrate, + int bitDepth, int samplerate, bool isVbr, int codecFamily, @@ -41,6 +42,7 @@ private void testGenericAudio( Assert.AreEqual(duration, (int)Math.Round(theReader.Duration)); Assert.AreEqual(bitrate, (int)Math.Round(theReader.BitRate)); + Assert.AreEqual(bitDepth, theReader.BitDepth); Assert.AreEqual(samplerate, theReader.SampleRate); Assert.AreEqual(isVbr, theReader.IsVBR); Assert.AreEqual(codecFamily, theReader.CodecFamily); @@ -54,230 +56,230 @@ private void testGenericAudio( [TestMethod] public void Audio_MP3() { - testGenericAudio("MP3/01 - Title Screen.mp3", 3866, 129, 44100, true, CF_LOSSY, JOINT_STEREO, "MPEG Audio (Layer III)", 2048, 62342); // VBR - testGenericAudio("MP3/headerPatternIsNotHeader.mp3", 184, 192, 44100, false, CF_LOSSY, JOINT_STEREO, "MPEG Audio (Layer III)", 1252, 3340); // Malpositioned header - testGenericAudio("MP3/truncated_frame.mp3", 520, 320, 48000, false, CF_LOSSY, STEREO, "MPEG Audio (Layer III)", 954, 19908); // Malpositioned header 2 - testGenericAudio("MP3/mp1Layer1.mp1", 520, 384, 44100, false, CF_LOSSY, STEREO, "MPEG Audio (Layer I)", 0, 25080); // MPEG1 Layer 1 - testGenericAudio("MP3/mp1Layer2.mp1", 752, 384, 44100, false, CF_LOSSY, STEREO, "MPEG Audio (Layer II)", 0, 36362); // MPEG1 Layer 2 - testGenericAudio("MP3/mp2Layer1.mp2", 1408, 128, 22050, false, CF_LOSSY, JOINT_STEREO, "MPEG Audio (Layer I)", 0, 22572); // MPEG2 Layer 1 - testGenericAudio("MP3/mp2Layer2.mp2", 1296, 160, 24000, false, CF_LOSSY, STEREO, "MPEG Audio (Layer II)", 0, 25920); // MPEG2 Layer 2 + testGenericAudio("MP3/01 - Title Screen.mp3", 3866, 129, -1, 44100, true, CF_LOSSY, JOINT_STEREO, "MPEG Audio (Layer III)", 2048, 62342); // VBR + testGenericAudio("MP3/headerPatternIsNotHeader.mp3", 184, 192, -1, 44100, false, CF_LOSSY, JOINT_STEREO, "MPEG Audio (Layer III)", 1252, 3340); // Malpositioned header + testGenericAudio("MP3/truncated_frame.mp3", 520, 320, -1, 48000, false, CF_LOSSY, STEREO, "MPEG Audio (Layer III)", 954, 19908); // Malpositioned header 2 + testGenericAudio("MP3/mp1Layer1.mp1", 520, 384, -1, 44100, false, CF_LOSSY, STEREO, "MPEG Audio (Layer I)", 0, 25080); // MPEG1 Layer 1 + testGenericAudio("MP3/mp1Layer2.mp1", 752, 384, -1, 44100, false, CF_LOSSY, STEREO, "MPEG Audio (Layer II)", 0, 36362); // MPEG1 Layer 2 + testGenericAudio("MP3/mp2Layer1.mp2", 1408, 128, -1, 22050, false, CF_LOSSY, JOINT_STEREO, "MPEG Audio (Layer I)", 0, 22572); // MPEG2 Layer 1 + testGenericAudio("MP3/mp2Layer2.mp2", 1296, 160, -1, 24000, false, CF_LOSSY, STEREO, "MPEG Audio (Layer II)", 0, 25920); // MPEG2 Layer 2 } [TestMethod] public void Audio_MP4() { - testGenericAudio("MP4/mp4.m4a", 14053, 75, 48000, true, CF_LOSSY, ISO_3_4_1, "MPEG-4 Part 14", 25746, 131708); + testGenericAudio("MP4/mp4.m4a", 14053, 75, -1, 48000, true, CF_LOSSY, ISO_3_4_1, "MPEG-4 Part 14", 25746, 131708); } [TestMethod] public void Audio_AAC_ADTS() { - testGenericAudio("AAC/adts_CBR88_8s.aac", 7742, 88, 44100, false, CF_LOSSY, STEREO, "Advanced Audio Coding", 0, 85022); // should be 7646 ms as well + testGenericAudio("AAC/adts_CBR88_8s.aac", 7742, 88, -1, 44100, false, CF_LOSSY, STEREO, "Advanced Audio Coding", 0, 85022); // should be 7646 ms as well } [TestMethod] public void Audio_AAC_ADIF() { - testGenericAudio("AAC/adif_CBR88_8s.aac", 7729, 88, 44100, false, CF_LOSSY, STEREO, "Advanced Audio Coding", 0, 85014); // should be 7646 ms as well + testGenericAudio("AAC/adif_CBR88_8s.aac", 7729, 88, -1, 44100, false, CF_LOSSY, STEREO, "Advanced Audio Coding", 0, 85014); // should be 7646 ms as well } [TestMethod] public void Audio_WMA() { - testGenericAudio("WMA/wma.wma", 14439, 9, 8000, false, CF_LOSSY, MONO, "Windows Media Audio", 18313, 16269); + testGenericAudio("WMA/wma.wma", 14439, 9, 16, 8000, false, CF_LOSSY, MONO, "Windows Media Audio", 18313, 16269); } [TestMethod] public void Audio_OGG() { - testGenericAudio("OGG/ogg.ogg", 33003, 69, 22050, true, CF_LOSSY, STEREO, "OGG (Vorbis)", 23125, 278029); + testGenericAudio("OGG/ogg.ogg", 33003, 69, -1, 22050, true, CF_LOSSY, STEREO, "OGG (Vorbis)", 23125, 278029); } [TestMethod] public void Audio_Opus() { - testGenericAudio("OPUS/opus.opus", 30959, 33, 48000, true, CF_LOSSY, STEREO, "OGG (Opus)", 19479, 126225); + testGenericAudio("OPUS/opus.opus", 30959, 33, -1, 48000, true, CF_LOSSY, STEREO, "OGG (Opus)", 19479, 126225); } [TestMethod] public void Audio_FLAC() { - testGenericAudio("FLAC/flac.flac", 5176, 694, 44100, false, CF_LOSSLESS, STEREO, "Free Lossless Audio Codec", 18030, 448997); - testGenericAudio("OGG/embedded-flac.ogg", 5176, 635, 44100, false, CF_LOSSLESS, STEREO, "OGG (FLAC)", 397, 410863); + testGenericAudio("FLAC/flac.flac", 5176, 694, 16, 44100, false, CF_LOSSLESS, STEREO, "Free Lossless Audio Codec", 18030, 448997); + testGenericAudio("OGG/embedded-flac.ogg", 5176, 635, 16, 44100, false, CF_LOSSLESS, STEREO, "OGG (FLAC)", 397, 410863); } [TestMethod] public void Audio_MPC() { - testGenericAudio("MPC/SV8.mpc", 7646, 127, 44100, true, CF_LOSSY, JOINT_STEREO_MID_SIDE, "Musepack / MPEGplus", 4, 121061); - testGenericAudio("MPC/SV7.mpc", 7654, 131, 44100, true, CF_LOSSY, JOINT_STEREO, "Musepack / MPEGplus", 0, 125432); // should be 7646 ms as well - testGenericAudio("MPC/SV5.mp+", 7654, 112, 44100, true, CF_LOSSY, JOINT_STEREO, "Musepack / MPEGplus", 0, 107160); // should be 7646 ms as well - testGenericAudio("MPC/SV4.mp+", 7654, 112, 44100, true, CF_LOSSY, JOINT_STEREO, "Musepack / MPEGplus", 0, 107156); // should be 7646 ms as well + testGenericAudio("MPC/SV8.mpc", 7646, 127, -1, 44100, true, CF_LOSSY, JOINT_STEREO_MID_SIDE, "Musepack / MPEGplus", 4, 121061); + testGenericAudio("MPC/SV7.mpc", 7654, 131, -1, 44100, true, CF_LOSSY, JOINT_STEREO, "Musepack / MPEGplus", 0, 125432); // should be 7646 ms as well + testGenericAudio("MPC/SV5.mp+", 7654, 112, -1, 44100, true, CF_LOSSY, JOINT_STEREO, "Musepack / MPEGplus", 0, 107160); // should be 7646 ms as well + testGenericAudio("MPC/SV4.mp+", 7654, 112, -1, 44100, true, CF_LOSSY, JOINT_STEREO, "Musepack / MPEGplus", 0, 107156); // should be 7646 ms as well } [TestMethod] public void Audio_AC3() { - testGenericAudio("AC3/empty.ac3", 4969, 128, 44100, false, CF_LOSSY, STEREO, "Dolby Digital", 0, 79508); + testGenericAudio("AC3/empty.ac3", 4969, 128, -1, 44100, false, CF_LOSSY, STEREO, "Dolby Digital", 0, 79508); } [TestMethod] public void Audio_DTS() { - testGenericAudio("DTS/dts.dts", 9834, 1536, 48000, false, CF_LOSSY, ISO_3_2_0, "Digital Theatre System", 0, 1888194); + testGenericAudio("DTS/dts.dts", 9834, 1536, 16, 48000, false, CF_LOSSY, ISO_3_2_0, "Digital Theatre System", 0, 1888194); } [TestMethod] public void Audio_DSF_DSD() { - testGenericAudio("DSF/dsf.dsf", 3982, 5671, 2822400, false, CF_LOSSLESS, STEREO, "Direct Stream Digital", 80, 2809868); + testGenericAudio("DSF/dsf.dsf", 3982, 5671, 1, 2822400, false, CF_LOSSLESS, STEREO, "Direct Stream Digital", 80, 2809868); } [TestMethod] public void Audio_IT() { - testGenericAudio("IT/empty.it", 475505, 1, 0, false, CF_SEQ_WAV, STEREO, "Impulse Tracker", 32, 578264); - testGenericAudio("IT/it.it", 42292, 1, 0, false, CF_SEQ_WAV, STEREO, "Impulse Tracker", 32, 22623); - testGenericAudio("IT/hasInstruments.it", 68092, 1, 0, false, CF_SEQ_WAV, STEREO, "Impulse Tracker", 32, 51781); + testGenericAudio("IT/empty.it", 475505, 1, -1, 0, false, CF_SEQ_WAV, STEREO, "Impulse Tracker", 32, 578264); + testGenericAudio("IT/it.it", 42292, 1, -1, 0, false, CF_SEQ_WAV, STEREO, "Impulse Tracker", 32, 22623); + testGenericAudio("IT/hasInstruments.it", 68092, 1, -1, 0, false, CF_SEQ_WAV, STEREO, "Impulse Tracker", 32, 51781); } [TestMethod] public void Audio_Midi() { - testGenericAudio("MID/ataezou - I (HEART) RUEAMATASU.mid", 66497, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 21264); - testGenericAudio("MID/TRANSIT1.MID", 104950, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 7087); - testGenericAudio("MID/ROQ.MID", 503602, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 59375); + testGenericAudio("MID/ataezou - I (HEART) RUEAMATASU.mid", 66497, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 21264); + testGenericAudio("MID/TRANSIT1.MID", 104950, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 7087); + testGenericAudio("MID/ROQ.MID", 503602, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 59375); // This one has a track header position issue - testGenericAudio("MID/yoru-uta.mid", 251182, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 13298); + testGenericAudio("MID/yoru-uta.mid", 251182, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 13298); // This one has 'sequencer data' and 'smpte offset' events - testGenericAudio("MID/memory.mid", 300915, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 93597); + testGenericAudio("MID/memory.mid", 300915, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 93597); // This one has 'channel prefix', 'poly pressure' and 'channel pressure' events - testGenericAudio("MID/villg.mid", 100059, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 21660); + testGenericAudio("MID/villg.mid", 100059, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 21660); // This one has 'program change repeat' and 'channel pressure repeat' events - testGenericAudio("MID/chron.mid", 323953, 0, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 56129); + testGenericAudio("MID/chron.mid", 323953, 0, -1, 0, false, CF_SEQ, STEREO, "Musical Instruments Digital Interface", 14, 56129); } [TestMethod] public void Audio_MOD() { - testGenericAudio("MOD/empty.mod", 158976, 0, 0, false, CF_SEQ_WAV, STEREO, "Tracker Module (ProTracker)", 20, 42042); - testGenericAudio("MOD/mod.mod", 330240, 0, 0, false, CF_SEQ_WAV, STEREO, "Tracker Module (ProTracker)", 20, 99986); + testGenericAudio("MOD/empty.mod", 158976, 0, -1, 0, false, CF_SEQ_WAV, STEREO, "Tracker Module (ProTracker)", 20, 42042); + testGenericAudio("MOD/mod.mod", 330240, 0, -1, 0, false, CF_SEQ_WAV, STEREO, "Tracker Module (ProTracker)", 20, 99986); } [TestMethod] public void Audio_Ape() { - testGenericAudio("APE/ape.ape", 7646, 652, 44100, false, CF_LOSSLESS, STEREO, "Monkey's Audio", 0, 623078); - testGenericAudio("APE/v394.ape", 7646, 599, 44100, false, CF_LOSSLESS, STEREO, "Monkey's Audio", 0, 572806); + testGenericAudio("APE/ape.ape", 7646, 652, 16, 44100, false, CF_LOSSLESS, STEREO, "Monkey's Audio", 0, 623078); + testGenericAudio("APE/v394.ape", 7646, 599, 16, 44100, false, CF_LOSSLESS, STEREO, "Monkey's Audio", 0, 572806); } [TestMethod] public void Audio_S3M() { - testGenericAudio("S3M/empty.s3m", 126720, 0, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 13936); - testGenericAudio("S3M/s3m.s3m", 404846, 2, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 626624); + testGenericAudio("S3M/empty.s3m", 126720, 0, -1, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 13936); + testGenericAudio("S3M/s3m.s3m", 404846, 2, -1, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 626624); // This one contains extra instructions - testGenericAudio("S3M/s3m2.s3m", 9796, 2, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 17870); + testGenericAudio("S3M/s3m2.s3m", 9796, 2, -1, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 17870); // This one contains yet other extra instructions - testGenericAudio("S3M/s3m3.s3m", 475070, 1, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 375488); + testGenericAudio("S3M/s3m3.s3m", 475070, 1, -1, 0, false, CF_SEQ_WAV, STEREO, "ScreamTracker Module", 32, 375488); } [TestMethod] public void Audio_XM() { - testGenericAudio("XM/empty.xm", 55172, 1, 0, false, CF_SEQ_WAV, STEREO, "Extended Module", 60, 55729); - testGenericAudio("XM/xm.xm", 260667, 2, 0, false, CF_SEQ_WAV, STEREO, "Extended Module", 60, 430062); + testGenericAudio("XM/empty.xm", 55172, 1, -1, 0, false, CF_SEQ_WAV, STEREO, "Extended Module", 60, 55729); + testGenericAudio("XM/xm.xm", 260667, 2, -1, 0, false, CF_SEQ_WAV, STEREO, "Extended Module", 60, 430062); } [TestMethod] public void Audio_DSF_PSF() { - testGenericAudio("PSF/psf.psf", 159000, 10, 44100, false, CF_SEQ_WAV, STEREO, "Portable Sound Format (Playstation)", 0, 204788); - testGenericAudio("PSF/nolength.psf", 180000, 13, 44100, false, CF_SEQ_WAV, STEREO, "Portable Sound Format (Playstation)", 0, 287437); - testGenericAudio("DSF/adgpp_PLAY_01_05.dsf", 26200, 0, 44100, false, CF_SEQ_WAV, STEREO, "Portable Sound Format (Dreamcast)", 0, 30, 1); + testGenericAudio("PSF/psf.psf", 159000, 10, -1, 44100, false, CF_SEQ_WAV, STEREO, "Portable Sound Format (Playstation)", 0, 204788); + testGenericAudio("PSF/nolength.psf", 180000, 13, -1, 44100, false, CF_SEQ_WAV, STEREO, "Portable Sound Format (Playstation)", 0, 287437); + testGenericAudio("DSF/adgpp_PLAY_01_05.dsf", 26200, 0, -1, 44100, false, CF_SEQ_WAV, STEREO, "Portable Sound Format (Dreamcast)", 0, 30, 1); } [TestMethod] public void Audio_SPC() { - testGenericAudio("SPC/spc.spc", 69, 7635, 32000, false, CF_SEQ_WAV, STEREO, "SPC700 Sound Files", 209, 65852); + testGenericAudio("SPC/spc.spc", 69, 7635, -1, 32000, false, CF_SEQ_WAV, STEREO, "SPC700 Sound Files", 209, 65852); ; } [TestMethod] public void Audio_VQF() { - testGenericAudio("VQF/vqf.vqf", 120130, 20, 22050, false, CF_LOSSY, MONO, "TwinVQ", 174, 300332); + testGenericAudio("VQF/vqf.vqf", 120130, 20, -1, 22050, false, CF_LOSSY, MONO, "TwinVQ", 174, 300332); } [TestMethod] public void Audio_TAK() { - testGenericAudio("TAK/003 BlackBird.tak", 6082, 634, 44100, false, CF_LOSSLESS, STEREO, "Tom's lossless Audio Kompressor", 0, 476797); + testGenericAudio("TAK/003 BlackBird.tak", 6082, 634, 16, 44100, false, CF_LOSSLESS, STEREO, "Tom's lossless Audio Kompressor", 0, 476797); } [TestMethod] public void Audio_WAV() { - testGenericAudio("WAV/wav.wav", 7646, 1411, 44100, false, CF_LOSSLESS, STEREO, "PCM (uncompressed audio) (Windows PCM)", 44, 1348720); - testGenericAudio("WAV/rifx.wav", 0, 2117, 44100, false, CF_LOSSLESS, STEREO, "PCM (uncompressed audio) (Unknown)", 80, 39690); + testGenericAudio("WAV/wav.wav", 7646, 1411, 16, 44100, false, CF_LOSSLESS, STEREO, "PCM (uncompressed audio) (Windows PCM)", 44, 1348720); + testGenericAudio("WAV/rifx.wav", 0, 2117, 24, 44100, false, CF_LOSSLESS, STEREO, "PCM (uncompressed audio) (Unknown)", 80, 39690); } [TestMethod] public void Audio_WV() { - testGenericAudio("WV/losslessv3.wv", 7646, 659, 44100, false, CF_LOSSLESS, STEREO, "WAVPack", 44, 629811); - testGenericAudio("WV/lossyv3.wv", 7646, 342, 44100, false, CF_LOSSY, STEREO, "WAVPack", 44, 326945); - testGenericAudio("WV/lossyv440.wv", 7646, 206, 44100, false, CF_LOSSY, STEREO, "WAVPack", 132, 196658); - testGenericAudio("WV/losslessv4.wv", 6082, 645, 44100, false, CF_LOSSLESS, STEREO, "WAVPack", 154, 490420); + testGenericAudio("WV/losslessv3.wv", 7646, 659, -1, 44100, false, CF_LOSSLESS, STEREO, "WAVPack", 44, 629811); + testGenericAudio("WV/lossyv3.wv", 7646, 342, 4, 44100, false, CF_LOSSY, STEREO, "WAVPack", 44, 326945); + testGenericAudio("WV/lossyv440.wv", 7646, 206, 16, 44100, false, CF_LOSSY, STEREO, "WAVPack", 132, 196658); + testGenericAudio("WV/losslessv4.wv", 6082, 645, 16, 44100, false, CF_LOSSLESS, STEREO, "WAVPack", 154, 490420); } [TestMethod] public void Audio_OFR() { - testGenericAudio("OFR/BlackBird.ofr", 6082, 620, 44100, false, CF_LOSSLESS, STEREO, "OptimFROG", 0, 471627); + testGenericAudio("OFR/BlackBird.ofr", 6082, 620, 16, 44100, false, CF_LOSSLESS, STEREO, "OptimFROG", 0, 471627); } [TestMethod] public void Audio_TTA() { - testGenericAudio("TTA/BlackBird.tta", 6082, 659, 44100, false, CF_LOSSY, STEREO, "True Audio", 0, 501282); + testGenericAudio("TTA/BlackBird.tta", 6082, 659, 16, 44100, false, CF_LOSSY, STEREO, "True Audio", 0, 501282); } [TestMethod] public void Audio_AIFF() { - testGenericAudio("AIF/aiff_empty.aif", 2937, 512, 8000, false, CF_LOSSLESS, STEREO, "Audio Interchange File Format", 120, 187960); + testGenericAudio("AIF/aiff_empty.aif", 2937, 512, 32, 8000, false, CF_LOSSLESS, STEREO, "Audio Interchange File Format", 120, 187960); } [TestMethod] public void Audio_AIFC() { - testGenericAudio("AIF/aifc_tagged.aif", 2937, 128, 8000, false, CF_LOSSY, STEREO, "Audio Interchange File Format", 146, 47002); + testGenericAudio("AIF/aifc_tagged.aif", 2937, 128, 8, 8000, false, CF_LOSSY, STEREO, "Audio Interchange File Format", 146, 47002); } [TestMethod] public void Audio_VGM() { - testGenericAudio("VGM/vgm.vgm", 86840, 1, 44100, false, CF_SEQ_WAV, STEREO, "Video Game Music", 4, 7708); - testGenericAudio("VGM/vgz.vgz", 232584, 3, 44100, false, CF_SEQ_WAV, STEREO, "Video Game Music", 4, 589589); + testGenericAudio("VGM/vgm.vgm", 86840, 1, -1, 44100, false, CF_SEQ_WAV, STEREO, "Video Game Music", 4, 7708); + testGenericAudio("VGM/vgz.vgz", 232584, 3, -1, 44100, false, CF_SEQ_WAV, STEREO, "Video Game Music", 4, 589589); } [TestMethod] public void Audio_GYM() { - testGenericAudio("GYM/gym.gym", 73000, 37, 44100, false, CF_SEQ_WAV, STEREO, "Genesis YM2612", 428, 341133); + testGenericAudio("GYM/gym.gym", 73000, 37, -1, 44100, false, CF_SEQ_WAV, STEREO, "Genesis YM2612", 428, 341133); } [TestMethod] public void Audio_AA() { - testGenericAudio("AA/aa.aa", 2967, 1, 8500, false, CF_LOSSY, MONO, "Audible (legacy) (acelp85)", 26806, 3152173); + testGenericAudio("AA/aa.aa", 2967, 1, -1, 8500, false, CF_LOSSY, MONO, "Audible (legacy) (acelp85)", 26806, 3152173); } [TestMethod] public void Audio_CAF() { - testGenericAudio("CAF/caf.caf", 3235, 176, 11025, false, CF_LOSSLESS, STEREO, "Apple Core Audio / Linear PCM", 4080, 71340); + testGenericAudio("CAF/caf.caf", 3235, 176, 16, 11025, false, CF_LOSSLESS, STEREO, "Apple Core Audio / Linear PCM", 4080, 71340); } #pragma warning restore S2699 // Tests should include assertions } diff --git a/ATL.test/IO/HighLevel.cs b/ATL.test/IO/HighLevel.cs index e20b3601..b7e61190 100644 --- a/ATL.test/IO/HighLevel.cs +++ b/ATL.test/IO/HighLevel.cs @@ -958,6 +958,7 @@ public void StreamedIO_R_Audio() Assert.AreEqual(33, theTrack.Duration); Assert.AreEqual(69, theTrack.Bitrate); + Assert.AreEqual(-1, theTrack.BitDepth); Assert.AreEqual(22050, theTrack.SampleRate); Assert.AreEqual(true, theTrack.IsVBR); Assert.AreEqual(23125, theTrack.TechnicalInformation.AudioDataOffset); diff --git a/ATL/AudioData/AudioFileIO.cs b/ATL/AudioData/AudioFileIO.cs index 1e75d0e1..a79c35c2 100644 --- a/ATL/AudioData/AudioFileIO.cs +++ b/ATL/AudioData/AudioFileIO.cs @@ -236,6 +236,11 @@ public double BitRate get => audioData.BitRate; } /// + public int BitDepth + { + get => audioData.BitDepth; + } + /// public int SampleRate { get => audioData.SampleRate; diff --git a/ATL/AudioData/IO/AA.cs b/ATL/AudioData/IO/AA.cs index a9b190f9..7e58b7c4 100644 --- a/ATL/AudioData/IO/AA.cs +++ b/ATL/AudioData/IO/AA.cs @@ -146,6 +146,9 @@ public int SampleRate } } } + + public int BitDepth => -1; // Irrelevant for lossy formats + public string FileName { get { return fileName; } diff --git a/ATL/AudioData/IO/AAC.cs b/ATL/AudioData/IO/AAC.cs index f0b24eda..73b6750e 100644 --- a/ATL/AudioData/IO/AAC.cs +++ b/ATL/AudioData/IO/AAC.cs @@ -92,6 +92,9 @@ public int SampleRate { get { return sampleRate; } } + + public int BitDepth => -1; // Irrelevant for lossy formats + public string FileName { get { return fileName; } diff --git a/ATL/AudioData/IO/AC3.cs b/ATL/AudioData/IO/AC3.cs index e822b817..ea3180c7 100644 --- a/ATL/AudioData/IO/AC3.cs +++ b/ATL/AudioData/IO/AC3.cs @@ -53,6 +53,9 @@ public int SampleRate { get { return (int)this.sampleRate; } } + + public int BitDepth => -1; // Irrelevant for lossy formats + public ChannelsArrangement ChannelsArrangement { get { return channelsArrangement; } diff --git a/ATL/AudioData/IO/AIFF.cs b/ATL/AudioData/IO/AIFF.cs index 9ccb3ee0..cd06c000 100644 --- a/ATL/AudioData/IO/AIFF.cs +++ b/ATL/AudioData/IO/AIFF.cs @@ -64,7 +64,7 @@ private struct ChunkHeader } // Private declarations - private uint bits; + private int bits; private string compression; private byte versionID; @@ -94,10 +94,6 @@ public byte VersionID // Version code { get { return this.versionID; } } - public uint Bits - { - get { return bits; } - } public double CompressionRatio { get { return getCompressionRatio(); } @@ -132,6 +128,9 @@ public double BitRate { get { return bitrate; } } + + public int BitDepth => (bits > 0) ? bits : -1; + public double Duration { get { return duration; } @@ -352,7 +351,7 @@ protected override bool read(BinaryReader source, MetaDataIO.ReadTagParams readT } uint numSampleFrames = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); - short sampleSize = StreamUtils.DecodeBEInt16(source.ReadBytes(2)); // This sample size is for uncompressed data only + bits = StreamUtils.DecodeBEInt16(source.ReadBytes(2)); // This sample size is for uncompressed data only byte[] byteArray = source.ReadBytes(10); Array.Reverse(byteArray); double aSampleRate = StreamUtils.ExtendedToDouble(byteArray); @@ -373,12 +372,12 @@ protected override bool read(BinaryReader source, MetaDataIO.ReadTagParams readT if (!compression.Equals(COMPRESSION_NONE)) // Sample size is specific to selected compression method { - if (compression.ToLower().Equals("fl32")) sampleSize = 32; - else if (compression.ToLower().Equals("fl64")) sampleSize = 64; - else if (compression.ToLower().Equals("alaw")) sampleSize = 8; - else if (compression.ToLower().Equals("ulaw")) sampleSize = 8; + if (compression.ToLower().Equals("fl32")) bits = 32; + else if (compression.ToLower().Equals("fl64")) bits = 64; + else if (compression.ToLower().Equals("alaw")) bits = 8; + else if (compression.ToLower().Equals("ulaw")) bits = 8; } - if (duration > 0) bitrate = sampleSize * numSampleFrames * channelsArrangement.NbChannels / duration; + if (duration > 0) bitrate = bits * numSampleFrames * channelsArrangement.NbChannels / duration; } } else if (header.ID.Equals(CHUNKTYPE_SOUND)) diff --git a/ATL/AudioData/IO/Ape.cs b/ATL/AudioData/IO/Ape.cs index af9d5e59..418cdfce 100644 --- a/ATL/AudioData/IO/Ape.cs +++ b/ATL/AudioData/IO/Ape.cs @@ -118,10 +118,6 @@ public ChannelsArrangement ChannelsArrangement { get { return channelsArrangement; } } - public int Bits - { - get { return bits; } - } public uint PeakLevel { get { return peakLevel; } @@ -190,6 +186,9 @@ public double Duration { get { return duration; } } + + public int BitDepth => bits; + public bool IsMetaSupported(MetaDataIOFactory.TagType metaDataType) { return (metaDataType == MetaDataIOFactory.TagType.APE) || (metaDataType == MetaDataIOFactory.TagType.ID3V1) || (metaDataType == MetaDataIOFactory.TagType.ID3V2); diff --git a/ATL/AudioData/IO/CAF.cs b/ATL/AudioData/IO/CAF.cs index 49a954b0..74c637be 100644 --- a/ATL/AudioData/IO/CAF.cs +++ b/ATL/AudioData/IO/CAF.cs @@ -129,6 +129,7 @@ class CAF : MetaDataIO, IAudioDataIO private double bitrate; private double duration; private uint channelsPerFrame; + private uint bitsPerChannel; double secondsPerByte; private ChannelsArrangement channelsArrangement; @@ -163,6 +164,9 @@ public double BitRate { get { return bitrate; } } + + public int BitDepth => (int)(bitsPerChannel * channelsPerFrame); + public double Duration { get { return duration; } @@ -217,6 +221,7 @@ protected void resetData() bitrate = 0; isVbr = false; codecFamily = 0; + bitsPerChannel = 0; channelsPerFrame = 0; channelsArrangement = null; secondsPerByte = 0; @@ -256,7 +261,7 @@ private void readAudioDescriptionChunk(BinaryReader source) uint bytesPerPacket = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); uint framesPerPacket = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); channelsPerFrame = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); - source.BaseStream.Seek(4, SeekOrigin.Current); // bits per channel + bitsPerChannel = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); sampleRate = (uint)Math.Round(m_sampleRate); diff --git a/ATL/AudioData/IO/DSF.cs b/ATL/AudioData/IO/DSF.cs index cafcec21..8c99b131 100644 --- a/ATL/AudioData/IO/DSF.cs +++ b/ATL/AudioData/IO/DSF.cs @@ -35,10 +35,6 @@ class DSF : IAudioDataIO, IMetaDataEmbedder // Public declarations - public uint Bits - { - get { return bits; } - } public double CompressionRatio { get { return getCompressionRatio(); } @@ -71,6 +67,9 @@ public double BitRate { get { return bitrate; } } + + public int BitDepth => (int)bits; + public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/DTS.cs b/ATL/AudioData/IO/DTS.cs index a4319fb0..a8283c42 100644 --- a/ATL/AudioData/IO/DTS.cs +++ b/ATL/AudioData/IO/DTS.cs @@ -30,10 +30,6 @@ class DTS : IAudioDataIO // Public declarations - public uint Bits - { - get { return bits; } - } public double CompressionRatio { get { return getCompressionRatio(); } @@ -66,6 +62,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => (int)bits; public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/DummyReader.cs b/ATL/AudioData/IO/DummyReader.cs index 8514ec6e..2703e634 100644 --- a/ATL/AudioData/IO/DummyReader.cs +++ b/ATL/AudioData/IO/DummyReader.cs @@ -38,6 +38,10 @@ public int SampleRate { get { return 0; } } + + /// + public int BitDepth => -1; + /// public bool IsVBR { diff --git a/ATL/AudioData/IO/FLAC.cs b/ATL/AudioData/IO/FLAC.cs index 77383844..cbdf48cb 100644 --- a/ATL/AudioData/IO/FLAC.cs +++ b/ATL/AudioData/IO/FLAC.cs @@ -93,6 +93,7 @@ public double BitRate { get { return Math.Round(((double)(sizeInfo.FileSize - AudioDataOffset)) * 8 / Duration); } } + public int BitDepth => bitsPerSample; public double Duration { get { return getDuration(); } diff --git a/ATL/AudioData/IO/GYM.cs b/ATL/AudioData/IO/GYM.cs index f4484534..4ee921a6 100644 --- a/ATL/AudioData/IO/GYM.cs +++ b/ATL/AudioData/IO/GYM.cs @@ -72,6 +72,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/IT.cs b/ATL/AudioData/IO/IT.cs index 4b9aeb8d..12e80b27 100644 --- a/ATL/AudioData/IO/IT.cs +++ b/ATL/AudioData/IO/IT.cs @@ -73,6 +73,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/MIDI.cs b/ATL/AudioData/IO/MIDI.cs index 2769f664..eeae308f 100644 --- a/ATL/AudioData/IO/MIDI.cs +++ b/ATL/AudioData/IO/MIDI.cs @@ -324,6 +324,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format /// public double Duration { diff --git a/ATL/AudioData/IO/MOD.cs b/ATL/AudioData/IO/MOD.cs index 98838f4a..59081d77 100644 --- a/ATL/AudioData/IO/MOD.cs +++ b/ATL/AudioData/IO/MOD.cs @@ -136,6 +136,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/MP4.cs b/ATL/AudioData/IO/MP4.cs index e3ca7a51..44fe8acd 100644 --- a/ATL/AudioData/IO/MP4.cs +++ b/ATL/AudioData/IO/MP4.cs @@ -161,6 +161,7 @@ public double BitRate { get { return bitrate / 1000.0; } } + public int BitDepth => -1; // Irrelevant for lossy formats public double Duration { get { return getDuration(); } diff --git a/ATL/AudioData/IO/MPEGaudio.cs b/ATL/AudioData/IO/MPEGaudio.cs index 02398d95..88a41026 100644 --- a/ATL/AudioData/IO/MPEGaudio.cs +++ b/ATL/AudioData/IO/MPEGaudio.cs @@ -234,6 +234,7 @@ public void LoadFromByteArray(byte[] data) public VBRData VBR { get => vbrData; } public bool IsVBR { get => vbrData.Found; } public double BitRate { get => getBitRate(); } + public int BitDepth => -1; // Irrelevant for lossy formats public double Duration { get => getDuration(); } public ChannelsArrangement ChannelsArrangement { get => getChannelsArrangement(HeaderFrame); } public int SampleRate { get => getSampleRate(); } diff --git a/ATL/AudioData/IO/MPEGplus.cs b/ATL/AudioData/IO/MPEGplus.cs index dadaf743..327aed95 100644 --- a/ATL/AudioData/IO/MPEGplus.cs +++ b/ATL/AudioData/IO/MPEGplus.cs @@ -60,6 +60,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for lossy formats public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/Ogg.cs b/ATL/AudioData/IO/Ogg.cs index 05a42a1a..84d24617 100644 --- a/ATL/AudioData/IO/Ogg.cs +++ b/ATL/AudioData/IO/Ogg.cs @@ -71,6 +71,7 @@ class Ogg : VorbisTagHolder, IMetaDataIO, IAudioDataIO private int contents; + private int bits; private int sampleRate; private ushort bitRateNominal; private ulong samples; @@ -100,6 +101,7 @@ public double BitRate { get { return getBitRate(); } } + public int BitDepth => bits; // Only for embedded FLAC public double Duration { get { return getDuration(); } @@ -312,6 +314,7 @@ protected void resetData() { sampleRate = 0; bitRateNominal = 0; + bits = -1; samples = 0; contents = -1; AudioDataOffset = -1; @@ -750,6 +753,7 @@ public bool Read(BinaryReader source, ReadTagParams readTagParams) { channelsArrangement = info.FlacParameters.getChannelsArrangement(); sampleRate = info.FlacParameters.SampleRate; + bits = info.FlacParameters.BitsPerSample; // No nominal bitrate for FLAC } diff --git a/ATL/AudioData/IO/OptimFROG.cs b/ATL/AudioData/IO/OptimFROG.cs index 7116c2f0..8a9df9a3 100644 --- a/ATL/AudioData/IO/OptimFROG.cs +++ b/ATL/AudioData/IO/OptimFROG.cs @@ -89,6 +89,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => getBits(); public double Duration { get { return duration; } @@ -153,6 +154,11 @@ private double getBitrate() return ((sizeInfo.FileSize - header.Size - sizeInfo.TotalTagSize) * 8 / Duration); } + private sbyte getBits() + { + return OFR_BITS[header.SampleType]; + } + public bool Read(BinaryReader source, SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams) { bool result = false; diff --git a/ATL/AudioData/IO/PSF.cs b/ATL/AudioData/IO/PSF.cs index 3a14606a..c191b6e9 100644 --- a/ATL/AudioData/IO/PSF.cs +++ b/ATL/AudioData/IO/PSF.cs @@ -104,6 +104,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/S3M.cs b/ATL/AudioData/IO/S3M.cs index d3f78f9f..79fb9e34 100644 --- a/ATL/AudioData/IO/S3M.cs +++ b/ATL/AudioData/IO/S3M.cs @@ -80,6 +80,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/SPC.cs b/ATL/AudioData/IO/SPC.cs index 3a0e9b04..86f0e093 100644 --- a/ATL/AudioData/IO/SPC.cs +++ b/ATL/AudioData/IO/SPC.cs @@ -166,6 +166,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/TAK.cs b/ATL/AudioData/IO/TAK.cs index 9519fb2e..a5f523a4 100644 --- a/ATL/AudioData/IO/TAK.cs +++ b/ATL/AudioData/IO/TAK.cs @@ -35,10 +35,6 @@ class TAK : IAudioDataIO // Public declarations - public uint Bits - { - get { return bits; } - } public double CompressionRatio { get { return getCompressionRatio(); } @@ -71,6 +67,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => (bits > 0) ? (int)bits : -1; public double Duration { get { return duration; } @@ -165,8 +162,9 @@ public bool Read(BinaryReader source, SizeInfo sizeInfo, MetaDataIO.ReadTagParam sampleCount = (readData16 >> 14) + (readData32 << 2) + ((restOfData & 0x00000080) << 34); - sampleRate = ((restOfData >> 4) & 0x03ffff) + 6000; // bits 4 to 21 - channelsArrangement = ChannelsArrangements.GuessFromChannelNumber((int)((restOfData >> 27) & 0x0F) + 1); // bits 28 to 31 + sampleRate = ((restOfData >> 4) & 0x03ffff) + 6000; // bits 5 to 22 + bits = ((restOfData >> 22) & 0x1f) + 8; // bits 23 to 27 + channelsArrangement = GuessFromChannelNumber((int)((restOfData >> 27) & 0x0f) + 1); // bits 28 to 31 if (sampleCount > 0) { diff --git a/ATL/AudioData/IO/TTA.cs b/ATL/AudioData/IO/TTA.cs index 0a72bbb8..fae955ee 100644 --- a/ATL/AudioData/IO/TTA.cs +++ b/ATL/AudioData/IO/TTA.cs @@ -30,10 +30,6 @@ class TTA : IAudioDataIO // Public declarations - public uint Bits - { - get { return bitsPerSample; } - } public double CompressionRatio { get { return getCompressionRatio(); } @@ -69,6 +65,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => (int)bitsPerSample; public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/TwinVQ.cs b/ATL/AudioData/IO/TwinVQ.cs index 0e8900ea..ccd70c89 100644 --- a/ATL/AudioData/IO/TwinVQ.cs +++ b/ATL/AudioData/IO/TwinVQ.cs @@ -112,6 +112,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for lossy formats public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/VGM.cs b/ATL/AudioData/IO/VGM.cs index ecd487dd..964f44b4 100644 --- a/ATL/AudioData/IO/VGM.cs +++ b/ATL/AudioData/IO/VGM.cs @@ -69,6 +69,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/IO/WAV.cs b/ATL/AudioData/IO/WAV.cs index 1b3b51ff..630059a7 100644 --- a/ATL/AudioData/IO/WAV.cs +++ b/ATL/AudioData/IO/WAV.cs @@ -95,14 +95,6 @@ class WAV : MetaDataIO, IAudioDataIO, IMetaDataEmbedder // ---------- INFORMATIVE INTERFACE IMPLEMENTATIONS & MANDATORY OVERRIDES // IAudioDataIO - public int SampleRate - { - get { return (int)this.sampleRate; } - } - public bool IsVBR - { - get { return false; } - } public Format AudioFormat { get @@ -112,26 +104,14 @@ public Format AudioFormat return f; } } - public int CodecFamily - { - get { return AudioDataIOFactory.CF_LOSSLESS; } - } - public string FileName - { - get { return filePath; } - } - public double BitRate - { - get { return bitrate; } - } - public double Duration - { - get { return duration; } - } - public ChannelsArrangement ChannelsArrangement - { - get { return channelsArrangement; } - } + public int SampleRate => (int)sampleRate; + public bool IsVBR => false; + public int CodecFamily => AudioDataIOFactory.CF_LOSSLESS; + public string FileName => filePath; + public double BitRate => bitrate; + public int BitDepth => bitsPerSample; + public double Duration => duration; + public ChannelsArrangement ChannelsArrangement => channelsArrangement; public bool IsMetaSupported(MetaDataIOFactory.TagType metaDataType) { return metaDataType == MetaDataIOFactory.TagType.ID3V1 || metaDataType == MetaDataIOFactory.TagType.ID3V2 || metaDataType == MetaDataIOFactory.TagType.NATIVE; // Native for bext, info and iXML chunks diff --git a/ATL/AudioData/IO/WAVPack.cs b/ATL/AudioData/IO/WAVPack.cs index 1aaba546..58e9aaf7 100644 --- a/ATL/AudioData/IO/WAVPack.cs +++ b/ATL/AudioData/IO/WAVPack.cs @@ -16,6 +16,7 @@ class WAVPack : IAudioDataIO private string encoder; + private int bits; private int sampleRate; private double bitrate; private double duration; @@ -133,34 +134,17 @@ public void Reset() // ---------- INFORMATIVE INTERFACE IMPLEMENTATIONS & MANDATORY OVERRIDES - public int SampleRate - { - get { return sampleRate; } - } - public bool IsVBR - { - get { return false; } - } public Format AudioFormat { get; } - public int CodecFamily - { - get { return codecFamily; } - } - public string FileName - { - get { return filePath; } - } - public double BitRate - { - get { return bitrate; } - } - public double Duration - { - get { return duration; } - } + public int SampleRate => sampleRate; + public bool IsVBR => false; + public int CodecFamily => codecFamily; + public string FileName => filePath; + public double BitRate => bitrate; + public int BitDepth => bits; + public double Duration => duration; public ChannelsArrangement ChannelsArrangement { get { return channelsArrangement; } @@ -181,6 +165,7 @@ private void resetData() bitrate = 0; codecFamily = AudioDataIOFactory.CF_LOSSLESS; + bits = -1; sampleRate = 0; encoder = ""; @@ -256,6 +241,7 @@ private bool _ReadV4(BinaryReader source) uint samples = wvh4.total_samples; sampleRate = (int)((wvh4.flags & (0x1F << 23)) >> 23); + bits = (int)((wvh4.flags & 3) * 16); if ((sampleRate > 14) || (sampleRate < 0)) { sampleRate = 44100; @@ -392,6 +378,7 @@ private bool _ReadV3(BinaryReader r) // Encoder guess if (wvh3.bits > 0) { + bits = wvh3.bits + 3; if ((wvh3.flags & NEW_HIGH_FLAG_v3) > 0) { encoder = "hybrid"; diff --git a/ATL/AudioData/IO/WMA.cs b/ATL/AudioData/IO/WMA.cs index c27f8a12..59660bc2 100644 --- a/ATL/AudioData/IO/WMA.cs +++ b/ATL/AudioData/IO/WMA.cs @@ -155,9 +155,10 @@ public int CodecFamily return isLossless ? AudioDataIOFactory.CF_LOSSLESS : AudioDataIOFactory.CF_LOSSY; } } - public string FileName { get { return filePath; } } - public double BitRate { get { return bitrate; } } - public double Duration { get { return duration; } } + public string FileName => filePath; + public double BitRate => bitrate; + public int BitDepth => 16; // Seems to be constant + public double Duration => duration; public ChannelsArrangement ChannelsArrangement { get { return channelsArrangement; } diff --git a/ATL/AudioData/IO/XM.cs b/ATL/AudioData/IO/XM.cs index 8fc51e2d..14b18596 100644 --- a/ATL/AudioData/IO/XM.cs +++ b/ATL/AudioData/IO/XM.cs @@ -78,6 +78,7 @@ public double BitRate { get { return bitrate; } } + public int BitDepth => -1; // Irrelevant for that format public double Duration { get { return duration; } diff --git a/ATL/AudioData/Interfaces/IAudioDataIO.cs b/ATL/AudioData/Interfaces/IAudioDataIO.cs index 94b0bc3c..cf776369 100644 --- a/ATL/AudioData/Interfaces/IAudioDataIO.cs +++ b/ATL/AudioData/Interfaces/IAudioDataIO.cs @@ -37,6 +37,14 @@ int SampleRate { get; } + /// + /// Bit depth (bits per sample) + /// -1 if bit depth is not relevant to that audio format + /// + int BitDepth + { + get; + } /// /// Returns true if the bitrate is variable; false if not /// diff --git a/ATL/Entities/Track.cs b/ATL/Entities/Track.cs index 5d8a52d2..b007dacb 100644 --- a/ATL/Entities/Track.cs +++ b/ATL/Entities/Track.cs @@ -241,6 +241,11 @@ public int? Year /// Bitrate (kilobytes per second) /// public int Bitrate { get; internal set; } + /// + /// Bit depth (bits per sample) + /// -1 if bit depth is not relevant to that audio format + /// + public int BitDepth { get; internal set; } /// /// Sample rate (Hz) /// @@ -407,6 +412,7 @@ protected void Update(bool onlyReadEmbeddedPictures = false) // Physical information Bitrate = fileIO.IntBitRate; + BitDepth = fileIO.BitDepth; CodecFamily = fileIO.CodecFamily; AudioFormat = fileIO.AudioFormat;