Esempio n. 1
0
void SDRPostThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();  // ID of this thread
    int priority = sched_get_priority_max( SCHED_FIFO);
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif

    std::cout << "SDR post-processing thread started.." << std::endl;

    iqDataInQueue = (SDRThreadIQDataQueue*)getInputQueue("IQDataInput");
    iqDataOutQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQDataOutput");
    iqVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQVisualDataOutput");
    iqActiveDemodVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQActiveDemodVisualDataOutput");

    iqDataInQueue->set_max_num_items(0);
    
    while (!terminated) {
        SDRThreadIQData *data_in;
        
        iqDataInQueue->pop(data_in);
        //        std::lock_guard < std::mutex > lock(data_in->m_mutex);

        busy_demod.lock();

        if (data_in && data_in->data.size()) {
            if(data_in->numChannels > 1) {
                runPFBCH(data_in);
            } else {
                runSingleCH(data_in);
            }
        }

        data_in->decRefCount();

        bool doUpdate = false;
        for (size_t j = 0; j < nRunDemods; j++) {
            DemodulatorInstance *demod = runDemods[j];
            if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
                doUpdate = true;
            }
        }
        
        if (doUpdate) {
            updateActiveDemodulators();
        }
        
        busy_demod.unlock();
    }
    
    if (iqVisualQueue && !iqVisualQueue->empty()) {
        DemodulatorThreadIQData *visualDataDummy;
        iqVisualQueue->pop(visualDataDummy);
    }

    //    buffers.purge();
    //    visualDataBuffers.purge();

    std::cout << "SDR post-processing thread done." << std::endl;
}
Esempio n. 2
0
void SDRPostThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();  // ID of this thread
    int priority = sched_get_priority_max( SCHED_FIFO);
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif

//    std::cout << "SDR post-processing thread started.." << std::endl;

    iqDataInQueue = static_cast<SDRThreadIQDataQueue*>(getInputQueue("IQDataInput"));
    iqDataOutQueue = static_cast<DemodulatorThreadInputQueue*>(getOutputQueue("IQDataOutput"));
    iqVisualQueue = static_cast<DemodulatorThreadInputQueue*>(getOutputQueue("IQVisualDataOutput"));
    iqActiveDemodVisualQueue = static_cast<DemodulatorThreadInputQueue*>(getOutputQueue("IQActiveDemodVisualDataOutput"));
    
    while (!stopping) {
        SDRThreadIQData *data_in;
        
        iqDataInQueue->pop(data_in);
        //        std::lock_guard < std::mutex > lock(data_in->m_mutex);

        std::lock_guard < std::mutex > lock(busy_demod);

        if (data_in && data_in->data.size()) {
            if(data_in->numChannels > 1) {
                runPFBCH(data_in);
            } else {
                runSingleCH(data_in);
            }
        }

        if (data_in) {
            data_in->decRefCount();   
        }

        bool doUpdate = false;
        for (size_t j = 0; j < nRunDemods; j++) {
            DemodulatorInstance *demod = runDemods[j];
            if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
                doUpdate = true;
            }
        }
        
        //Only update the list of demodulators here
        if (doUpdate) {
            updateActiveDemodulators();
        }
    } //end while
    
    //Be safe, remove as many elements as possible
    DemodulatorThreadIQData *visualDataDummy;
    while (iqVisualQueue && iqVisualQueue->try_pop(visualDataDummy)) {
        visualDataDummy->decRefCount();        
    }

    //    buffers.purge();
    //    visualDataBuffers.purge();

