diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp b/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp index 671675741..54949e51b 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp @@ -160,3 +160,132 @@ void c_InputFPPRemotePlayFile::CalculatePlayStartTime () // DEBUG_END; } // CalculatePlayStartTime + +//----------------------------------------------------------------------------- +bool c_InputFPPRemotePlayFile::ParseFseqFile () +{ + // DEBUG_START; + bool Response = false; + + do // once + { + FSEQRawHeader fsqRawHeader; + FSEQParsedHeader fsqParsedHeader; + + FileHandleForFileBeingPlayed = 0; + if (false == FileMgr.OpenSdFile (PlayItemName, + c_FileMgr::FileMode::FileRead, + FileHandleForFileBeingPlayed)) + { + logcon (String (F ("ParseFseqFile:: Could not open file: filename: '")) + PlayItemName + "'"); + break; + } + + // DEBUG_V (String ("FileHandleForFileBeingPlayed: ") + String (FileHandleForFileBeingPlayed)); + size_t BytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed, + (uint8_t*)&fsqRawHeader, + sizeof (fsqRawHeader), 0); + // DEBUG_V (String (" BytesRead: ") + String (BytesRead)); + // DEBUG_V (String (" sizeof (fsqRawHeader): ") + String (sizeof (fsqRawHeader))); + + if (BytesRead != sizeof (fsqRawHeader)) + { + logcon (String (F ("ParseFseqFile:: Could not read FSEQ header: filename: '")) + PlayItemName + "'"); + break; + } + + // DEBUG_V ("Convert Raw Header into a processed header"); + memcpy (fsqParsedHeader.header, fsqRawHeader.header, sizeof (fsqParsedHeader.header)); + fsqParsedHeader.dataOffset = read16 (fsqRawHeader.dataOffset); + fsqParsedHeader.minorVersion = fsqRawHeader.minorVersion; + fsqParsedHeader.majorVersion = fsqRawHeader.majorVersion; + fsqParsedHeader.VariableHdrOffset = read16 (fsqRawHeader.VariableHdrOffset); + fsqParsedHeader.channelCount = read32 (fsqRawHeader.channelCount, 0); + fsqParsedHeader.TotalNumberOfFramesInSequence = read32 (fsqRawHeader.TotalNumberOfFramesInSequence, 0); + fsqParsedHeader.stepTime = fsqRawHeader.stepTime; + fsqParsedHeader.flags = fsqRawHeader.flags; + fsqParsedHeader.compressionType = fsqRawHeader.compressionType; + fsqParsedHeader.numCompressedBlocks = fsqRawHeader.numCompressedBlocks; + fsqParsedHeader.numSparseRanges = fsqRawHeader.numSparseRanges; + fsqParsedHeader.flags2 = fsqRawHeader.flags2; + fsqParsedHeader.id = read64 (fsqRawHeader.id, 0); + + // DEBUG_V (String (" dataOffset: ") + String (fsqParsedHeader.dataOffset)); + // DEBUG_V (String (" minorVersion: ") + String (fsqParsedHeader.minorVersion)); + // DEBUG_V (String (" majorVersion: ") + String (fsqParsedHeader.majorVersion)); + // DEBUG_V (String (" VariableHdrOffset: ") + String (fsqParsedHeader.VariableHdrOffset)); + // DEBUG_V (String (" channelCount: ") + String (fsqParsedHeader.channelCount)); + // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (fsqParsedHeader.TotalNumberOfFramesInSequence)); + // DEBUG_V (String (" stepTime: ") + String (fsqParsedHeader.stepTime)); + // DEBUG_V (String (" flags: ") + String (fsqParsedHeader.flags)); + // DEBUG_V (String (" compressionType: 0x") + String (fsqParsedHeader.compressionType, HEX)); + // DEBUG_V (String (" numCompressedBlocks: ") + String (fsqParsedHeader.numCompressedBlocks)); + // DEBUG_V (String (" numSparseRanges: ") + String (fsqParsedHeader.numSparseRanges)); + // DEBUG_V (String (" flags2: ") + String (fsqParsedHeader.flags2)); + // DEBUG_V (String (" id: 0x") + String ((unsigned long)fsqParsedHeader.id, HEX)); + + if (fsqParsedHeader.majorVersion != 2 || fsqParsedHeader.compressionType != 0) + { + logcon (String (F ("ParseFseqFile:: Could not start. ")) + PlayItemName + F (" is not a v2 uncompressed sequence")); + break; + } + // DEBUG_V (""); + + // FrameStepTimeMS = max ((uint8_t)1, fsqParsedHeader.stepTime) * 30; + FrameStepTimeMS = max ((uint8_t)1, fsqParsedHeader.stepTime); + TotalNumberOfFramesInSequence = fsqParsedHeader.TotalNumberOfFramesInSequence; + + DataOffset = fsqParsedHeader.dataOffset; + ChannelsPerFrame = fsqParsedHeader.channelCount; + + memset ((void*)&SparseRanges, 0x00, sizeof (SparseRanges)); + if (fsqParsedHeader.numSparseRanges) + { + if (MAX_NUM_SPARSE_RANGES < fsqParsedHeader.numSparseRanges) + { + logcon (String (F ("ParseFseqFile:: Could not start. ")) + PlayItemName + F (" Too many sparse ranges defined in file header.")); + break; + } + + FSEQRawRangeEntry FseqRawRanges[MAX_NUM_SPARSE_RANGES]; + + FileMgr.ReadSdFile (FileHandleForFileBeingPlayed, + (uint8_t*)&FseqRawRanges[0], + sizeof (FseqRawRanges), + fsqParsedHeader.numCompressedBlocks * 8 + sizeof (FseqRawRanges)); + + uint32_t SparseRangeIndex = 0; + for (auto & CurrentSparseRange : SparseRanges) + { + // DEBUG_V (String (" Sparse Range Index: ") + String (SparseRangeIndex)); + if (SparseRangeIndex >= fsqParsedHeader.numSparseRanges) + { + // DEBUG_V (String ("No Sparse Range Data for this entry ")); + ++SparseRangeIndex; + continue; + } + + CurrentSparseRange.DataOffset = read24 (FseqRawRanges[SparseRangeIndex].Start); + CurrentSparseRange.ChannelCount = read24 (FseqRawRanges[SparseRangeIndex].Length); + + // DEBUG_V (String (" RangeChannelCount: ") + String (CurrentSparseRange.ChannelCount)); + // DEBUG_V (String (" RangeDataOffset: 0x") + String (CurrentSparseRange.DataOffset, HEX)); + + ++SparseRangeIndex; + } + } + else + { + SparseRanges[0].DataOffset = 0; + SparseRanges[0].ChannelCount = fsqParsedHeader.channelCount; + } + + Response = true; + + } while (false); + + // DEBUG_END; + + return Response; + +} // ParseFseqFile diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp b/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp index adeda4510..51d03d003 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp @@ -22,6 +22,7 @@ #include "../ESPixelStick.h" #include "InputFPPRemotePlayItem.hpp" #include "InputFPPRemotePlayFileFsm.hpp" +#include "../service/fseq.h" class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem { @@ -65,8 +66,12 @@ class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem uint32_t SyncCount = 0; uint32_t SyncAdjustmentCount = 0; +#define MAX_NUM_SPARSE_RANGES 5 + FSEQParsedRangeEntry SparseRanges[MAX_NUM_SPARSE_RANGES]; + uint32_t CalculateFrameId (time_t now, int32_t SyncOffsetMS = 0); void CalculatePlayStartTime (); + bool ParseFseqFile (); #define TimeOffsetStep 0.00001 diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp index 8ddc88830..1b6fc0fd8 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp @@ -215,7 +215,7 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize) p_InputFPPRemotePlayFile->LastPlayedFrameId = CurrentFrame; size_t TotalBytesRead = 0; - for (auto & CurrentSparseRange : SparseRanges) + for (auto & CurrentSparseRange : p_InputFPPRemotePlayFile->SparseRanges) { size_t ActualBytesToRead = min (MaxBytesToRead, CurrentSparseRange.ChannelCount); if (0 == ActualBytesToRead) @@ -224,13 +224,16 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize) continue; } + uint32_t AdjustedFilePosition = FilePosition + CurrentSparseRange.DataOffset; + + // DEBUG_V (String (" FilePosition: ") + String (FilePosition)); + // DEBUG_V (String (" AdjustedFilePosition: ") + String (uint32_t(AdjustedFilePosition), HEX)); // DEBUG_V (String (" CurrentDestination: ") + String (uint32_t(CurrentDestination), HEX)); // DEBUG_V (String (" ActualBytesToRead: ") + String (ActualBytesToRead)); - // DEBUG_V (String (" FilePosition: ") + String (FilePosition)); - size_t ActualBytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed, + size_t ActualBytesRead = FileMgr.ReadSdFile (p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed, CurrentDestination, ActualBytesToRead, - FilePosition); + AdjustedFilePosition); MaxBytesToRead -= ActualBytesRead; CurrentDestination += ActualBytesRead; @@ -240,7 +243,7 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize) // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence)); // DEBUG_V (String (" CurrentFrame: ") + String (CurrentFrame)); - if (0 != FileHandleForFileBeingPlayed) + if (0 != p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed) { logcon (F ("File Playback Failed to read enough data")); Stop (); @@ -285,100 +288,16 @@ void fsm_PlayFile_state_PlayingFile::Init (c_InputFPPRemotePlayFile* Parent) --p_InputFPPRemotePlayFile->RemainingPlayCount; // DEBUG_V (String ("RemainingPlayCount: ") + p_InputFPPRemotePlayFile->RemainingPlayCount); - FSEQHeader fsqHeader; - FileHandleForFileBeingPlayed = 0; - if (false == FileMgr.OpenSdFile (p_InputFPPRemotePlayFile->PlayItemName, - c_FileMgr::FileMode::FileRead, - FileHandleForFileBeingPlayed)) - { - logcon (String (F ("StartPlaying:: Could not open file: filename: '")) + p_InputFPPRemotePlayFile->PlayItemName + "'"); - Stop (); - break; - } - - // DEBUG_V (String ("FileHandleForFileBeingPlayed: ") + String (FileHandleForFileBeingPlayed)); - p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed = FileHandleForFileBeingPlayed; - size_t BytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed, - (uint8_t*)&fsqHeader, - sizeof (FSEQHeader), 0); - // DEBUG_V (String ("BytesRead: ") + String (BytesRead)); - // DEBUG_V (String ("sizeof (fsqHeader): ") + String (sizeof (fsqHeader))); - - if (BytesRead != sizeof (fsqHeader)) + if (!p_InputFPPRemotePlayFile->ParseFseqFile ()) { - logcon (String (F ("StartPlaying:: Could not read FSEQ header: filename: '")) + p_InputFPPRemotePlayFile->PlayItemName + "'"); Stop (); break; } - // DEBUG_V (""); - - if (fsqHeader.majorVersion != 2 || fsqHeader.compressionType != 0) - { - logcon (String (F ("StartPlaying:: Could not start. ")) + p_InputFPPRemotePlayFile->PlayItemName + F (" is not a v2 uncompressed sequence")); - Stop (); - break; - } - // DEBUG_V (""); p_InputFPPRemotePlayFile->LastPlayedFrameId = 0; - p_InputFPPRemotePlayFile->DataOffset = fsqHeader.dataOffset; - p_InputFPPRemotePlayFile->ChannelsPerFrame = fsqHeader.channelCount; - p_InputFPPRemotePlayFile->FrameStepTimeMS = max ((uint8_t)1, fsqHeader.stepTime); - p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence = fsqHeader.TotalNumberOfFramesInSequence; p_InputFPPRemotePlayFile->CalculatePlayStartTime (); - memset ((void*)&SparseRanges, 0x00, sizeof (SparseRanges)); - if (fsqHeader.numSparseRanges) - { - if (MAX_NUM_SPARSE_RANGES < fsqHeader.numSparseRanges) - { - logcon (String (F ("StartPlaying:: Could not start. ")) + p_InputFPPRemotePlayFile->PlayItemName + F (" Too many sparse ranges defined.")); - Stop (); - break; - } - - FSEQRangeEntry FseqRanges[MAX_NUM_SPARSE_RANGES]; - - // DEBUG_V (String (" numCompressedBlocks: ") + String (fsqHeader.numCompressedBlocks)); - - FileMgr.ReadSdFile (FileHandleForFileBeingPlayed, - (uint8_t*)&FseqRanges[0], - sizeof (FseqRanges), - fsqHeader.numCompressedBlocks * 8 + sizeof(fsqHeader)); - - // DEBUG_V (String (" numSparseRanges: ") + String (fsqHeader.numSparseRanges)); - uint32_t SparseRangeIndex = 0; - for (auto& CurrentSparseRange : SparseRanges) - { - // DEBUG_V (String (" Sparse Range Index: ") + String (SparseRangeIndex)); - if (SparseRangeIndex >= fsqHeader.numSparseRanges) - { - // DEBUG_V (String ("No Sparse Range Data for this entry ")); - ++SparseRangeIndex; - continue; - } - - CurrentSparseRange.DataOffset = read24 (FseqRanges[SparseRangeIndex].Start); - CurrentSparseRange.ChannelCount = read24 (FseqRanges[SparseRangeIndex].Length); - - // DEBUG_V (String (" ChannelCount: ") + String (CurrentSparseRange.ChannelCount)); - // DEBUG_V (String (" DataOffset: 0x") + String (CurrentSparseRange.DataOffset, HEX)); - - ++SparseRangeIndex; - } - } - else - { - SparseRanges[0].DataOffset = 0; - SparseRanges[0].ChannelCount = fsqHeader.channelCount; - } - // DEBUG_V (String (" LastPlayedFrameId: ") + String (p_InputFPPRemotePlayFile->LastPlayedFrameId)); - // DEBUG_V (String (" numCompressedBlocks: ") + String (fsqHeader.numCompressedBlocks)); - // DEBUG_V (String (" DataOffset: ") + String (p_InputFPPRemotePlayFile->DataOffset)); - // DEBUG_V (String (" Total ChannelsPerFrame: ") + String (p_InputFPPRemotePlayFile->ChannelsPerFrame)); - // DEBUG_V (String (" FrameStepTimeMS: ") + String (p_InputFPPRemotePlayFile->FrameStepTimeMS)); - // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence)); // DEBUG_V (String (" StartTimeMS: ") + String (p_InputFPPRemotePlayFile->StartTimeMS)); // DEBUG_V (String (" RemainingPlayCount: ") + p_InputFPPRemotePlayFile->RemainingPlayCount); diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.hpp b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.hpp index c3565b8f7..1213ee8c8 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.hpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.hpp @@ -89,11 +89,6 @@ class fsm_PlayFile_state_PlayingFile : public fsm_PlayFile_state uint32_t ChannelCount; }; -#define MAX_NUM_SPARSE_RANGES 5 - SparseRange SparseRanges[MAX_NUM_SPARSE_RANGES]; - c_FileMgr::FileId FileHandleForFileBeingPlayed = 0; - - }; // fsm_PlayFile_state_PlayingFile /*****************************************************************************/ diff --git a/ESPixelStick/src/service/FPPDiscovery.cpp b/ESPixelStick/src/service/FPPDiscovery.cpp index f6cfd0254..9577c38f2 100644 --- a/ESPixelStick/src/service/FPPDiscovery.cpp +++ b/ESPixelStick/src/service/FPPDiscovery.cpp @@ -406,17 +406,17 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St DynamicJsonDocument JsonDoc (4*1024); JsonObject JsonData = JsonDoc.to (); - FSEQHeader fsqHeader; + FSEQRawHeader fsqHeader; FileMgr.ReadSdFile (fseq, (byte*)&fsqHeader, sizeof (fsqHeader), 0); JsonData[F ("Name")] = fname; JsonData[CN_Version] = String (fsqHeader.majorVersion) + "." + String (fsqHeader.minorVersion); - JsonData[F ("ID")] = int64String (fsqHeader.id); + JsonData[F ("ID")] = int64String (read64 (fsqHeader.id, 0)); JsonData[F ("StepTime")] = String (fsqHeader.stepTime); - JsonData[F ("NumFrames")] = String (fsqHeader.TotalNumberOfFramesInSequence); + JsonData[F ("NumFrames")] = String (read32 (fsqHeader.TotalNumberOfFramesInSequence, 0)); JsonData[F ("CompressionType")] = fsqHeader.compressionType; - uint32_t maxChannel = fsqHeader.channelCount; + uint32_t maxChannel = read32 (fsqHeader.channelCount, 0); if (0 != fsqHeader.numSparseRanges) { @@ -424,10 +424,10 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St maxChannel = 0; - uint8_t* RangeDataBuffer = (uint8_t*)malloc (6 * fsqHeader.numSparseRanges); - FSEQRangeEntry* CurrentFSEQRangeEntry = (FSEQRangeEntry*)RangeDataBuffer; + uint8_t* RangeDataBuffer = (uint8_t*)malloc (sizeof(FSEQRawRangeEntry) * fsqHeader.numSparseRanges); + FSEQRawRangeEntry* CurrentFSEQRangeEntry = (FSEQRawRangeEntry*)RangeDataBuffer; - FileMgr.ReadSdFile (fseq, RangeDataBuffer, sizeof (FSEQRangeEntry), fsqHeader.numCompressedBlocks * 8 + 32); + FileMgr.ReadSdFile (fseq, RangeDataBuffer, sizeof (FSEQRawRangeEntry), fsqHeader.numCompressedBlocks * 8 + 32); for (int CurrentRangeIndex = 0; CurrentRangeIndex < fsqHeader.numSparseRanges; @@ -450,10 +450,10 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St } JsonData[F ("MaxChannel")] = String (maxChannel); - JsonData[F ("ChannelCount")] = String (fsqHeader.channelCount); + JsonData[F ("ChannelCount")] = String (read32 (fsqHeader.channelCount,0)); - uint32_t FileOffsetToCurrentHeaderRecord = read16 ((uint8_t*)&fsqHeader.headerLen); - uint32_t FileOffsetToStartOfSequenceData = read16 ((uint8_t*)&fsqHeader.dataOffset); // DataOffset + uint32_t FileOffsetToCurrentHeaderRecord = read16 (fsqHeader.VariableHdrOffset); + uint32_t FileOffsetToStartOfSequenceData = read16 (fsqHeader.dataOffset); // DataOffset // DEBUG_V (String ("FileOffsetToCurrentHeaderRecord: ") + String (FileOffsetToCurrentHeaderRecord)); // DEBUG_V (String ("FileOffsetToStartOfSequenceData: ") + String (FileOffsetToStartOfSequenceData)); @@ -462,16 +462,16 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St { JsonArray JsonDataHeaders = JsonData.createNestedArray (F ("variableHeaders")); - char FSEQVariableDataHeaderBuffer[sizeof (FSEQVariableDataHeader) + 1]; + char FSEQVariableDataHeaderBuffer[sizeof (FSEQRawVariableDataHeader) + 1]; memset ((uint8_t*)FSEQVariableDataHeaderBuffer, 0x00, sizeof (FSEQVariableDataHeaderBuffer)); - FSEQVariableDataHeader* pCurrentVariableHeader = (FSEQVariableDataHeader*)FSEQVariableDataHeaderBuffer; + FSEQRawVariableDataHeader* pCurrentVariableHeader = (FSEQRawVariableDataHeader*)FSEQVariableDataHeaderBuffer; while (FileOffsetToCurrentHeaderRecord < FileOffsetToStartOfSequenceData) { - FileMgr.ReadSdFile (fseq, (byte*)FSEQVariableDataHeaderBuffer, sizeof (FSEQVariableDataHeader), FileOffsetToCurrentHeaderRecord); + FileMgr.ReadSdFile (fseq, (byte*)FSEQVariableDataHeaderBuffer, sizeof (FSEQRawVariableDataHeader), FileOffsetToCurrentHeaderRecord); int VariableDataHeaderTotalLength = read16 ((uint8_t*)&(pCurrentVariableHeader->length)); - int VariableDataHeaderDataLength = VariableDataHeaderTotalLength - sizeof (FSEQVariableDataHeader); + int VariableDataHeaderDataLength = VariableDataHeaderTotalLength - sizeof (FSEQRawVariableDataHeader); String HeaderTypeCode (pCurrentVariableHeader->type); @@ -488,7 +488,7 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St free (VariableDataHeaderDataBuffer); } - FileOffsetToCurrentHeaderRecord += VariableDataHeaderTotalLength + sizeof (FSEQVariableDataHeader); + FileOffsetToCurrentHeaderRecord += VariableDataHeaderTotalLength + sizeof (FSEQRawVariableDataHeader); } // while there are headers to process } // there are headers to process diff --git a/ESPixelStick/src/service/fseq.h b/ESPixelStick/src/service/fseq.h index 1227ba765..003720b11 100644 --- a/ESPixelStick/src/service/fseq.h +++ b/ESPixelStick/src/service/fseq.h @@ -66,29 +66,59 @@ typedef union uint8_t raw[301]; } FPPMultiSyncPacket; -struct FSEQVariableDataHeader +// https://github.com/FalconChristmas/fpp/blob/master/docs/FSEQ_Sequence_File_Format.txt +struct FSEQRawVariableDataHeader +{ + uint8_t length[2]; + char type[2]; + uint8_t data; +}; + +struct FSEQParsedVariableDataHeader { uint16_t length; char type[2]; -// uint8_t data[???]; + String Data; +}; -} __attribute__ ((packed)); - -struct FSEQRangeEntry +struct FSEQRawRangeEntry { uint8_t Start[3]; uint8_t Length[3]; } __attribute__ ((packed)); -// https://github.com/FalconChristmas/fpp/blob/master/docs/FSEQ_Sequence_File_Format.txt -struct FSEQHeader +struct FSEQParsedRangeEntry +{ + uint32_t DataOffset; + uint32_t ChannelCount; +}; + +struct FSEQRawHeader +{ + uint8_t header[4]; // PSEQ + uint8_t dataOffset[2]; + uint8_t minorVersion; + uint8_t majorVersion; + uint8_t VariableHdrOffset[2]; + uint8_t channelCount[4]; + uint8_t TotalNumberOfFramesInSequence[4]; + uint8_t stepTime; + uint8_t flags; + uint8_t compressionType; + uint8_t numCompressedBlocks; + uint8_t numSparseRanges; + uint8_t flags2; + uint8_t id[8]; +} __attribute__ ((packed)); + +struct FSEQParsedHeader { uint8_t header[4]; // PSEQ uint16_t dataOffset; uint8_t minorVersion; uint8_t majorVersion; - uint16_t headerLen; + uint16_t VariableHdrOffset; uint32_t channelCount; uint32_t TotalNumberOfFramesInSequence; uint8_t stepTime; @@ -98,8 +128,7 @@ struct FSEQHeader uint8_t numSparseRanges; uint8_t flags2; uint64_t id; -} __attribute__ ((packed)); - +}; inline uint64_t read64 (uint8_t* buf, int idx) { uint32_t r1 = (int)(buf[idx + 3]) << 24;