mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			739 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			739 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////////
 | |
| // Copyright (C) 2020, 2023 Edouard Griffiths, F4EXB <f4exb06@gmail.com>         //
 | |
| //                                                                               //
 | |
| // This program is free software; you can redistribute it and/or modify          //
 | |
| // it under the terms of the GNU General Public License as published by          //
 | |
| // the Free Software Foundation as version 3 of the License, or                  //
 | |
| // (at your option) any later version.                                           //
 | |
| //                                                                               //
 | |
| // This program is distributed in the hope that it will be useful,               //
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | |
| // GNU General Public License V3 for more details.                               //
 | |
| //                                                                               //
 | |
| // You should have received a copy of the GNU General Public License             //
 | |
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | |
| ///////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <errno.h>
 | |
| #include <QDebug>
 | |
| 
 | |
| #include "dsp/samplesinkfifo.h"
 | |
| #include "util/messagequeue.h"
 | |
| 
 | |
| #include "sigmffiledata.h"
 | |
| #include "sigmffileconvert.h"
 | |
| #include "sigmffileinputsettings.h"
 | |
| #include "sigmffileinputworker.h"
 | |
| 
 | |
| MESSAGE_CLASS_DEFINITION(SigMFFileInputWorker::MsgReportEOF, Message)
 | |
| MESSAGE_CLASS_DEFINITION(SigMFFileInputWorker::MsgReportTrackChange, Message)
 | |
| 
 | |
| SigMFFileInputWorker::SigMFFileInputWorker(std::ifstream *samplesStream,
 | |
|         SampleSinkFifo* sampleFifo,
 | |
|         const QTimer& timer,
 | |
|         MessageQueue *fileInputMessageQueue,
 | |
|         QObject* parent) :
 | |
| 	QObject(parent),
 | |
| 	m_running(false),
 | |
|     m_currentTrackIndex(0),
 | |
| 	m_ifstream(samplesStream),
 | |
| 	m_fileBuf(0),
 | |
| 	m_convertBuf(0),
 | |
| 	m_bufsize(0),
 | |
| 	m_chunksize(0),
 | |
| 	m_sampleFifo(sampleFifo),
 | |
| 	m_samplesCount(0),
 | |
| 	m_timer(timer),
 | |
| 	m_fileInputMessageQueue(fileInputMessageQueue),
 | |
|     m_samplerate(48000),
 | |
|     m_accelerationFactor(1),
 | |
| 	m_samplesize(16),
 | |
| 	m_samplebytes(2),
 | |
|     m_throttlems(FILESOURCE_THROTTLE_MS),
 | |
|     m_throttleToggle(false),
 | |
|     m_sigMFConverter(nullptr)
 | |
| {
 | |
| }
 | |
| 
 | |
| SigMFFileInputWorker::~SigMFFileInputWorker()
 | |
