/* Copyright (c) MediaArea.net SARL. All Rights Reserved. * * Use of this source code is governed by a BSD-style license that can * be found in the License.html file in the root of the source tree. */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Information about Tak files // // Contributor: Lionel Duchateau, kurtnoise@free.fr // // Specifications : http://linuxstb.cream.org/tak_format.html // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //--------------------------------------------------------------------------- // Pre-compilation #include "MediaInfo/PreComp.h" #ifdef __BORLANDC__ #pragma hdrstop #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Setup.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_TAK_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Audio/File_Tak.h" #if defined(MEDIAINFO_RIFF_YES) #include "MediaInfo/Multiple/File_Riff.h" #endif //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Const //*************************************************************************** namespace Elements { const int16u ENDOFMETADATA =0x00; const int16u STREAMINFO =0x01; const int16u SEEKTABLE =0x02; const int16u WAVEMETADATA =0x03; const int16u ENCODERINFO =0x04; const int16u PADDING =0x05; } //*************************************************************************** // Const //*************************************************************************** int8u Tak_samplesize[]= { 8, 16, 24, 0, }; //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Tak::File_Tak() :File__Analyze(), File__Tags_Helper() { //File__Tags_Helper Base=this; } //*************************************************************************** // Buffer - File header //*************************************************************************** //--------------------------------------------------------------------------- bool File_Tak::FileHeader_Begin() { if (!File__Tags_Helper::FileHeader_Begin()) return false; //Synchro if (Buffer_Offset+4>Buffer_Size) return false; if (CC4(Buffer+Buffer_Offset)!=0x7442614B) //"tBaK" { File__Tags_Helper::Reject("TAK"); return false; } return true; } //*************************************************************************** // Buffer - File header //*************************************************************************** //--------------------------------------------------------------------------- void File_Tak::FileHeader_Parse() { Skip_C4( "Signature"); } //*************************************************************************** // Buffer - Per element //*************************************************************************** //--------------------------------------------------------------------------- void File_Tak::Header_Parse() { //Parsing int32u block_length; int8u block_type; Get_L1 (block_type, "Block Type"); Get_L3 (block_length, "Block Length"); //Filling Header_Fill_Code(block_type, Ztring().From_CC1(block_type)); Header_Fill_Size(Element_Offset+block_length); } //--------------------------------------------------------------------------- void File_Tak::Data_Parse() { #define CASE_INFO(_NAME) \ case Elements::_NAME : Element_Info1(#_NAME); _NAME(); break; //Parsing switch (Element_Code) { CASE_INFO(ENDOFMETADATA); CASE_INFO(STREAMINFO); CASE_INFO(SEEKTABLE); CASE_INFO(WAVEMETADATA); CASE_INFO(ENCODERINFO); CASE_INFO(PADDING); default : Skip_XX(Element_Size, "Data"); } Element_Offset=Element_Size; } //*************************************************************************** // Elements //*************************************************************************** //--------------------------------------------------------------------------- void File_Tak::ENDOFMETADATA() { //Filling Fill(Stream_General, 0, General_StreamSize, 0); //File_Offset+Buffer_Offset+Element_Size); Fill(Stream_Audio, 0, Audio_StreamSize, File_Size-(File_Offset+Buffer_Offset+Element_Size)); File__Tags_Helper::Finish("TAK"); } //--------------------------------------------------------------------------- void File_Tak::STREAMINFO() { //Parsing int32u num_samples_hi, samplerate; int8u num_samples_lo, framesizecode, samplesize; bool channels; Skip_L1 ( "unknown"); BS_Begin(); Get_S1 ( 2, num_samples_lo, "num_samples (lo)"); Get_S1 ( 3, framesizecode, "framesizecode"); Skip_S1( 2, "unknown"); BS_End(); Get_L4 (num_samples_hi, "num_samples (hi)"); Param_Info2((((int64u)num_samples_hi)<<2 | num_samples_lo), " samples"); Get_L3 (samplerate, "samplerate"); Param_Info2((samplerate/16)+6000, " Hz"); BS_Begin(); Skip_S1( 4, "unknown"); Get_SB ( channels, "channels"); Param_Info1(channels?"Stereo":"Mono"); Get_S1 ( 2, samplesize, "samplesize"); Param_Info1(Tak_samplesize[samplesize]); Skip_SB( "unknown"); BS_End(); Skip_L3( "crc"); FILLING_BEGIN(); //Coherency if (samplerate==0) return; //Computing int64u Samples=((int64u)num_samples_hi)<<2 | num_samples_lo; int32u SamplingRate=(samplerate/16)+6000; //Filling File__Tags_Helper::Accept("TAK"); File__Tags_Helper::Stream_Prepare(Stream_Audio); Fill(Stream_Audio, 0, Audio_Format, "TAK"); Fill(Stream_Audio, 0, Audio_Codec, "TAK"); Fill(Stream_Audio, 0, Audio_SamplingRate, SamplingRate); Fill(Stream_Audio, 0, Audio_Channel_s_, channels?2:1); if (Tak_samplesize[samplesize]) Fill(Stream_Audio, 0, Audio_BitDepth, Tak_samplesize[samplesize]); Fill(Stream_Audio, 0, Audio_Duration, Samples*1000/SamplingRate); FILLING_END(); } //--------------------------------------------------------------------------- void File_Tak::SEEKTABLE() { //Parsing int16u num_seekpoints; Get_L2 (num_seekpoints, "num_seekpoints"); Skip_L1 ( "unknown"); Skip_L1 ( "seek interval"); Element_Begin1("seekpoints"); for (int16u Pos=0; Pos