//    std::cout << "SDR post-processing thread done." << std::endl;
}
Esempio n. 3
0
IOReturn HoRNDIS::enable(IONetworkInterface *netif) {
	IONetworkMedium	*medium;
	IOReturn rtn = kIOReturnSuccess;

	if (fNetifEnabled) {
		LOG(V_ERROR, "already enabled?");
		return kIOReturnSuccess;
	}
	
	if (!allocateResources())
		return kIOReturnNoMemory;
	
	if (!fMediumDict)
		if (!createMediumTables()) {
			rtn = kIOReturnNoMemory;
			goto bailout;
		}
	setCurrentMedium(IONetworkMedium::medium(kIOMediumEthernetAuto, 480 * 1000000));
	
	/* Kick off the first read. */
	inbuf.comp.target = this;
	inbuf.comp.action = dataReadComplete;
	inbuf.comp.parameter = NULL;
	
	rtn = fInPipe->Read(inbuf.mdp, &inbuf.comp, NULL);
	if (rtn != kIOReturnSuccess)
		goto bailout;

	/* Tell the world that the link is up... */
	medium = IONetworkMedium::getMediumWithType(fMediumDict, kIOMediumEthernetAuto);
	setLinkStatus(kIONetworkLinkActive | kIONetworkLinkValid, medium, 480 * 1000000);
	
	/* ... and then listen for packets! */
	getOutputQueue()->setCapacity(TRANSMIT_QUEUE_SIZE);
	getOutputQueue()->start();
	LOG(V_DEBUG, "txqueue started");
	
	/* Tell the other end to start transmitting. */
	if (!rndisSetPacketFilter(RNDIS_DEFAULT_FILTER))
		goto bailout;
	
	/* Now we can say we're alive. */
	fNetifEnabled = true;
	
	return kIOReturnSuccess;
	
bailout:
	LOG(V_ERROR, "setting up the pipes failed");
	releaseResources();
	return rtn;
}
Esempio n. 4
0
void AudioThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();	 // ID of this thread
    int priority = sched_get_priority_max( SCHED_RR) - 1;
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_RR, &prio);
#endif

    std::cout << "Audio thread initializing.." << std::endl;

    if (dac.getDeviceCount() < 1) {
        std::cout << "No audio devices found!" << std::endl;
        return;
    }

    setupDevice((outputDevice.load() == -1) ? (dac.getDefaultOutputDevice()) : outputDevice.load());

    std::cout << "Audio thread started." << std::endl;

    inputQueue = (AudioThreadInputQueue *)getInputQueue("AudioDataInput");
    threadQueueNotify = (DemodulatorThreadCommandQueue*)getOutputQueue("NotifyQueue");
    
    while (!terminated) {
        AudioThreadCommand command;
        cmdQueue.pop(command);

        if (command.cmd == AudioThreadCommand::AUDIO_THREAD_CMD_SET_DEVICE) {
            setupDevice(command.int_value);
        }
        if (command.cmd == AudioThreadCommand::AUDIO_THREAD_CMD_SET_SAMPLE_RATE) {
            setSampleRate(command.int_value);
        }
    }

    if (deviceController[parameters.deviceId] != this) {
        deviceController[parameters.deviceId]->removeThread(this);
    } else {
        try {
            if (dac.isStreamOpen()) {
                if (dac.isStreamRunning()) {
                    dac.stopStream();
                }
                dac.closeStream();
            }
        } catch (RtAudioError& e) {
            e.printMessage();
        }
    }

    if (threadQueueNotify != NULL) {
        DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED);
        tCmd.context = this;
        threadQueueNotify->push(tCmd);
    }
    std::cout << "Audio thread done." << std::endl;
}
bool RTL8139::initEventSources( IOService *provider )
{
	ELG( 0, 0, 'InES', "RTL8139::initEventSources - " );
    DEBUG_LOG( "initEventSources() ===>\n" );

	IOWorkLoop	*wl = getWorkLoop();
	if ( 0 == wl )
        return false;

	fTransmitQueue = getOutputQueue();
	if ( 0 == fTransmitQueue )
        return false;
	fTransmitQueue->setCapacity( kTransmitQueueCapacity );

		// Create an interrupt event source to handle hardware interrupts.

	interruptSrc = IOInterruptEventSource::interruptEventSource(
						this,
					   OSMemberFunctionCast(	IOInterruptEventAction,
												this,
												&RTL8139::interruptOccurred ),
					   provider );

	if ( !interruptSrc || (wl->addEventSource( interruptSrc ) != kIOReturnSuccess) )
		return false;

		// This is important. If the interrupt line is shared with other devices,
		// then the interrupt vector will be enabled only if all corresponding
		// interrupt event sources are enabled. To avoid masking interrupts for
		// other devices that are sharing the interrupt line, the event source
		// is enabled immediately. Hardware interrupt sources remain disabled.

    interruptSrc->enable();

		// Register a timer event source used as a watchdog timer:

	timerSrc = IOTimerEventSource::timerEventSource(
					this,
					OSMemberFunctionCast(	IOTimerEventSource::Action,
											this,
											&RTL8139::timeoutOccurred ) );

	if ( !timerSrc || (wl->addEventSource( timerSrc ) != kIOReturnSuccess) )
		return false;

		// Create a dictionary to hold IONetworkMedium objects:

	mediumDict = OSDictionary::withCapacity( 5 );
	if ( 0 == mediumDict )
		return false;

	DEBUG_LOG( "initEventSources() <===\n" );
	return true;
}/* end initEventSources */
void IOVideoSampleStream::postFreeInputBuffer(UInt64 vbiTime, UInt64 outputTime, UInt64 totalFrameCount, UInt64 droppedFrameCount,UInt64 lastDisplayedSequenceNumber)
{
	IOStreamBuffer* buf = OSDynamicCast(IOStreamBuffer, _freeBuffers->getObject(0));
	if (NULL == buf)
	{
		USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - no free buffers\n");
		if ((getOutputQueue())->entryCount > 0)
		{
			//all the free buffers are in the queue already so just alert the host
			(void) sendOutputNotification();
		}
		return;
	}
	
	_freeBuffers->removeObject(0);

	IOMemoryDescriptor *ctrlDescriptor = OSDynamicCast(IOMemoryDescriptor, buf->getControlBuffer());
	if (NULL != ctrlDescriptor)
	{
		USBLog(1, "IOVideoSampleStream got control buffer descriptor\n");
		SampleVideoDeviceControlBuffer theBuffControl, readBackControl;
		USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - passed in vbiTime = %lld outputTime = %lld framecount = %lld droppedframecount = %lld lastDisplayedSequenceNumber = %lld  \n", vbiTime, outputTime, totalFrameCount, droppedFrameCount, lastDisplayedSequenceNumber);

		
		theBuffControl.vbiTime = vbiTime; 
		theBuffControl.outputTime = outputTime; 
		theBuffControl.totalFrameCount = totalFrameCount; 
		theBuffControl.droppedFrameCount = droppedFrameCount; 
		theBuffControl.firstVBITime = 0;
		theBuffControl.sequenceNumber = lastDisplayedSequenceNumber;
		theBuffControl.discontinuityFlags = 0;
		
		(void) ctrlDescriptor->prepare();
		
        ctrlDescriptor->writeBytes(0, &theBuffControl, buf->getControlBuffer()->getLength());
		ctrlDescriptor->readBytes(0, &readBackControl, buf->getControlBuffer()->getLength());
		USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - control buffer info vbiTime = %lld outputTime = %lld framecount = %lld droppedframecount = %lld  sequencenumber = %lld\n", readBackControl.vbiTime, readBackControl.outputTime, readBackControl.totalFrameCount, readBackControl.droppedFrameCount,readBackControl.sequenceNumber);
		(void) ctrlDescriptor->complete();
	}
		
	IOReturn result = enqueueOutputBuffer(buf, 0, buf->getDataBuffer()->getLength(), 0, buf->getControlBuffer()->getLength()); 
	if (result != kIOReturnSuccess)
	{
		USBLog(1, "IOVideoSampleStream::postFreeInputBuffer help enqueueOutputBuffer failed! (%x)\n", result);
		return;
	}
	
	result = sendOutputNotification();
	if (result != kIOReturnSuccess)
	{
		USBLog(1, "IOVideoSampleStream::postFreeInputBuffer help sendOutputNotification failed! (%x)\n", result);
		return;
	}
}
Esempio n. 7
0
IOReturn HoRNDIS::disable(IONetworkInterface * netif) {
	/* Disable the queue (no more outputPacket), and then flush everything in the queue. */
	getOutputQueue()->stop();
	getOutputQueue()->setCapacity(0);
	getOutputQueue()->flush();
	
	/* Other end should stop xmitting, too. */
	rndisSetPacketFilter(0);
	
	setLinkStatus(0, 0);
	
	/* Release all resources */
	releaseResources();
	
	fNetifEnabled = false;
	
	/* Terminates also close the device in 'disable'. */
	if (fTerminate) {
		fpDevice->close(this);
		fpDevice = NULL;
	}

	return kIOReturnSuccess;
}
Esempio n. 8
0
void SDRThread::readLoop() {
    SDRThreadIQDataQueue* iqDataOutQueue = static_cast<SDRThreadIQDataQueue*>( getOutputQueue("IQDataOutput"));
    
    if (iqDataOutQueue == NULL) {
        return;
    }
    
    updateGains();

    while (!stopping.load()) {
        updateSettings();
        readStream(iqDataOutQueue);
    }

    buffers.purge();
}
//---------------------------------------------------------------------------
bool AgereET131x::initEventSources( IOService* provider )
{
	// Get a handle to our superclass' workloop.
	//
	IOWorkLoop* myWorkLoop = (IOWorkLoop *) getWorkLoop();
	if (myWorkLoop == NULL) {
		IOLog(" myWorkLoop is NULL.\n");
		return false;
	}
	
	transmitQueue = getOutputQueue();
	if (transmitQueue == NULL) {
		IOLog("getOutputQueue failed.\n");
		return false;
	}
	transmitQueue->setCapacity(NUM_TCB);
	
	interruptSource = IOFilterInterruptEventSource::filterInterruptEventSource( this, &AgereET131x::interruptHandler, &AgereET131x::interruptFilter, provider);
	
	if (!interruptSource ||
		(myWorkLoop->addEventSource(interruptSource) != kIOReturnSuccess)) {
		IOLog("workloop add eventsource interrupt source.\n");
		return false;
	}
	
	// This is important. If the interrupt line is shared with other devices,
	// then the interrupt vector will be enabled only if all corresponding
	// interrupt event sources are enabled. To avoid masking interrupts for
	// other devices that are sharing the interrupt line, the event source
	// is enabled immediately.
	interruptSource->enable();
	
	// Register a timer event source. This is used as a watchdog timer.
	//
	watchdogSource = IOTimerEventSource::timerEventSource(this, &AgereET131x::timeoutHandler );
	if (!watchdogSource || (myWorkLoop->addEventSource(watchdogSource) != kIOReturnSuccess)) {
		IOLog("watchdogSource create failed.\n");
		return false;
	}
	
	mediumDict = OSDictionary::withCapacity(MEDIUM_INDEX_COUNT + 1);
	if (mediumDict == NULL) {
		return false;
	}
	return true;
}
Esempio n. 10
0
void FFTVisualDataThread::run() {
    DemodulatorThreadInputQueue *pipeIQDataIn = static_cast<DemodulatorThreadInputQueue *>(getInputQueue("IQDataInput"));
    SpectrumVisualDataQueue *pipeFFTDataOut = static_cast<SpectrumVisualDataQueue *>(getOutputQueue("FFTDataOutput"));
    
    fftQueue.set_max_num_items(100);
    pipeFFTDataOut->set_max_num_items(100);
    fftDistrib.setInput(pipeIQDataIn);
    fftDistrib.attachOutput(&fftQueue);
    wproc.setInput(&fftQueue);
    wproc.attachOutput(pipeFFTDataOut);
    wproc.setup(DEFAULT_FFT_SIZE);

//    std::cout << "FFT visual data thread started." << std::endl;
    
    while(!stopping) {
        
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
//        std::this_thread::yield();
        
        int fftSize = wproc.getDesiredInputSize();
        
        if (fftSize) {
            fftDistrib.setFFTSize(fftSize);
        } else {
            fftDistrib.setFFTSize(DEFAULT_FFT_SIZE * SPECTRUM_VZM);
        }
    
        if (lpsChanged.load()) {
            fftDistrib.setLinesPerSecond(linesPerSecond.load());
//            pipeIQDataIn->set_max_num_items(linesPerSecond.load());
            lpsChanged.store(false);
        }
        
        fftDistrib.run();
        
        while (!wproc.isInputEmpty()) {
            wproc.run();
        }
    }
    
//    std::cout << "FFT visual data thread done." << std::endl;
}
void FFTVisualDataThread::run() {
    DemodulatorThreadInputQueue *pipeIQDataIn = (DemodulatorThreadInputQueue *)getInputQueue("IQDataInput");
    SpectrumVisualDataQueue *pipeFFTDataOut = (SpectrumVisualDataQueue *)getOutputQueue("FFTDataOutput");
    
    fftDistrib.setInput(pipeIQDataIn);
    fftDistrib.attachOutput(&fftQueue);
    wproc.setInput(&fftQueue);
    wproc.attachOutput(pipeFFTDataOut);
    wproc.setup(2048);

    std::cout << "FFT visual data thread started." << std::endl;
    
    while(!terminated) {
        
        std::this_thread::sleep_for(std::chrono::milliseconds(12));
        
        int fftSize = wproc.getDesiredInputSize();
        
        if (fftSize) {
            fftDistrib.setFFTSize(fftSize);
        } else {
            fftDistrib.setFFTSize(DEFAULT_FFT_SIZE);
        }
    
        if (lpsChanged.load()) {
            fftDistrib.setLinesPerSecond(linesPerSecond.load());
            pipeIQDataIn->set_max_num_items(linesPerSecond.load());
            lpsChanged.store(false);
        }
        
        fftDistrib.run();
        
        while (!wproc.isInputEmpty()) {
            wproc.run();
        }
    }
    
    std::cout << "FFT visual data thread done." << std::endl;
}
Esempio n. 12
0
void DemodulatorPreThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();  // ID of this thread
    int priority = sched_get_priority_max( SCHED_FIFO) - 1;
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif

    if (!initialized) {
        initialize();
    }

    std::cout << "Demodulator preprocessor thread started.." << std::endl;

    t_Worker = new std::thread(&DemodulatorWorkerThread::threadMain, workerThread);

    ReBuffer<DemodulatorThreadPostIQData> buffers;

    iqInputQueue = (DemodulatorThreadInputQueue*)getInputQueue("IQDataInput");
    iqOutputQueue = (DemodulatorThreadPostInputQueue*)getOutputQueue("IQDataOutput");
    threadQueueNotify = (DemodulatorThreadCommandQueue*)getOutputQueue("NotifyQueue");
    commandQueue = ( DemodulatorThreadCommandQueue*)getInputQueue("CommandQueue");
    
    std::vector<liquid_float_complex> in_buf_data;
    std::vector<liquid_float_complex> out_buf_data;