| {
 | |
| 	if (m_running) {
 | |
| 		stopWork();
 | |
| 	}
 | |
| 
 | |
| 	if (m_fileBuf != 0) {
 | |
| 		free(m_fileBuf);
 | |
| 	}
 | |
| 
 | |
| 	if (m_convertBuf != 0) {
 | |
| 		free(m_convertBuf);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::startWork()
 | |
| {
 | |
| 	qDebug() << "SigMFFileInputWorker::startWork: ";
 | |
| 
 | |
|     if (m_ifstream->is_open())
 | |
|     {
 | |
|         qDebug() << "SigMFFileInputWorker::startWork: file stream open, starting...";
 | |
|         m_elapsedTimer.start();
 | |
|         connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
 | |
|         m_running = true;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         qDebug() << "SigMFFileInputWorker::startWork: file stream closed, not starting.";
 | |
|     }
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::stopWork()
 | |
| {
 | |
| 	qDebug() << "SigMFFileInputWorker::stopWork";
 | |
| 	disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
 | |
| 	m_running = false;
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::setMetaInformation(const SigMFFileMetaInfo *metaInfo, const QList<SigMFFileCapture> *captures)
 | |
| {
 | |
|     m_metaInfo = metaInfo;
 | |
|     m_captures = captures;
 | |
|     m_samplerate = m_metaInfo->m_coreSampleRate;
 | |
|     m_samplesize = m_metaInfo->m_dataType.m_sampleBits;
 | |
|     setConverter();
 | |
|     setSampleRate();
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::setTrackIndex(int trackIndex)
 | |
| {
 | |
|     m_currentTrackIndex = trackIndex;
 | |
|     m_samplesCount = m_captures->at(m_currentTrackIndex).m_sampleStart;
 | |
|     int sampleRate = m_captures->at(m_currentTrackIndex).m_sampleRate;
 | |
| 
 | |
|     if (sampleRate != m_samplerate)
 | |
|     {
 | |
|         m_samplerate = sampleRate;
 | |
|         setSampleRate();
 | |
|     }
 | |
| 
 | |
|     MsgReportTrackChange *message = MsgReportTrackChange::create(m_currentTrackIndex);
 | |
|     m_fileInputMessageQueue->push(message);
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::setAccelerationFactor(int accelerationFactor)
 | |
| {
 | |
|     m_accelerationFactor = accelerationFactor;
 | |
|     setSampleRate();
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::setSampleRate()
 | |
| {
 | |
|     bool running = m_running;
 | |
| 
 | |
|     if (running) {
 | |
|         stopWork();
 | |
|     }
 | |
| 
 | |
|     m_samplebytes = SigMFFileInputSettings::bitsToBytes(m_samplesize);
 | |
|     m_chunksize = (m_accelerationFactor * m_samplerate * 2 * m_samplebytes * m_throttlems) / 1000;
 | |
| 
 | |
|     setBuffers(m_chunksize);
 | |
| 
 | |
|     if (running) {
 | |
|         startWork();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::setBuffers(std::size_t chunksize)
 | |
| {
 | |
|     if (chunksize > m_bufsize)
 | |
|     {
 | |
|         m_bufsize = chunksize;
 | |
|         int nbSamples = m_bufsize/(2 * m_samplebytes);
 | |
| 
 | |
|         if (m_fileBuf == 0)
 | |
|         {
 | |
|             qDebug() << "FileInputThread::setBuffers: Allocate file buffer";
 | |
|             m_fileBuf = (quint8*) malloc(m_bufsize);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             qDebug() << "FileInputThread::setBuffers: Re-allocate file buffer";
 | |
|             quint8 *buf = m_fileBuf;
 | |
|             m_fileBuf = (quint8*) realloc((void*) m_fileBuf, m_bufsize);
 | |
|             if (!m_fileBuf) free(buf);
 | |
|         }
 | |
| 
 | |
|         if (m_convertBuf == 0)
 | |
|         {
 | |
|             qDebug() << "FileInputThread::setBuffers: Allocate conversion buffer";
 | |
|             m_convertBuf = (quint8*) malloc(nbSamples*sizeof(Sample));
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             qDebug() << "FileInputThread::setBuffers: Re-allocate conversion buffer";
 | |
|             quint8 *buf = m_convertBuf;
 | |
|             m_convertBuf = (quint8*) realloc((void*) m_convertBuf, nbSamples*sizeof(Sample));
 | |
|             if (!m_convertBuf) free(buf);
 | |
|         }
 | |
| 
 | |
|         qDebug() << "FileInputThread::setBuffers: size: " << m_bufsize
 | |
|                 << " #samples: " << nbSamples;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::tick()
 | |
| {
 | |
| 	if (m_running)
 | |
| 	{
 | |
|         qint64 throttlems = m_elapsedTimer.restart();
 | |
| 
 | |
|         if (throttlems != m_throttlems)
 | |
|         {
 | |
|             m_throttlems = throttlems;
 | |
|             m_chunksize = 2 * m_samplebytes * ((m_samplerate * m_accelerationFactor * (m_throttlems+(m_throttleToggle ? 1 : 0))) / 1000);
 | |
|             m_throttleToggle = !m_throttleToggle;
 | |
|             setBuffers(m_chunksize);
 | |
|         }
 | |
| 
 | |
| 		// read samples directly feeding the SampleFifo (no callback)
 | |
| 
 | |
|         if (m_samplesCount + m_chunksize > m_totalSamples) {
 | |
|             m_ifstream->read(reinterpret_cast<char*>(m_fileBuf), m_totalSamples - m_samplesCount);
 | |
|         } else {
 | |
|     		m_ifstream->read(reinterpret_cast<char*>(m_fileBuf), m_chunksize);
 | |
|         }
 | |
| 
 | |
|         if ((m_samplesCount + m_chunksize > m_totalSamples) || m_ifstream->eof())
 | |
|         {
 | |
|         	writeToSampleFifo(m_fileBuf, (qint32) m_ifstream->gcount()); // take what has been read
 | |
|         	MsgReportEOF *message = MsgReportEOF::create();
 | |
|         	m_fileInputMessageQueue->push(message);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|         	writeToSampleFifo(m_fileBuf, (qint32) m_chunksize);
 | |
|     		m_samplesCount += m_chunksize / (2 * m_samplebytes);
 | |
| 
 | |
|             if ((m_currentTrackIndex + 1 < m_captures->size())
 | |
|              && (m_samplesCount > m_captures->at(m_currentTrackIndex+1).m_sampleStart))
 | |
|             {
 | |
|                 m_currentTrackIndex++;
 | |
|                 int sampleRate = m_captures->at(m_currentTrackIndex).m_sampleRate;
 | |
| 
 | |
|                 if (sampleRate != m_samplerate)
 | |
|                 {
 | |
|                     m_samplerate = sampleRate;
 | |
|                     setSampleRate();
 | |
|                 }
 | |
| 
 | |
|                 MsgReportTrackChange *message = MsgReportTrackChange::create(m_currentTrackIndex);
 | |
|                 m_fileInputMessageQueue->push(message);
 | |
|             }
 | |
|         }
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::setConverter()
 | |
| {
 | |
|     if (m_metaInfo->m_dataType.m_floatingPoint) // float
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<float, SDR_RX_SAMP_SZ, 32, true, true, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<float, SDR_RX_SAMP_SZ, 32, true, true, false>();
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<float, SDR_RX_SAMP_SZ, 32, true, false, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<float, SDR_RX_SAMP_SZ, 32, true, false, false>();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian) {
 | |
|                 m_sigMFConverter = new SigMFConverter<float, SDR_RX_SAMP_SZ, 32, false, true, false>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<float, SDR_RX_SAMP_SZ, 32, false, false, false>();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     else if ((m_metaInfo->m_dataType.m_signed) && (m_samplesize == 8))  // i8
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                 m_sigMFConverter = new SigMFConverter<int8_t, SDR_RX_SAMP_SZ, 8, true, false, true>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<int8_t, SDR_RX_SAMP_SZ, 8, true, false, false>();
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             m_sigMFConverter = new SigMFConverter<int8_t, SDR_RX_SAMP_SZ, 8, false, false, false>();
 | |
|         }
 | |
|     }
 | |
|     else if ((!m_metaInfo->m_dataType.m_signed) && (m_samplesize == 8))  // u8
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                 m_sigMFConverter = new SigMFConverter<uint8_t, SDR_RX_SAMP_SZ, 8, true, false, true>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<uint8_t, SDR_RX_SAMP_SZ, 8, true, false, false>();
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             m_sigMFConverter = new SigMFConverter<uint8_t, SDR_RX_SAMP_SZ, 8, false, false, false>();
 | |
|         }
 | |
|     }
 | |
|     else if ((m_metaInfo->m_dataType.m_signed) && (m_samplesize == 16))  // i16
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<int16_t, SDR_RX_SAMP_SZ, 16, true, true, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<int16_t, SDR_RX_SAMP_SZ, 16, true, true, false>();
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<int16_t, SDR_RX_SAMP_SZ, 16, true, false, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<int16_t, SDR_RX_SAMP_SZ, 16, true, false, false>();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian) {
 | |
|                 m_sigMFConverter = new SigMFConverter<int16_t, SDR_RX_SAMP_SZ, 16, false, true, false>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<int16_t, SDR_RX_SAMP_SZ, 16, false, false, false>();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     else if ((!m_metaInfo->m_dataType.m_signed) && (m_samplesize == 16))  // u16
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint16_t, SDR_RX_SAMP_SZ, 16, true, true, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint16_t, SDR_RX_SAMP_SZ, 16, true, true, false>();
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint16_t, SDR_RX_SAMP_SZ, 16, true, false, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint16_t, SDR_RX_SAMP_SZ, 16, true, false, false>();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian) {
 | |
|                 m_sigMFConverter = new SigMFConverter<uint16_t, SDR_RX_SAMP_SZ, 16, false, true, false>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<uint16_t, SDR_RX_SAMP_SZ, 16, false, false, false>();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     else if ((m_metaInfo->m_dataType.m_signed) && (m_samplesize == 24))  // i24 (SDRangel special)
 | |
|     {
 | |
|         m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 24, true, false, false>();
 | |
|     }
 | |
|     else if ((m_metaInfo->m_dataType.m_signed) && (m_samplesize == 32))  // i32
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 32, true, true, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 32, true, true, false>();
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 32, true, false, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 32, true, false, false>();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian) {
 | |
|                 m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 32, false, true, false>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<int32_t, SDR_RX_SAMP_SZ, 32, false, false, false>();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     else if ((!m_metaInfo->m_dataType.m_signed) && (m_samplesize == 32))  // u32
 | |
|     {
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint32_t, SDR_RX_SAMP_SZ, 32, true, true, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint32_t, SDR_RX_SAMP_SZ, 32, true, true, false>();
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_swapIQ) {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint32_t, SDR_RX_SAMP_SZ, 32, true, false, true>();
 | |
|                 } else {
 | |
|                     m_sigMFConverter = new SigMFConverter<uint32_t, SDR_RX_SAMP_SZ, 32, true, false, false>();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (m_metaInfo->m_dataType.m_bigEndian) {
 | |
|                 m_sigMFConverter = new SigMFConverter<uint32_t, SDR_RX_SAMP_SZ, 32, false, true, false>();
 | |
|             } else {
 | |
|                 m_sigMFConverter = new SigMFConverter<uint32_t, SDR_RX_SAMP_SZ, 32, false, false, false>();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::writeToSampleFifo(const quint8* buf, qint32 nbBytes)
 | |
| {
 | |
|     if (!m_sigMFConverter)
 | |
|     {
 | |
|         qDebug("SigMFFileInputWorker::writeToSampleFifo: no converter - probably sample format is not supported");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
| #if defined(__WINDOWS__) || (BYTE_ORDER == LITTLE_ENDIAN)
 | |
|     if ((m_metaInfo->m_dataType.m_complex) && (!m_metaInfo->m_dataType.m_bigEndian) && (!m_metaInfo->m_dataType.m_swapIQ))
 | |
|     {
 | |
|         if ((m_samplesize == 16) && (SDR_RX_SAMP_SZ == 16))
 | |
|         {
 | |
|             m_sampleFifo->write(buf, nbBytes);
 | |
|             return;
 | |
|         }
 | |
|         if ((m_samplesize == 24) && (SDR_RX_SAMP_SZ == 24))
 | |
|         {
 | |
|             m_sampleFifo->write(buf, nbBytes);
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
| #endif
 | |
|     int nbSamples = m_sigMFConverter->convert((FixReal *) m_convertBuf, buf, nbBytes);
 | |
|     m_sampleFifo->write(m_convertBuf, nbSamples*sizeof(Sample));
 | |
| }
 | |
| 
 | |
| void SigMFFileInputWorker::writeToSampleFifoBAK(const quint8* buf, qint32 nbBytes)
 | |
| {
 | |
|     if (m_metaInfo->m_dataType.m_floatingPoint) // FP assumes 32 bit floats (float) always
 | |
|     {
 | |
|         FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|         const float *fileBuf = (float *) buf;
 | |
|         int nbSamples;
 | |
| 
 | |
|         if (m_metaInfo->m_dataType.m_complex)
 | |
|         {
 | |
|             nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|             for (int is = 0; is < nbSamples; is++)
 | |
|             {
 | |
|                 convertBuf[2*is]   = fileBuf[2*is] * SDR_RX_SCALEF;
 | |
|                 convertBuf[2*is+1] = fileBuf[2*is+1] * SDR_RX_SCALEF;
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             nbSamples = nbBytes / m_samplebytes;
 | |
|             for (int is = 0; is < nbSamples; is++)
 | |
|             {
 | |
|                 convertBuf[2*is]   = fileBuf[is] * SDR_RX_SCALEF;
 | |
|                 convertBuf[2*is+1] = 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|     }
 | |
|     else if (m_metaInfo->m_dataType.m_signed) // signed integers
 | |
|     {
 | |
|         if (m_samplesize == 8)
 | |
|         {
 | |
|             FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|             const int8_t *fileBuf = (int8_t *) buf;
 | |
|             int nbSamples;
 | |
| 
 | |
|             if (m_metaInfo->m_dataType.m_complex)
 | |
|             {
 | |
|                 nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[2*is];
 | |
|                     convertBuf[2*is]   <<= (SDR_RX_SAMP_SZ == 16) ? 8 : 16;
 | |
|                     convertBuf[2*is+1] = fileBuf[2*is+1];
 | |
|                     convertBuf[2*is+1] <<= (SDR_RX_SAMP_SZ == 16) ? 8 : 16;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 nbSamples = nbBytes / m_samplebytes;
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[is];
 | |
|                     convertBuf[2*is]   <<= (SDR_RX_SAMP_SZ == 16) ? 8 : 16;
 | |
|                     convertBuf[2*is+1] = 0;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|         }
 | |
|         else if (m_samplesize == 16)
 | |
|         {
 | |
|             if (SDR_RX_SAMP_SZ == 16)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_complex)
 | |
|                 {
 | |
|                     m_sampleFifo->write(buf, nbBytes);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|                     const int16_t *fileBuf = (int16_t *) buf;
 | |
|                     int nbSamples = nbBytes / m_samplebytes;
 | |
| 
 | |
|                     for (int is = 0; is < nbSamples; is++)
 | |
|                     {
 | |
|                         convertBuf[2*is]   = fileBuf[2*is];
 | |
|                         convertBuf[2*is+1] = 0;
 | |
|                     }
 | |
| 
 | |
|                     m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|                 }
 | |
|             }
 | |
|             else if (SDR_RX_SAMP_SZ == 24)
 | |
|             {
 | |
|                 FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|                 const int16_t *fileBuf = (int16_t *) buf;
 | |
|                 int nbSamples;
 | |
| 
 | |
|                 if (m_metaInfo->m_dataType.m_complex)
 | |
|                 {
 | |
|                     nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                     for (int is = 0; is < nbSamples; is++)
 | |
|                     {
 | |
|                         convertBuf[2*is]   = fileBuf[2*is] << 8;
 | |
|                         convertBuf[2*is+1] = fileBuf[2*is+1] << 8;
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     nbSamples = nbBytes / m_samplebytes;
 | |
|                     for (int is = 0; is < nbSamples; is++)
 | |
|                     {
 | |
|                         convertBuf[2*is]   = fileBuf[is] << 8;
 | |
|                         convertBuf[2*is+1] = 0;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|             }
 | |
|         }
 | |
|         else if (m_samplesize == 24)
 | |
|         {
 | |
|             if (SDR_RX_SAMP_SZ == 24)
 | |
|             {
 | |
|                 if (m_metaInfo->m_dataType.m_complex)
 | |
|                 {
 | |
|                     m_sampleFifo->write(buf, nbBytes);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|                     const int32_t *fileBuf = (int32_t *) buf;
 | |
|                     int nbSamples = nbBytes / m_samplebytes;
 | |
| 
 | |
|                     for (int is = 0; is < nbSamples; is++)
 | |
|                     {
 | |
|                         convertBuf[2*is]   = fileBuf[2*is];
 | |
|                         convertBuf[2*is+1] = 0;
 | |
|                     }
 | |
| 
 | |
|                     m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|                 }
 | |
|             }
 | |
|             else if (SDR_RX_SAMP_SZ == 16)
 | |
|             {
 | |
|                 FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|                 const int32_t *fileBuf = (int32_t *) buf;
 | |
|                 int nbSamples;
 | |
| 
 | |
|                 if (m_metaInfo->m_dataType.m_complex)
 | |
|                 {
 | |
|                     nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                     for (int is = 0; is < nbSamples; is++)
 | |
|                     {
 | |
|                         convertBuf[2*is]   = fileBuf[2*is] >> 8;
 | |
|                         convertBuf[2*is+1] = fileBuf[2*is+1] >> 8;
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     nbSamples = nbBytes / m_samplebytes;
 | |
|                     for (int is = 0; is < nbSamples; is++)
 | |
|                     {
 | |
|                         convertBuf[2*is]   = fileBuf[is] >> 8;
 | |
|                         convertBuf[2*is+1] = 0;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|             }
 | |
|         }
 | |
|         if (m_samplesize == 32)
 | |
|         {
 | |
|             FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|             const int32_t *fileBuf = (int32_t *) buf;
 | |
|             int nbSamples;
 | |
| 
 | |
|             if (m_metaInfo->m_dataType.m_complex)
 | |
|             {
 | |
|                 nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[2*is] >> ((SDR_RX_SAMP_SZ == 24) ? 8 : 16);
 | |
|                     convertBuf[2*is+1] = fileBuf[2*is+1] >> ((SDR_RX_SAMP_SZ == 24) ? 8 : 16);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 nbSamples = nbBytes / m_samplebytes;
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[is] >> ((SDR_RX_SAMP_SZ == 24) ? 8 : 16);
 | |
|                     convertBuf[2*is+1] = 0;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|         }
 | |
|     }
 | |
|     else // unsigned integers
 | |
|     {
 | |
|         if (m_samplesize == 8)
 | |
|         {
 | |
|             FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|             const uint8_t *fileBuf = (uint8_t *) buf;
 | |
|             int nbSamples;
 | |
| 
 | |
|             if (m_metaInfo->m_dataType.m_complex)
 | |
|             {
 | |
|                 nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[2*is] - 128;
 | |
|                     convertBuf[2*is]   <<= (SDR_RX_SAMP_SZ == 16) ? 8 : 16;
 | |
|                     convertBuf[2*is+1] = fileBuf[2*is+1] - 128;
 | |
|                     convertBuf[2*is+1] <<= (SDR_RX_SAMP_SZ == 16) ? 8 : 16;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 nbSamples = nbBytes / m_samplebytes;
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[is] - 128;
 | |
|                     convertBuf[2*is]   <<= (SDR_RX_SAMP_SZ == 16) ? 8 : 16;
 | |
|                     convertBuf[2*is+1] = 0;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|         }
 | |
|         else if (m_samplesize == 16)
 | |
|         {
 | |
|             FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|             const uint16_t *fileBuf = (uint16_t *) buf;
 | |
|             int nbSamples;
 | |
| 
 | |
|             if (m_metaInfo->m_dataType.m_complex)
 | |
|             {
 | |
|                 nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[2*is] - 32768;
 | |
|                     convertBuf[2*is]   <<= (SDR_RX_SAMP_SZ == 16) ? 0 : 8;
 | |
|                     convertBuf[2*is+1] = fileBuf[2*is+1] - 32768;
 | |
|                     convertBuf[2*is+1] <<= (SDR_RX_SAMP_SZ == 16) ? 0 : 8;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 nbSamples = nbBytes / m_samplebytes;
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is]   = fileBuf[is] - 32768;
 | |
|                     convertBuf[2*is]   <<= (SDR_RX_SAMP_SZ == 16) ? 0 : 8;
 | |
|                     convertBuf[2*is+1] = 0;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|         }
 | |
|         else if (m_samplesize == 32)
 | |
|         {
 | |
|             FixReal *convertBuf = (FixReal *) m_convertBuf;
 | |
|             const uint32_t *fileBuf = (uint32_t *) buf;
 | |
|             int nbSamples;
 | |
| 
 | |
|             if (m_metaInfo->m_dataType.m_complex)
 | |
|             {
 | |
|                 nbSamples = nbBytes / (2 * m_samplebytes);
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is] = (fileBuf[2*is] >> ((SDR_RX_SAMP_SZ == 24) ? 8 : 16))
 | |
|                         - ((SDR_RX_SAMP_SZ == 24) ? (1<<23) : (1<<15));
 | |
|                     convertBuf[2*is+1] = (fileBuf[2*is+1] >> ((SDR_RX_SAMP_SZ == 24) ? 8 : 16))
 | |
|                         - ((SDR_RX_SAMP_SZ == 24) ? (1<<23) : (1<<15));;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 nbSamples = nbBytes / m_samplebytes;
 | |
|                 for (int is = 0; is < nbSamples; is++)
 | |
|                 {
 | |
|                     convertBuf[2*is] = (fileBuf[is] >> ((SDR_RX_SAMP_SZ == 24) ? 8 : 16))
 | |
|                         - ((SDR_RX_SAMP_SZ == 24) ? (1<<23) : (1<<15));
 | |
|                     convertBuf[2*is+1] = 0;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
 | |
|         }
 | |
|     }
 | |
| }
 |