mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-23 18:52:28 -04:00
FileRecord improvement: fixed header packing and CRC32 computation
This commit is contained in:
parent
cc49d5c266
commit
38aa1a8e77
@ -86,24 +86,25 @@ void FileSourceInput::openFileStream()
|
|||||||
if (fileSize > sizeof(FileRecord::Header))
|
if (fileSize > sizeof(FileRecord::Header))
|
||||||
{
|
{
|
||||||
// TODO: add CRC
|
// TODO: add CRC
|
||||||
m_ifstream.seekg(0,std::ios_base::beg);
|
|
||||||
FileRecord::Header header;
|
FileRecord::Header header;
|
||||||
|
m_ifstream.seekg(0,std::ios_base::beg);
|
||||||
|
bool crcOK = FileRecord::readHeader(m_ifstream, header);
|
||||||
|
m_sampleRate = header.sampleRate;
|
||||||
|
m_centerFrequency = header.centerFrequency;
|
||||||
|
m_startingTimeStamp = header.startTimeStamp;
|
||||||
|
m_sampleSize = header.sampleSize;
|
||||||
|
QString crcHex = QString("%1").arg(header.crc32 , 0, 16);
|
||||||
|
|
||||||
if (FileRecord::readHeader(m_ifstream, header)) // CRC OK
|
if (crcOK)
|
||||||
{
|
{
|
||||||
m_sampleRate = header.sampleRate;
|
qDebug("FileSourceInput::openFileStream: CRC32 OK for header: %s", qPrintable(crcHex));
|
||||||
m_centerFrequency = header.centerFrequency;
|
|
||||||
m_startingTimeStamp = header.startTimeStamp;
|
|
||||||
m_sampleSize = header.sampleSize;
|
|
||||||
|
|
||||||
m_recordLength = (fileSize - sizeof(FileRecord::Header)) / ((m_sampleSize == 24 ? 8 : 4) * m_sampleRate);
|
m_recordLength = (fileSize - sizeof(FileRecord::Header)) / ((m_sampleSize == 24 ? 8 : 4) * m_sampleRate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qCritical("FileSourceInput::openFileStream: bad CRC header");
|
qCritical("FileSourceInput::openFileStream: bad CRC32 for header: %s", qPrintable(crcHex));
|
||||||
m_recordLength = 0;
|
m_recordLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -111,8 +112,11 @@ void FileSourceInput::openFileStream()
|
|||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "FileSourceInput::openFileStream: " << m_fileName.toStdString().c_str()
|
qDebug() << "FileSourceInput::openFileStream: " << m_fileName.toStdString().c_str()
|
||||||
<< " fileSize: " << fileSize << "bytes"
|
<< " fileSize: " << fileSize << " bytes"
|
||||||
<< " length: " << m_recordLength << " seconds";
|
<< " length: " << m_recordLength << " seconds"
|
||||||
|
<< " sample rate: " << m_sampleRate << " S/s"
|
||||||
|
<< " center frequency: " << m_centerFrequency << " Hz"
|
||||||
|
<< " sample size: " << m_sampleSize << " bits";
|
||||||
|
|
||||||
if (getMessageQueueToGUI()) {
|
if (getMessageQueueToGUI()) {
|
||||||
MsgReportFileSourceStreamData *report = MsgReportFileSourceStreamData::create(m_sampleRate,
|
MsgReportFileSourceStreamData *report = MsgReportFileSourceStreamData::create(m_sampleRate,
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type HeaderStd struct {
|
type HeaderStd struct {
|
||||||
SampleRate uint32
|
SampleRate uint32
|
||||||
CenterFrequency uint64
|
CenterFrequency uint64
|
||||||
@ -22,7 +22,7 @@ type HeaderStd struct {
|
|||||||
CRC32 uint32
|
CRC32 uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func check(e error) {
|
func check(e error) {
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
@ -38,12 +38,12 @@ func analyze(r *bufio.Reader) HeaderStd {
|
|||||||
if (n != 32) {
|
if (n != 32) {
|
||||||
panic("Header too small")
|
panic("Header too small")
|
||||||
}
|
}
|
||||||
|
|
||||||
var header HeaderStd
|
var header HeaderStd
|
||||||
headerr := bytes.NewReader(headerbuf)
|
headerr := bytes.NewReader(headerbuf)
|
||||||
err = binary.Read(headerr, binary.LittleEndian, &header)
|
err = binary.Read(headerr, binary.LittleEndian, &header)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,14 +55,6 @@ func writeHeader(writer *bufio.Writer, header *HeaderStd) {
|
|||||||
fmt.Printf("Wrote %d bytes header\n", noh)
|
fmt.Printf("Wrote %d bytes header\n", noh)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printHeader(header *HeaderStd) {
|
|
||||||
fmt.Println("Sample rate:", header.SampleRate)
|
|
||||||
fmt.Println("Frequency :", header.CenterFrequency)
|
|
||||||
fmt.Println("Sample Size:", header.SampleSize)
|
|
||||||
tm := time.Unix(header.StartTimestamp, 0)
|
|
||||||
fmt.Println("Start :", tm)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setCRC(header *HeaderStd) {
|
func setCRC(header *HeaderStd) {
|
||||||
var bin_buf bytes.Buffer
|
var bin_buf bytes.Buffer
|
||||||
header.Filler = 0
|
header.Filler = 0
|
||||||
@ -70,13 +62,30 @@ func setCRC(header *HeaderStd) {
|
|||||||
header.CRC32 = crc32.ChecksumIEEE(bin_buf.Bytes()[0:28])
|
header.CRC32 = crc32.ChecksumIEEE(bin_buf.Bytes()[0:28])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCRC(header *HeaderStd) uint32 {
|
||||||
|
var bin_buf bytes.Buffer
|
||||||
|
header.Filler = 0
|
||||||
|
binary.Write(&bin_buf, binary.LittleEndian, header)
|
||||||
|
return crc32.ChecksumIEEE(bin_buf.Bytes()[0:28])
|
||||||
|
}
|
||||||
|
|
||||||
|
func printHeader(header *HeaderStd) {
|
||||||
|
fmt.Println("Sample rate:", header.SampleRate)
|
||||||
|
fmt.Println("Frequency :", header.CenterFrequency)
|
||||||
|
fmt.Println("Sample Size:", header.SampleSize)
|
||||||
|
tm := time.Unix(header.StartTimestamp, 0)
|
||||||
|
fmt.Println("Start :", tm)
|
||||||
|
fmt.Println("CRC32 :", header.CRC32)
|
||||||
|
fmt.Println("CRC32 OK :", getCRC(header))
|
||||||
|
}
|
||||||
|
|
||||||
func copyContent(reader *bufio.Reader, writer *bufio.Writer, blockSize uint) {
|
func copyContent(reader *bufio.Reader, writer *bufio.Writer, blockSize uint) {
|
||||||
p := make([]byte, blockSize*4096) // buffer in 4k multiples
|
p := make([]byte, blockSize*4096) // buffer in 4k multiples
|
||||||
var sz int64 = 0
|
var sz int64 = 0
|
||||||
|
|
||||||
for {
|
for {
|
||||||
n, err := reader.Read(p)
|
n, err := reader.Read(p)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
writer.Write(p[0:n])
|
writer.Write(p[0:n])
|
||||||
@ -90,10 +99,10 @@ func copyContent(reader *bufio.Reader, writer *bufio.Writer, blockSize uint) {
|
|||||||
writer.Write(p)
|
writer.Write(p)
|
||||||
sz += int64(blockSize)*4096
|
sz += int64(blockSize)*4096
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Wrote %d bytes\r", sz)
|
fmt.Printf("Wrote %d bytes\r", sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Wrote %d bytes\r", sz)
|
fmt.Printf("Wrote %d bytes\r", sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,27 +115,27 @@ func main() {
|
|||||||
timeStr := flag.String("ts", "", "start time RFC3339 (ex: 2006-01-02T15:04:05Z)")
|
timeStr := flag.String("ts", "", "start time RFC3339 (ex: 2006-01-02T15:04:05Z)")
|
||||||
timeNow := flag.Bool("now", false , "use now for start time")
|
timeNow := flag.Bool("now", false , "use now for start time")
|
||||||
blockSize := flag.Uint("bz", 1, "Copy block size in multiple of 4k")
|
blockSize := flag.Uint("bz", 1, "Copy block size in multiple of 4k")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
flagSeen := make(map[string]bool)
|
flagSeen := make(map[string]bool)
|
||||||
flag.Visit(func(f *flag.Flag) { flagSeen[f.Name] = true })
|
flag.Visit(func(f *flag.Flag) { flagSeen[f.Name] = true })
|
||||||
|
|
||||||
if flagSeen["in"] {
|
if flagSeen["in"] {
|
||||||
fmt.Println("input file :", *inFileStr)
|
fmt.Println("input file :", *inFileStr)
|
||||||
|
|
||||||
// open input file
|
// open input file
|
||||||
fi, err := os.Open(*inFileStr)
|
fi, err := os.Open(*inFileStr)
|
||||||
check(err)
|
check(err)
|
||||||
// close fi on exit and check for its returned error
|
// close fi on exit and check for its returned error
|
||||||
defer func() {
|
defer func() {
|
||||||
err := fi.Close();
|
err := fi.Close();
|
||||||
check(err)
|
check(err)
|
||||||
}()
|
}()
|
||||||
// make a read buffer
|
// make a read buffer
|
||||||
reader := bufio.NewReader(fi)
|
reader := bufio.NewReader(fi)
|
||||||
var headerOrigin HeaderStd = analyze(reader)
|
var headerOrigin HeaderStd = analyze(reader)
|
||||||
printHeader(&headerOrigin)
|
printHeader(&headerOrigin)
|
||||||
|
|
||||||
if flagSeen["out"] {
|
if flagSeen["out"] {
|
||||||
if flagSeen["sr"] {
|
if flagSeen["sr"] {
|
||||||
headerOrigin.SampleRate = uint32(*sampleRate)
|
headerOrigin.SampleRate = uint32(*sampleRate)
|
||||||
@ -134,7 +143,7 @@ func main() {
|
|||||||
headerOrigin.CenterFrequency = *centerFreq
|
headerOrigin.CenterFrequency = *centerFreq
|
||||||
} else if flagSeen["sz"] {
|
} else if flagSeen["sz"] {
|
||||||
if (*sampleSize == 16) || (*sampleSize == 24) {
|
if (*sampleSize == 16) || (*sampleSize == 24) {
|
||||||
headerOrigin.SampleSize = uint32(*sampleSize)
|
headerOrigin.SampleSize = uint32(*sampleSize)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Incorrect sample size specified. Defaulting to 16")
|
fmt.Println("Incorrect sample size specified. Defaulting to 16")
|
||||||
headerOrigin.SampleSize = 16
|
headerOrigin.SampleSize = 16
|
||||||
@ -150,30 +159,30 @@ func main() {
|
|||||||
} else if *timeNow {
|
} else if *timeNow {
|
||||||
headerOrigin.StartTimestamp = int64(time.Now().Unix())
|
headerOrigin.StartTimestamp = int64(time.Now().Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("\nHeader is now")
|
fmt.Println("\nHeader is now")
|
||||||
printHeader(&headerOrigin)
|
printHeader(&headerOrigin)
|
||||||
setCRC(&headerOrigin)
|
setCRC(&headerOrigin)
|
||||||
fmt.Println("CRC32 :", headerOrigin.CRC32)
|
fmt.Println("CRC32 :", headerOrigin.CRC32)
|
||||||
fmt.Println("Output file:", *outFileStr)
|
fmt.Println("Output file:", *outFileStr)
|
||||||
|
|
||||||
fo, err := os.Create(*outFileStr)
|
fo, err := os.Create(*outFileStr)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
err := fo.Close();
|
err := fo.Close();
|
||||||
check(err)
|
check(err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
writer := bufio.NewWriter(fo)
|
writer := bufio.NewWriter(fo)
|
||||||
|
|
||||||
writeHeader(writer, &headerOrigin)
|
writeHeader(writer, &headerOrigin)
|
||||||
copyContent(reader, writer, *blockSize)
|
copyContent(reader, writer, *blockSize)
|
||||||
|
|
||||||
fmt.Println("\nCopy done")
|
fmt.Println("\nCopy done")
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("No input file given")
|
fmt.Println("No input file given")
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,17 @@ class Message;
|
|||||||
class SDRBASE_API FileRecord : public BasebandSampleSink {
|
class SDRBASE_API FileRecord : public BasebandSampleSink {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
quint32 sampleRate;
|
quint32 sampleRate;
|
||||||
quint64 centerFrequency;
|
quint64 centerFrequency;
|
||||||
quint64 startTimeStamp;
|
quint64 startTimeStamp;
|
||||||
quint32 sampleSize;
|
quint32 sampleSize;
|
||||||
quint32 filler;
|
quint32 filler;
|
||||||
quint32 crc32;
|
quint32 crc32;
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
FileRecord();
|
FileRecord();
|
||||||
FileRecord(const QString& filename);
|
FileRecord(const QString& filename);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user