//    liquid_float_complex carrySample;   // Keep the stream count even to simplify some demod operations
//    bool carrySampleFlag = false;

    while (!terminated) {
        DemodulatorThreadIQData *inp;
        iqInputQueue->pop(inp);

        bool bandwidthChanged = false;
        bool rateChanged = false;
        DemodulatorThreadParameters tempParams = params;

        if (!commandQueue->empty()) {
            while (!commandQueue->empty()) {
                DemodulatorThreadCommand command;
                commandQueue->pop(command);
                switch (command.cmd) {
                case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH:
                    if (command.llong_value < 1500) {
                        command.llong_value = 1500;
                    }
                    if (command.llong_value > params.sampleRate) {
                        tempParams.bandwidth = params.sampleRate;
                    } else {
                        tempParams.bandwidth = command.llong_value;
                    }
                    bandwidthChanged = true;
                    break;
                case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_FREQUENCY:
                    params.frequency = tempParams.frequency = command.llong_value;
                    break;
                case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_AUDIO_RATE:
                    tempParams.audioSampleRate = (int)command.llong_value;
                    rateChanged = true;
                    break;
                default:
                    break;
                }
            }
        }

        if (inp->sampleRate != tempParams.sampleRate && inp->sampleRate) {
            tempParams.sampleRate = inp->sampleRate;
            rateChanged = true;
        }

        if (bandwidthChanged || rateChanged) {
            DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS);
            command.sampleRate = tempParams.sampleRate;
            command.audioSampleRate = tempParams.audioSampleRate;
            command.bandwidth = tempParams.bandwidth;
            command.frequency = tempParams.frequency;

            workerQueue->push(command);
        }

        if (!initialized) {
            inp->decRefCount();
            continue;
        }

        // Requested frequency is not center, shift it into the center!
        if ((params.frequency - inp->frequency) != shiftFrequency || rateChanged) {
            shiftFrequency = params.frequency - inp->frequency;
            if (abs(shiftFrequency) <= (int) ((double) (inp->sampleRate / 2) * 1.5)) {
                nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) inp->sampleRate)));
            }
        }

        if (abs(shiftFrequency) > (int) ((double) (inp->sampleRate / 2) * 1.5)) {
            inp->decRefCount();
            continue;
        }

