1 /* 2 * Copyright (C) 2017 3 * Albrecht Lohofener (albrechtloh@gmx.de) 4 * 5 * This file is based on SDR-J 6 * Copyright (C) 2010, 2011, 2012, 2013 7 * Jan van Katwijk (J.vanKatwijk@gmail.com) 8 * 9 * This file is part of the welle.io. 10 * Many of the ideas as implemented in welle.io are derived from 11 * other work, made available through the GNU general Public License. 12 * All copyrights of the original authors are recognized. 13 * 14 * welle.io is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * welle.io is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with welle.io; if not, write to the Free Software 26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 * 28 */ 29 30 #ifndef __VIRTUAL_INPUT 31 #define __VIRTUAL_INPUT 32 33 #include <memory> 34 #include <fstream> 35 #include <iostream> 36 37 #include "dab-constants.h" 38 #include "radio-controller.h" 39 #include "ringbuffer.h" 40 41 enum class CDeviceID { 42 UNKNOWN, NULLDEVICE, AIRSPY, RAWFILE, RTL_SDR, RTL_TCP, SOAPYSDR, ANDROID_RTL_SDR, LIMESDR}; 43 44 class CVirtualInput : public InputInterface { 45 public: ~CVirtualInput()46 virtual ~CVirtualInput() {} 47 virtual CDeviceID getID(void) = 0; 48 writeRecordBufferToFile(std::string & fileanme)49 void writeRecordBufferToFile(std::string &fileanme) { 50 if(!recordBuffer) 51 return; 52 53 std::ofstream rawStream(fileanme, std::ios::binary); 54 55 while (1) { 56 uint8_t data_tmp[1024]; 57 const auto available = recordBuffer->GetRingBufferReadAvailable(); 58 59 if (available <= 0) { 60 break; 61 } 62 63 const size_t data_tmpSize = std::min(sizeof(data_tmp), (size_t)available); 64 recordBuffer->getDataFromBuffer(data_tmp, data_tmpSize); 65 rawStream.write((char*)data_tmp, data_tmpSize); 66 } 67 68 rawStream.close(); 69 } 70 initRecordBuffer(uint32_t size)71 void initRecordBuffer(uint32_t size) { 72 // The ring buffer size has to be power of 2 73 uint32_t bitCount = ceil(log2(size)); 74 uint32_t bufferSize = pow(2, bitCount); 75 76 try { 77 recordBuffer.reset(new RingBuffer<uint8_t>(bufferSize)); 78 } 79 80 catch (const std::bad_alloc& e) { 81 std::clog << "CVirtualInput: recordBuffer allocation failed (size " << bufferSize * sizeof(uint8_t) << " bytes) : " << e.what() << std::endl; 82 } 83 } 84 85 protected: putIntoRecordBuffer(uint8_t & data,uint32_t size)86 void putIntoRecordBuffer(uint8_t &data, uint32_t size) { 87 if(!recordBuffer) 88 return; 89 90 recordBuffer->putDataIntoBuffer(&data, static_cast<int>(size)); 91 //std::clog << "CVirtualInput: GetRingBufferReadAvailable() " << recordBuffer->GetRingBufferReadAvailable() << std::endl; 92 } 93 94 private: 95 std::unique_ptr<RingBuffer<uint8_t>> recordBuffer; 96 }; 97 98 #endif 99