//        std::lock_guard < std::mutex > lock(inp->m_mutex);
        std::vector<liquid_float_complex> *data = &inp->data;
        if (data->size() && (inp->sampleRate == params.sampleRate)) {
            int bufSize = data->size();

            if (in_buf_data.size() != bufSize) {
                if (in_buf_data.capacity() < bufSize) {
                    in_buf_data.reserve(bufSize);
                    out_buf_data.reserve(bufSize);
                }
                in_buf_data.resize(bufSize);
                out_buf_data.resize(bufSize);
            }

            in_buf_data.assign(inp->data.begin(), inp->data.end());

            liquid_float_complex *in_buf = &in_buf_data[0];
            liquid_float_complex *out_buf = &out_buf_data[0];
            liquid_float_complex *temp_buf = NULL;

            if (shiftFrequency != 0) {
                if (shiftFrequency < 0) {
                    nco_crcf_mix_block_up(freqShifter, in_buf, out_buf, bufSize);
                } else {
                    nco_crcf_mix_block_down(freqShifter, in_buf, out_buf, bufSize);
                }
                temp_buf = in_buf;
                in_buf = out_buf;
                out_buf = temp_buf;
            }

            DemodulatorThreadPostIQData *resamp = buffers.getBuffer();

            int out_size = ceil((double) (bufSize) * iqResampleRatio) + 512;

            if (resampledData.size() != out_size) {
                if (resampledData.capacity() < out_size) {
                    resampledData.reserve(out_size);
                }
                resampledData.resize(out_size);
            }

            unsigned int numWritten;
            msresamp_crcf_execute(iqResampler, in_buf, bufSize, &resampledData[0], &numWritten);

            resamp->setRefCount(1);

            resamp->data.assign(resampledData.begin(), resampledData.begin() + numWritten);

//            bool uneven = (numWritten % 2 != 0);

//            if (!carrySampleFlag && !uneven) {
//                resamp->data.assign(resampledData.begin(), resampledData.begin() + numWritten);
//                carrySampleFlag = false;
//            } else if (!carrySampleFlag && uneven) {
//                resamp->data.assign(resampledData.begin(), resampledData.begin() + (numWritten-1));
//                carrySample = resampledData.back();
//                carrySampleFlag = true;
//            } else if (carrySampleFlag && uneven) {
//                resamp->data.resize(numWritten+1);
//                resamp->data[0] = carrySample;
//                memcpy(&resamp->data[1],&resampledData[0],sizeof(liquid_float_complex)*numWritten);
//                carrySampleFlag = false;
//            } else if (carrySampleFlag && !uneven) {
//                resamp->data.resize(numWritten);
//                resamp->data[0] = carrySample;
//                memcpy(&resamp->data[1],&resampledData[0],sizeof(liquid_float_complex)*(numWritten-1));
//                carrySample = resampledData.back();
//                carrySampleFlag = true;
//            }



            resamp->audioResampleRatio = audioResampleRatio;
            resamp->audioResampler = audioResampler;
            resamp->audioSampleRate = params.audioSampleRate;
            resamp->stereoResampler = stereoResampler;
            resamp->firStereoLeft = firStereoLeft;
            resamp->firStereoRight = firStereoRight;
            resamp->iirStereoPilot = iirStereoPilot;
            resamp->sampleRate = params.bandwidth;

            iqOutputQueue->push(resamp);
        }

        inp->decRefCount();

        if (!terminated && !workerResults->empty()) {
            while (!workerResults->empty()) {
                DemodulatorWorkerThreadResult result;
                workerResults->pop(result);

                switch (result.cmd) {
                case DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS:
                    msresamp_crcf_destroy(iqResampler);

                    if (result.iqResampler) {
                        iqResampler = result.iqResampler;
                        iqResampleRatio = result.iqResampleRatio;
                    }

                    if (result.firStereoLeft) {
                        firStereoLeft = result.firStereoLeft;
                    }

                    if (result.firStereoRight) {
                        firStereoRight = result.firStereoRight;
                    }

                    if (result.iirStereoPilot) {
                        iirStereoPilot = result.iirStereoPilot;
                    }
                    
                    if (result.audioResampler) {
                        audioResampler = result.audioResampler;
                        audioResampleRatio = result.audioResamplerRatio;
                        stereoResampler = result.stereoResampler;
                    }

                    if (result.audioSampleRate) {
                        params.audioSampleRate = result.audioSampleRate;
                    }

                    if (result.bandwidth) {
                        params.bandwidth = result.bandwidth;
                    }

                    if (result.sampleRate) {
                        params.sampleRate = result.sampleRate;
                    }
                    break;
                default:
                    break;
                }
            }
        }
    }

    buffers.purge();

    DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED);
    tCmd.context = this;
    threadQueueNotify->push(tCmd);
    std::cout << "Demodulator preprocessor thread done." << std::endl;
}
Esempio n. 13
0
bool AtherosL1Ethernet::start(IOService *provider)
{
    DbgPrint("start()\n");

    at_adapter *adapter=&adapter_;
    
    if (!BASE::start(provider))
    {
        ErrPrint("Couldn't start BASE\n");
        return false;
    }

    adapter->pdev = OSDynamicCast(IOPCIDevice, provider);

    if (!adapter->pdev)
    {
        ErrPrint("Unable to cast provider\n");
        return false;
    }

    adapter->pdev->retain();
    adapter->pdev->open(this);

    //Adding Mac OS X PHY's
    mediumDict = OSDictionary::withCapacity(MEDIUM_INDEX_COUNT + 1);

    OSAddNetworkMedium(kIOMediumEthernetAuto, 0, MEDIUM_INDEX_AUTO);
    OSAddNetworkMedium(kIOMediumEthernet10BaseT | kIOMediumOptionHalfDuplex, 10 * MBit, MEDIUM_INDEX_10HD);
    OSAddNetworkMedium(kIOMediumEthernet10BaseT | kIOMediumOptionFullDuplex, 10 * MBit, MEDIUM_INDEX_10FD);
    OSAddNetworkMedium(kIOMediumEthernet100BaseTX | kIOMediumOptionHalfDuplex, 100 * MBit, MEDIUM_INDEX_100HD);
    OSAddNetworkMedium(kIOMediumEthernet100BaseTX | kIOMediumOptionFullDuplex, 100 * MBit, MEDIUM_INDEX_100FD);
    OSAddNetworkMedium(kIOMediumEthernet1000BaseTX | kIOMediumOptionHalfDuplex, 1000 * MBit, MEDIUM_INDEX_1000HD);
    OSAddNetworkMedium(kIOMediumEthernet1000BaseTX | kIOMediumOptionFullDuplex, 1000 * MBit, MEDIUM_INDEX_1000FD);
    
    if (!publishMediumDictionary(mediumDict)) return false;

    if (!atProbe()) //Fix false reporting int probe function
    {
        ErrPrint("Couldn't probe adapter\n");
        stop(provider);
        return false;
    }
    

    workLoop_ = getWorkLoop();
    if (!workLoop_)
    {
        ErrPrint("workLoop is not exists\n");
        stop(provider);
        return false;
    }

    transmitQueue_ = getOutputQueue();
    if (!transmitQueue_)
    {
        ErrPrint("transmitQueue is not exists\n");
        stop(provider);
        return false;
    }

    //Looking for MSI interrupt index
    int msi_index = -1;
    int intr_index = 0, intr_type = 0;
    IOReturn intr_ret;
    while (true)
    {
        intr_ret = provider->getInterruptType(intr_index, &intr_type);
        if (intr_ret != kIOReturnSuccess) break;
        if (intr_type & kIOInterruptTypePCIMessaged) msi_index = intr_index;
        intr_index++;
    }

    if (msi_index != -1)
    {
        DbgPrint("MSI interrupt index %d\n", msi_index);
        intSource_ = IOInterruptEventSource::interruptEventSource(this,
                    OSMemberFunctionCast(IOInterruptEventSource::Action, this, &AtherosL1Ethernet::atIntr),
                    adapter->pdev, msi_index);
    }

    if (msi_index == -1 || intSource_ == NULL)
    {
        DbgPrint("MSI index was not found or MSI interrupt couldn't be enabled\n");
        intSource_ = IOInterruptEventSource::interruptEventSource(this,
                    OSMemberFunctionCast(IOInterruptEventSource::Action, this, &AtherosL1Ethernet::atIntr),
                    adapter->pdev);
    }

    //Adding interrupt to our workloop event sources
    if (!intSource_ || workLoop_->addEventSource(intSource_) != kIOReturnSuccess)
    {
        if (!intSource_) ErrPrint("Couldn't create interrupt source\n");
        else ErrPrint("Couldn't attach interrupt source\n");
        stop(provider);
        return false;
    }

    //Attaching dynamic link layer
    if (!this->attachInterface(reinterpret_cast<IONetworkInterface **>(&netIface_)), false)
    {
        DbgPrint("Failed to attach data link layer\n");
        return false;
    }

    intSource_->enable();
    
    /* allocate Tx / RX descriptor resources */
    if (at_setup_ring_resources(adapter))
    {
        ErrPrint("Couldn't allocate ring descriptors\n");
        adapter->pdev->close(this);
        return kIOReturnError;
    }
    

    netIface_->registerService();
    adapter->pdev->close(this);
    return true;
}
Esempio n. 14
0
void SDRPostThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();  // ID of this thread
    int priority = sched_get_priority_max( SCHED_FIFO) - 1;
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif

    dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);

    std::cout << "SDR post-processing thread started.." << std::endl;

    iqDataInQueue = (SDRThreadIQDataQueue*)getInputQueue("IQDataInput");
    iqDataOutQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQDataOutput");
    iqVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQVisualDataOutput");
    
    ReBuffer<DemodulatorThreadIQData> buffers;
    std::vector<liquid_float_complex> fpData;
    std::vector<liquid_float_complex> dataOut;
    
    iqDataInQueue->set_max_num_items(0);
    
    while (!terminated) {
        SDRThreadIQData *data_in;
        
        iqDataInQueue->pop(data_in);
        //        std::lock_guard < std::mutex > lock(data_in->m_mutex);
        
        if (data_in && data_in->data.size()) {
            int dataSize = data_in->data.size()/2;
            if (dataSize > fpData.capacity()) {
                fpData.reserve(dataSize);
                dataOut.reserve(dataSize);
            }
            if (dataSize != fpData.size()) {
                fpData.resize(dataSize);
                dataOut.resize(dataSize);
            }
            
            if (swapIQ) {
                for (int i = 0; i < dataSize; i++) {
                    fpData[i] = _lut_swap[*((uint16_t*)&data_in->data[2*i])];
                }
            } else {
                for (int i = 0; i < dataSize; i++) {
                    fpData[i] = _lut[*((uint16_t*)&data_in->data[2*i])];
                }
            }
            
            iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
            
            if (iqVisualQueue != NULL && !iqVisualQueue->full()) {
                DemodulatorThreadIQData *visualDataOut = visualDataBuffers.getBuffer();
                visualDataOut->setRefCount(1);
                
                int num_vis_samples = dataOut.size();

//                if (visualDataOut->data.size() < num_vis_samples) {
//                    if (visualDataOut->data.capacity() < num_vis_samples) {
//                        visualDataOut->data.reserve(num_vis_samples);
//                    }
//                    visualDataOut->data.resize(num_vis_samples);
//                }
//
                visualDataOut->frequency = data_in->frequency;
                visualDataOut->sampleRate = data_in->sampleRate;
                visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples);
                
                iqVisualQueue->push(visualDataOut);
            }
            
            busy_demod.lock();
            
            int activeDemods = 0;
            bool pushedData = false;
            
            if (demodulators.size() || iqDataOutQueue != NULL) {
                std::vector<DemodulatorInstance *>::iterator demod_i;
                for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
                    DemodulatorInstance *demod = *demod_i;
                    if (demod->getFrequency() != data_in->frequency
                        && abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
                        continue;
                    }
                    activeDemods++;
                }
                
                if (iqDataOutQueue != NULL) {
                    activeDemods++;
                }
                
                DemodulatorThreadIQData *demodDataOut = buffers.getBuffer();
                
                //                    std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
                demodDataOut->frequency = data_in->frequency;
                demodDataOut->sampleRate = data_in->sampleRate;
                demodDataOut->setRefCount(activeDemods);
                demodDataOut->data.assign(dataOut.begin(), dataOut.end());
                
                for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
                    DemodulatorInstance *demod = *demod_i;
                    DemodulatorThreadInputQueue *demodQueue = demod->getIQInputDataPipe();
                    
                    if (abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
                        if (demod->isActive() && !demod->isFollow() && !demod->isTracking()) {
                            demod->setActive(false);
                            DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData;
                            dummyDataOut->frequency = data_in->frequency;
                            dummyDataOut->sampleRate = data_in->sampleRate;
                            demodQueue->push(dummyDataOut);
                        }
                        
                        if (demod->isFollow() && wxGetApp().getFrequency() != demod->getFrequency()) {
                            wxGetApp().setFrequency(demod->getFrequency());
                        }
                    } else if (!demod->isActive()) {
                        demod->setActive(true);
                        if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == NULL) {
                            wxGetApp().getDemodMgr().setActiveDemodulator(demod);
                        }
                    }
                    
                    if (!demod->isActive()) {
                        continue;
                    }
                    if (demod->isFollow()) {
                        demod->setFollow(false);
                    }
                    
                    demodQueue->push(demodDataOut);
                    pushedData = true;
                }
                
                if (iqDataOutQueue != NULL) {
                    if (!iqDataOutQueue->full()) {
                        iqDataOutQueue->push(demodDataOut);
                        pushedData = true;
                    } else {
                        demodDataOut->decRefCount();
                    }
                }
                
                if (!pushedData && iqDataOutQueue == NULL) {
                    demodDataOut->setRefCount(0);
                }
            }
            
            busy_demod.unlock();
        }
        data_in->decRefCount();
    }

//    buffers.purge();
    
    if (iqVisualQueue && !iqVisualQueue->empty()) {
        DemodulatorThreadIQData *visualDataDummy;
        iqVisualQueue->pop(visualDataDummy);
    }

//    visualDataBuffers.purge();

    std::cout << "SDR post-processing thread done." << std::endl;
}
Esempio n. 15
0
bool CLASS::allocateSupportObjects( IOService * provider )
{
    fTransmitQueue = OSDynamicCast(IOOutputQueue, getOutputQueue());
    if (fTransmitQueue == 0)
        return false;

    fKDPQueue = IOPacketQueue::withCapacity(~0);
    if (!fKDPQueue)
        return false;

    // Allocate two Mbuf Cursors. One dedicated for transmit and
    // the other for receive. NOTE types are different.

    fRxMbufCursor = IOMbufLittleMemoryCursor::withSpecification(
                    kRxMaxBufferSize, 1);

    fTxMbufCursor = IOMbufNaturalMemoryCursor::withSpecification(
                    kTxMaxBufferSize, 1);

    if (!fRxMbufCursor || !fTxMbufCursor)
    {
        ERROR_LOG("%s: mbuf cursor allocation error\n", getName());
        return false;
    }

    IOWorkLoop * workLoop = (IOWorkLoop *) getWorkLoop();
    if (!workLoop)
    {
        ERROR_LOG("%s: no work loop\n", getName());
        return false;
    }

    // Create an interrupt event source to dispatch interrupts.
    // FIXME: Use interrupt filter event source

    fInterruptSource = IOInterruptEventSource::interruptEventSource(
                       this,
                       &AppleDP83816Ethernet::interruptHandler,
                       provider);

    if (!fInterruptSource ||
        (workLoop->addEventSource(fInterruptSource) != kIOReturnSuccess))
    {
        ERROR_LOG("%s: IOInterruptEventSource error\n", getName());
        return false;
    }

    fWatchdogTimer = IOTimerEventSource::timerEventSource(
                     this,
                     &AppleDP83816Ethernet::timeoutHandler);
    if (!fWatchdogTimer ||
        (workLoop->addEventSource(fWatchdogTimer) != kIOReturnSuccess))
    {
        ERROR_LOG("%s: IOTimerEventSource error\n", getName());
        return false;
    }

    // Very important. If the interrupt line is shared with other devices,
    // then the interrupt vector will be enabled only if all corresponding
    // interrupt event sources are enabled. To avoid masking interrupts for
    // other devices that are sharing the interrupt line, the event source
    // is enabled immediately.

    fInterruptSource->enable();

    return true;
}
Esempio n. 16
0
void DemodulatorWorkerThread::run() {

    std::cout << "Demodulator worker thread started.." << std::endl;
    
    commandQueue = (DemodulatorThreadWorkerCommandQueue *)getInputQueue("WorkerCommandQueue");
    resultQueue = (DemodulatorThreadWorkerResultQueue *)getOutputQueue("WorkerResultQueue");
    
    while (!terminated) {
        bool filterChanged = false;
        bool makeDemod = false;
        DemodulatorWorkerThreadCommand filterCommand, demodCommand;
        DemodulatorWorkerThreadCommand command;

        bool done = false;
        while (!done) {
            commandQueue->pop(command);
            switch (command.cmd) {
                case DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS:
                    filterChanged = true;
                    filterCommand = command;
                    break;
                case DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_MAKE_DEMOD:
                    makeDemod = true;
                    demodCommand = command;
                    break;
                default:
                    break;
            }
            done = commandQueue->empty();
        }

        if ((makeDemod || filterChanged) && !terminated) {
            DemodulatorWorkerThreadResult result(DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS);
            
            
            if (filterCommand.sampleRate) {
                result.sampleRate = filterCommand.sampleRate;
            }
            
            if (makeDemod) {
                cModem = Modem::makeModem(demodCommand.demodType);
                cModemName = cModem->getName();
                cModemType = cModem->getType();
                if (demodCommand.settings.size()) {
                    cModem->writeSettings(demodCommand.settings);
                }
                result.sampleRate = demodCommand.sampleRate;
                wxGetApp().getAppFrame()->updateModemProperties(cModem->getSettings());
            }
            result.modem = cModem;

            if (makeDemod && demodCommand.bandwidth && demodCommand.audioSampleRate) {
                if (cModem != nullptr) {
                    result.bandwidth = cModem->checkSampleRate(demodCommand.bandwidth, demodCommand.audioSampleRate);
                    cModemKit = cModem->buildKit(result.bandwidth, demodCommand.audioSampleRate);
                } else {
                    cModemKit = nullptr;
                }
            } else if (filterChanged && filterCommand.bandwidth && filterCommand.audioSampleRate) {
                if (cModem != nullptr) {
                    result.bandwidth = cModem->checkSampleRate(filterCommand.bandwidth, filterCommand.audioSampleRate);
                    cModemKit = cModem->buildKit(result.bandwidth, filterCommand.audioSampleRate);
                } else {
                    cModemKit = nullptr;
                }
            } else if (makeDemod) {
                cModemKit = nullptr;
            }
            if (cModem != nullptr) {
                cModem->clearRebuildKit();
            }
            
            float As = 60.0f;         // stop-band attenuation [dB]
            
            if (result.sampleRate && result.bandwidth) {
                result.bandwidth = cModem->checkSampleRate(result.bandwidth, makeDemod?demodCommand.audioSampleRate:filterCommand.audioSampleRate);
                result.iqResampleRatio = (double) (result.bandwidth) / (double) result.sampleRate;
                result.iqResampler = msresamp_crcf_create(result.iqResampleRatio, As);
            }

            result.modemKit = cModemKit;
            result.modemType = cModemType;
            result.modemName = cModemName;
            
            resultQueue->push(result);
        }

    }

    std::cout << "Demodulator worker thread done." << std::endl;
}
Esempio n. 17
0
void DemodulatorThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();  // ID of this thread
    int priority = sched_get_priority_max( SCHED_FIFO )-1;
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif
    
    ReBuffer<AudioThreadInput> audioVisBuffers;
    
    std::cout << "Demodulator thread started.." << std::endl;
    
    iqInputQueue = (DemodulatorThreadPostInputQueue*)getInputQueue("IQDataInput");
    audioOutputQueue = (AudioThreadInputQueue*)getOutputQueue("AudioDataOutput");
    threadQueueControl = (DemodulatorThreadControlCommandQueue *)getInputQueue("ControlQueue");
    threadQueueNotify = (DemodulatorThreadCommandQueue*)getOutputQueue("NotifyQueue");
    
    ModemIQData modemData;
    
    while (!terminated) {
        DemodulatorThreadPostIQData *inp;
        iqInputQueue->pop(inp);
        //        std::lock_guard < std::mutex > lock(inp->m_mutex);
        
        audioSampleRate = demodInstance->getAudioSampleRate();
        
        int bufSize = inp->data.size();
        
        if (!bufSize) {
            inp->decRefCount();
            continue;
        }
        
        if (inp->modemKit && inp->modemKit != cModemKit) {
            if (cModemKit != nullptr) {
                cModem->disposeKit(cModemKit);
            }
            cModemKit = inp->modemKit;
        }
        
        if (inp->modem && inp->modem != cModem) {
            delete cModem;
            cModem = inp->modem;
        }
        
        if (!cModem || !cModemKit) {
            inp->decRefCount();
            continue;
        }
        
        float currentSignalLevel = 0;
        float accum = 0;
        
        for (std::vector<liquid_float_complex>::iterator i = inp->data.begin(); i != inp->data.end(); i++) {
            accum += abMagnitude(0.948059448969, 0.392699081699, i->real, i->imag);
        }
        
        currentSignalLevel = linearToDb(accum / float(inp->data.size()));
        if (currentSignalLevel < DEMOD_SIGNAL_MIN+1) {
            currentSignalLevel = DEMOD_SIGNAL_MIN+1;
        }
        
        std::vector<liquid_float_complex> *inputData;
        
        inputData = &inp->data;
        
        modemData.sampleRate = inp->sampleRate;
        modemData.data.assign(inputData->begin(), inputData->end());
        modemData.setRefCount(1);
        
        AudioThreadInput *ati = NULL;
        
        ModemAnalog *modemAnalog = (cModem->getType() == "analog")?((ModemAnalog *)cModem):nullptr;
//        ModemDigital *modemDigital = (cModem->getType() == "digital")?((ModemDigital *)cModem):nullptr;
        
        if (modemAnalog != nullptr) {
            ati = outputBuffers.getBuffer();
            
            ati->sampleRate = audioSampleRate;
            ati->inputRate = inp->sampleRate;
            ati->setRefCount(1);
        }
        cModem->demodulate(cModemKit, &modemData, ati);
        
        if (currentSignalLevel > signalLevel) {
            signalLevel = signalLevel + (currentSignalLevel - signalLevel) * 0.5;
        } else {
            signalLevel = signalLevel + (currentSignalLevel - signalLevel) * 0.05;
        }
        
        bool squelched = (squelchEnabled && (signalLevel < squelchLevel));
        
        if (audioOutputQueue != NULL && ati && !squelched) {
            std::vector<float>::iterator data_i;
            ati->peak = 0;
            for (data_i = ati->data.begin(); data_i != ati->data.end(); data_i++) {
                float p = fabs(*data_i);
                if (p > ati->peak) {
                    ati->peak = p;
                }
            }
        } else if (ati) {
            ati->decRefCount();
            ati = nullptr;
        }
        
        if (ati && audioVisOutputQueue != NULL && audioVisOutputQueue->empty()) {
            AudioThreadInput *ati_vis = audioVisBuffers.getBuffer();
            ati_vis->setRefCount(1);
            ati_vis->sampleRate = inp->sampleRate;
            ati_vis->inputRate = inp->sampleRate;
            
            int num_vis = DEMOD_VIS_SIZE;
            if (ati->channels==2) {
                ati_vis->channels = 2;
                int stereoSize = ati->data.size();
                if (stereoSize > DEMOD_VIS_SIZE * 2) {
                    stereoSize = DEMOD_VIS_SIZE * 2;
                }
                
                ati_vis->data.resize(stereoSize);
                
                if (inp->modemType == "I/Q") {
                    for (int i = 0; i < stereoSize / 2; i++) {
                        ati_vis->data[i] = (*inputData)[i].real * 0.75;
                        ati_vis->data[i + stereoSize / 2] = (*inputData)[i].imag * 0.75;
                    }
                } else {
                    for (int i = 0; i < stereoSize / 2; i++) {
                        ati_vis->inputRate = audioSampleRate;
                        ati_vis->sampleRate = 36000;
                        ati_vis->data[i] = ati->data[i * 2];
                        ati_vis->data[i + stereoSize / 2] = ati->data[i * 2 + 1];
                    }
                }
            } else {
                int numAudioWritten = ati->data.size();
                ati_vis->channels = 1;
                std::vector<float> *demodOutData = (modemAnalog != nullptr)?modemAnalog->getDemodOutputData():nullptr;
                if ((numAudioWritten > bufSize) || (demodOutData == nullptr)) {
                    ati_vis->inputRate = audioSampleRate;
                    if (num_vis > numAudioWritten) {
                        num_vis = numAudioWritten;
                    }
                    ati_vis->data.assign(ati->data.begin(), ati->data.begin() + num_vis);
                } else {
                    if (num_vis > demodOutData->size()) {
                        num_vis = demodOutData->size();
                    }
                    ati_vis->data.assign(demodOutData->begin(), demodOutData->begin() + num_vis);
                }
                
            }
            
            audioVisOutputQueue->push(ati_vis);
        }
        
        
        if (ati != NULL) {
            if (!muted.load()) {
                audioOutputQueue->push(ati);
            } else {
                ati->setRefCount(0);
            }
        }
        
        if (!threadQueueControl->empty()) {
            while (!threadQueueControl->empty()) {
                DemodulatorThreadControlCommand command;
                threadQueueControl->pop(command);
                
                switch (command.cmd) {
                    case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_ON:
                        squelchEnabled = true;
                        break;
                    case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_OFF:
                        squelchEnabled = false;
                        break;
                    default:
                        break;
                }
            }
        }
        
        inp->decRefCount();
    }
    // end while !terminated
    
    outputBuffers.purge();
    
    if (audioVisOutputQueue && !audioVisOutputQueue->empty()) {
        AudioThreadInput *dummy_vis;
        audioVisOutputQueue->pop(dummy_vis);
    }
    audioVisBuffers.purge();
    
    DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED);
    tCmd.context = this;
    threadQueueNotify->push(tCmd);
    
    std::cout << "Demodulator thread done." << std::endl;
}
Esempio n. 18
0
bool
MolEnet::start( IOService * provider )
{
	IOPhysicalAddress tx_phys, rx_phys;
	IOPhysicalAddress tx_of_phys, rx_of_phys;
	int i, result;

	if( !super::start(provider) )
		return false;

	if( OSI_Enet2Open() ) {
		is_open = 1;
		return false;
	}
	
	//transmitQueue = OSDynamicCast( IOGatedOutputQueue, getOutputQueue() );
	transmitQueue = OSDynamicCast( IOBasicOutputQueue, getOutputQueue() );
	if( !transmitQueue ) {
		printm("MolEnet: output queue initialization failed\n");
		return false;
	}
	transmitQueue->retain();

	// Allocate a IOMbufBigMemoryCursor instance. Currently, the maximum
	// number of segments is set to 2. The maximum length for each segment
	// is set to the maximum ethernet frame size (plus padding).

	txMBufCursor = IOMbufBigMemoryCursor::withSpecification( NETWORK_BUFSIZE, 2 );
	rxMBufCursor = IOMbufBigMemoryCursor::withSpecification( NETWORK_BUFSIZE, 2 );
	if( !txMBufCursor || !rxMBufCursor ) {
		printm("MolEnet: IOMbufBigMemoryCursor allocation failure\n");
		return false;
	}

	// Get a reference to the IOWorkLoop in our superclass.
	IOWorkLoop * myWorkLoop = getWorkLoop();
	assert(myWorkLoop);

	// Allocate a IOInterruptEventSources.
	_irq = IOInterruptEventSource::interruptEventSource( this, 
				     (IOInterruptEventAction)&MolEnet::rxIRQ, provider, 0);
	
        if( !_irq || (myWorkLoop->addEventSource(_irq) != kIOReturnSuccess )) {
		printm("MolEnet: _irq init failure\n");
		return false;
	}

	// Allocate the ring descriptors
	rx_ring = (enet2_ring_t*)IOMallocContiguous( 2 * RX_NUM_EL * sizeof(enet2_ring_t), 
						     sizeof(enet2_ring_t), &rx_phys );
	tx_ring = (enet2_ring_t*)IOMallocContiguous( 2 * TX_NUM_EL * sizeof(enet2_ring_t),
						     sizeof(enet2_ring_t), &tx_phys );		
	if( !rx_ring || !tx_ring )
		return false;

	rx_of_ring = rx_ring + RX_NUM_EL;
	tx_of_ring = tx_ring + TX_NUM_EL;
	rx_of_phys = rx_phys + sizeof(enet2_ring_t) * RX_NUM_EL;
	tx_of_phys = tx_phys + sizeof(enet2_ring_t) * TX_NUM_EL;

	// Allocate receive buffers
	for( i=0; i<RX_NUM_EL; i++ ) {
		if( !(rxMBuf[i]=allocatePacket( NETWORK_BUFSIZE )) ) {
			printm("MolEnet: packet allocation failed\n");
			return false;
		}
		// reserve 2 bytes before the actual packet
		rxMBuf[i]->m_data += 2;
		rxMBuf[i]->m_len -= 2;
	}

	OSI_Enet2Cntrl( kEnet2Reset );
	result = OSI_Enet2RingSetup( kEnet2SetupRXRing, rx_phys, RX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupTXRing, tx_phys, TX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupRXOverflowRing, rx_of_phys, RX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupTXOverflowRing, tx_of_phys, TX_NUM_EL );
	if( result )
		return false;

	if( !resetAndEnable(false) )
		return false;

	// Create a table of supported media types.
	if( !createMediumTables() )
		return false;

	// Attach an IOEthernetInterface client.
	if( !attachInterface( (IONetworkInterface**)&networkInterface, false ) )
		return false;

	// Ready to service interface requests.
	networkInterface->registerService();

	printm("Ethernet driver 1.1\n");
	return true;
}