void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { Complex ci; qint16 sample; Real a, b, s, demod; double meansqr = 1.0; for(SampleVector::const_iterator it = begin; it < end; ++it) { Complex c(it->real() / 32768.0, it->imag() / 32768.0); c *= m_nco.nextIQ(); if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) { s = ci.real() * ci.real() + ci.imag() * ci.imag(); meansqr += s; m_movingAverage.feed(s); if(m_movingAverage.average() >= m_squelchLevel) m_squelchState = m_sampleRate / 50; a = m_scale * m_this.real() * (m_last.imag() - ci.imag()); b = m_scale * m_this.imag() * (m_last.real() - ci.real()); m_last = m_this; m_this = Complex(ci.real(), ci.imag()); demod = m_volume * m_lowpass.filter(b - a); sample = demod * 30000; // Display audio spectrum to 12kHz if (++m_framedrop & 1) m_sampleBuffer.push_back(Sample(sample, sample)); if(m_squelchState > 0) m_squelchState--; else sample = 0; { m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; ++m_audioBufferFill; if(m_audioBufferFill >= m_audioBuffer.size()) { uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); if(res != m_audioBufferFill) qDebug("lost %u samples", m_audioBufferFill - res); m_audioBufferFill = 0; } } m_sampleDistanceRemain += (Real)m_sampleRate / 48000.0; } } if(m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) ;//qDebug("lost samples"); m_audioBufferFill = 0; if(m_sampleSink != NULL) m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), true); m_sampleBuffer.clear(); // TODO: correct levels m_scale = ( end - begin) * m_sampleRate / 48000 / meansqr; }
bool ScopeVis::triggerCondition(SampleVector::const_iterator& it) { Complex c(it->real()/32768.0f, it->imag()/32768.0f); m_traceback.push_back(c); // store into trace memory FIFO if (m_tracebackCount < m_traceback.size()) { // increment count up to trace memory size m_tracebackCount++; } if (m_triggerChannel[m_triggerIndex] == TriggerChannelI) { return c.real() > m_triggerLevel[m_triggerIndex]; } else if (m_triggerChannel[m_triggerIndex] == TriggerChannelQ) { return c.imag() > m_triggerLevel[m_triggerIndex]; } else if (m_triggerChannel[m_triggerIndex] == TriggerMagLin) { return abs(c) > m_triggerLevel[m_triggerIndex]; } else if (m_triggerChannel[m_triggerIndex] == TriggerMagDb) { Real mult = (10.0f / log2f(10.0f)); Real v = c.real() * c.real() + c.imag() * c.imag(); return mult * log2f(v) > m_triggerLevel[m_triggerIndex]; } else if (m_triggerChannel[m_triggerIndex] == TriggerPhase) { return arg(c) / M_PI > m_triggerLevel[m_triggerIndex]; } else if (m_triggerChannel[m_triggerIndex] == TriggerDPhase) { Real curArg = arg(c) - m_prevArg; m_prevArg = arg(c); if (curArg < -M_PI) { curArg += 2.0 * M_PI; } else if (curArg > M_PI) { curArg -= 2.0 * M_PI; } if (m_firstArg) { m_firstArg = false; return false; } else { return curArg / M_PI > m_triggerLevel[m_triggerIndex]; } } else { return false; } }
void WFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { qint16 sample; Real x, y, demod; for(SampleVector::const_iterator it = begin; it < end; ++it) { x = it->real() * m_last.real() + it->imag() * m_last.imag(); y = it->real() * m_last.imag() - it->imag() * m_last.real(); m_last = Complex(it->real(), it->imag()); demod = atan2(y, x); Complex e(demod, 0); Complex c; if(m_interpolator.interpolate(&m_sampleDistanceRemain, e, &c)) { sample = (qint16)(c.real() * 100 * m_volume * m_volume); m_sampleBuffer.push_back(Sample(sample, sample)); m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; ++m_audioBufferFill; if(m_audioBufferFill >= m_audioBuffer.size()) { uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); if(res != m_audioBufferFill) qDebug("lost %u samples", m_audioBufferFill - res); m_audioBufferFill = 0; } m_sampleDistanceRemain += (Real)m_sampleRate / 48000.0; } } if(m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) qDebug("lost samples"); m_audioBufferFill = 0; if(m_sampleSink != NULL) m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), true); m_sampleBuffer.clear(); }
void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { Complex ci; cmplx* sideband; Real l, r; m_sampleBuffer.clear(); // Rtl-Sdr uses full 16-bit scale; FCDPP does not int rescale = 30000 * (1 << m_boost); for(SampleVector::const_iterator it = begin; it < end; ++it) { Complex c(it->real() / 32768.0, it->imag() / 32768.0); c *= m_nco.nextIQ(); if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) { m_sampleBuffer.push_back(Sample(ci.real() * rescale, ci.imag() * rescale)); m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate; } } if((m_spectrum != NULL) && (m_spectrumEnabled)) m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), positiveOnly); for(int i = 0; i < m_s16leSockets.count(); i++) m_s16leSockets[i].socket->write((const char*)&m_sampleBuffer[0], m_sampleBuffer.size() * 4); if((m_sampleFormat == FormatSSB) && (m_ssbSockets.count() > 0)) { for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) { Complex cj(it->real() / 30000.0, it->imag() / 30000.0); int n_out = TCPFilter->runSSB(cj, &sideband, true); if (n_out) { for (int i = 0; i < n_out; i+=2) { l = (sideband[i].real() + sideband[i].imag()) * 0.7 * 32000.0; r = (sideband[i+1].real() + sideband[i+1].imag()) * 0.7 * 32000.0; m_sampleBufferSSB.push_back(Sample(l, r)); } for(int i = 0; i < m_ssbSockets.count(); i++) m_ssbSockets[i].socket->write((const char*)&m_sampleBufferSSB[0], n_out * 2); m_sampleBufferSSB.clear(); } } } if((m_sampleFormat == FormatNFM) && (m_ssbSockets.count() > 0)) { for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) { Complex cj(it->real() / 30000.0, it->imag() / 30000.0); // An FFT filter here is overkill, but was already set up for SSB int n_out = TCPFilter->runFilt(cj, &sideband); if (n_out) { Real sum = 1.0; for (int i = 0; i < n_out; i+=2) { l = m_this.real() * (m_last.imag() - sideband[i].imag()) - m_this.imag() * (m_last.real() - sideband[i].real()); m_last = sideband[i]; r = m_last.real() * (m_this.imag() - sideband[i+1].imag()) - m_last.imag() * (m_this.real() - sideband[i+1].real()); m_this = sideband[i+1]; m_sampleBufferSSB.push_back(Sample(l * m_scale, r * m_scale)); sum += m_this.real() * m_this.real() + m_this.imag() * m_this.imag(); } // TODO: correct levels m_scale = 24000 * tcpFftLen / sum; for(int i = 0; i < m_ssbSockets.count(); i++) m_ssbSockets[i].socket->write((const char*)&m_sampleBufferSSB[0], n_out * 2); m_sampleBufferSSB.clear(); } } } }
void ScopeVis::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst) { while(begin < end) { if(m_triggerChannel == TriggerChannelI) { if(m_triggerState == Untriggered) { while(begin < end) { if(begin->real() >= m_triggerLevelHigh) { m_triggerState = Triggered; break; } ++begin; } } if(m_triggerState == Triggered) { int count = end - begin; if(count > (int)(m_trace.size() - m_fill)) count = m_trace.size() - m_fill; std::vector<Complex>::iterator it = m_trace.begin() + m_fill; for(int i = 0; i < count; ++i) { *it++ = Complex(begin->real() / 32768.0, begin->imag() / 32768.0); ++begin; } m_fill += count; if(m_fill >= m_trace.size()) { m_glScope->newTrace(m_trace, m_sampleRate); m_fill = 0; m_triggerState = WaitForReset; } } if(m_triggerState == WaitForReset) { while(begin < end) { if(begin->real() < m_triggerLevelLow) { m_triggerState = Untriggered; break; } ++begin; } } } else if(m_triggerChannel == TriggerChannelQ) { if(m_triggerState == Untriggered) { while(begin < end) { if(begin->imag() >= m_triggerLevelHigh) { m_triggerState = Triggered; break; } ++begin; } } if(m_triggerState == Triggered) { int count = end - begin; if(count > (int)(m_trace.size() - m_fill)) count = m_trace.size() - m_fill; std::vector<Complex>::iterator it = m_trace.begin() + m_fill; for(int i = 0; i < count; ++i) { *it++ = Complex(begin->real() / 32768.0, begin->imag() / 32768.0); ++begin; } m_fill += count; if(m_fill >= m_trace.size()) { m_glScope->newTrace(m_trace, m_sampleRate); m_fill = 0; m_triggerState = WaitForReset; } } if(m_triggerState == WaitForReset) { while(begin < end) { if(begin->imag() < m_triggerLevelLow) { m_triggerState = Untriggered; break; } ++begin; } } } else { int count = end - begin; if(count > (int)(m_trace.size() - m_fill)) count = m_trace.size() - m_fill; std::vector<Complex>::iterator it = m_trace.begin() + m_fill; for(int i = 0; i < count; ++i) { *it++ = Complex(begin->real() / 32768.0, begin->imag() / 32768.0); ++begin; } m_fill += count; if(m_fill >= m_trace.size()) { m_glScope->newTrace(m_trace, m_sampleRate); m_fill = 0; } } } }
void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { Complex ci; int samplesPerSymbol = m_dsdDecoder.getSamplesPerSymbol(); m_settingsMutex.lock(); m_scopeSampleBuffer.clear(); m_dsdDecoder.enableMbelib(!DSPEngine::instance()->hasDVSerialSupport()); // disable mbelib if DV serial support is present and activated else enable it for (SampleVector::const_iterator it = begin; it != end; ++it) { Complex c(it->real(), it->imag()); c *= m_nco.nextIQ(); if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) { qint16 sample, delayedSample; Real magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())) / (1<<30); m_movingAverage.feed(magsq); m_magsqSum += magsq; if (magsq > m_magsqPeak) { m_magsqPeak = magsq; } m_magsqCount++; Real demod = 32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * ((float) m_running.m_demodGain / 100.0f); m_sampleCount++; // AF processing if (m_movingAverage.average() > m_squelchLevel) { if (m_squelchGate > 0) { if (m_squelchCount < m_squelchGate) { m_squelchCount++; } m_squelchOpen = m_squelchCount == m_squelchGate; } else { m_squelchOpen = true; } } else { m_squelchCount = 0; m_squelchOpen = false; } if (m_squelchOpen) { sample = demod; } else { sample = 0; } m_dsdDecoder.pushSample(sample); if (m_running.m_enableCosineFiltering) { // show actual input to FSK demod sample = m_dsdDecoder.getFilteredSample(); } if (m_sampleBufferIndex < (1<<17)) { m_sampleBufferIndex++; } else { m_sampleBufferIndex = 0; } m_sampleBuffer[m_sampleBufferIndex] = sample; if (m_sampleBufferIndex < samplesPerSymbol) { delayedSample = m_sampleBuffer[(1<<17) - samplesPerSymbol + m_sampleBufferIndex]; // wrap } else { delayedSample = m_sampleBuffer[m_sampleBufferIndex - samplesPerSymbol]; } if (m_running.m_syncOrConstellation) { Sample s(sample, m_dsdDecoder.getSymbolSyncSample()); m_scopeSampleBuffer.push_back(s); } else { Sample s(sample, delayedSample); // I=signal, Q=signal delayed by 20 samples (2400 baud: lowest rate) m_scopeSampleBuffer.push_back(s); } if (DSPEngine::instance()->hasDVSerialSupport()) { if ((m_running.m_slot1On) && m_dsdDecoder.mbeDVReady1()) { if (!m_running.m_audioMute) { DSPEngine::instance()->pushMbeFrame( m_dsdDecoder.getMbeDVFrame1(), m_dsdDecoder.getMbeRateIndex(), m_running.m_volume, m_running.m_tdmaStereo ? 1 : 3, // left or both channels &m_audioFifo1); } m_dsdDecoder.resetMbeDV1(); } if ((m_running.m_slot2On) && m_dsdDecoder.mbeDVReady2()) { if (!m_running.m_audioMute) { DSPEngine::instance()->pushMbeFrame( m_dsdDecoder.getMbeDVFrame2(), m_dsdDecoder.getMbeRateIndex(), m_running.m_volume, m_running.m_tdmaStereo ? 2 : 3, // right or both channels &m_audioFifo2); } m_dsdDecoder.resetMbeDV2(); } } // if (DSPEngine::instance()->hasDVSerialSupport() && m_dsdDecoder.mbeDVReady1()) // { // if (!m_running.m_audioMute) // { // DSPEngine::instance()->pushMbeFrame(m_dsdDecoder.getMbeDVFrame1(), m_dsdDecoder.getMbeRateIndex(), m_running.m_volume, &m_audioFifo1); // } // // m_dsdDecoder.resetMbeDV1(); // } m_interpolatorDistanceRemain += m_interpolatorDistance; } } if (!DSPEngine::instance()->hasDVSerialSupport()) { if (m_running.m_slot1On) { int nbAudioSamples; short *dsdAudio = m_dsdDecoder.getAudio1(nbAudioSamples); if (nbAudioSamples > 0) { if (!m_running.m_audioMute) { uint res = m_audioFifo1.write((const quint8*) dsdAudio, nbAudioSamples, 10); } m_dsdDecoder.resetAudio1(); } } if (m_running.m_slot2On) { int nbAudioSamples; short *dsdAudio = m_dsdDecoder.getAudio2(nbAudioSamples); if (nbAudioSamples > 0) { if (!m_running.m_audioMute) { uint res = m_audioFifo2.write((const quint8*) dsdAudio, nbAudioSamples, 10); } m_dsdDecoder.resetAudio2(); } } // int nbAudioSamples; // short *dsdAudio = m_dsdDecoder.getAudio1(nbAudioSamples); // // if (nbAudioSamples > 0) // { // if (!m_running.m_audioMute) { // uint res = m_audioFifo1.write((const quint8*) dsdAudio, nbAudioSamples, 10); // } // // m_dsdDecoder.resetAudio1(); // } } if ((m_scope != 0) && (m_scopeEnabled)) { m_scope->feed(m_scopeSampleBuffer.begin(), m_scopeSampleBuffer.end(), true); // true = real samples for what it's worth } m_settingsMutex.unlock(); }
void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { Complex ci; m_settingsMutex.lock(); for (SampleVector::const_iterator it = begin; it != end; ++it) { //Complex c(it->real() / 32768.0f, it->imag() / 32768.0f); Complex c(it->real(), it->imag()); c *= m_nco.nextIQ(); { if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) { qint16 sample; m_AGC.feed(ci); double magsqRaw = m_AGC.getMagSq(); Real magsq = magsqRaw / (1<<30); m_movingAverage.feed(magsq); m_magsqSum += magsq; if (magsq > m_magsqPeak) { m_magsqPeak = magsq; } m_magsqCount++; Real demod = m_phaseDiscri.phaseDiscriminator2(ci); //m_m2Sample = m_m1Sample; //m_m1Sample = ci; m_sampleCount++; // AF processing if (m_movingAverage.average() > m_squelchLevel) { if (m_squelchCount < m_squelchGate) { m_squelchCount++; } } else { m_squelchCount = 0; } //squelchOpen = (getMag() > m_squelchLevel); m_squelchOpen = m_squelchCount == m_squelchGate; // wait for AGC to stabilize /* if (m_afSquelch.analyze(demod)) { squelchOpen = m_afSquelch.evaluate(); }*/ if ((m_squelchOpen) && !m_running.m_audioMute) //if (m_AGC.getAverage() > m_squelchLevel) { if (m_running.m_ctcssOn) { Real ctcss_sample = m_lowpass.filter(demod); if ((m_sampleCount & 7) == 7) // decimate 48k -> 6k { if (m_ctcssDetector.analyze(&ctcss_sample)) { int maxToneIndex; if (m_ctcssDetector.getDetectedTone(maxToneIndex)) { if (maxToneIndex+1 != m_ctcssIndex) { m_nfmDemodGUI->setCtcssFreq(m_ctcssDetector.getToneSet()[maxToneIndex]); m_ctcssIndex = maxToneIndex+1; } } else { if (m_ctcssIndex != 0) { m_nfmDemodGUI->setCtcssFreq(0); m_ctcssIndex = 0; } } } } } if (m_running.m_ctcssOn && m_ctcssIndexSelected && (m_ctcssIndexSelected != m_ctcssIndex)) { sample = 0; } else { demod = m_bandpass.filter(demod); sample = demod * m_running.m_volume; } } else { if (m_ctcssIndex != 0) { m_nfmDemodGUI->setCtcssFreq(0); m_ctcssIndex = 0; } sample = 0; } m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; ++m_audioBufferFill; if (m_audioBufferFill >= m_audioBuffer.size()) { uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 10); if (res != m_audioBufferFill) { qDebug("NFMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill); } m_audioBufferFill = 0; } m_interpolatorDistanceRemain += m_interpolatorDistance; } } } if (m_audioBufferFill > 0) { uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 10); if (res != m_audioBufferFill) { qDebug("NFMDemod::feed: %u/%u tail samples written", res, m_audioBufferFill); } m_audioBufferFill = 0; } m_settingsMutex.unlock(); }
void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { (void) firstOfBurst; Complex ci; int samplesPerSymbol = m_dsdDecoder.getSamplesPerSymbol(); m_settingsMutex.lock(); m_scopeSampleBuffer.clear(); m_dsdDecoder.enableMbelib(!DSPEngine::instance()->hasDVSerialSupport()); // disable mbelib if DV serial support is present and activated else enable it for (SampleVector::const_iterator it = begin; it != end; ++it) { Complex c(it->real(), it->imag()); c *= m_nco.nextIQ(); if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) { FixReal sample, delayedSample; qint16 sampleDSD; Real re = ci.real() / SDR_RX_SCALED; Real im = ci.imag() / SDR_RX_SCALED; Real magsq = re*re + im*im; m_movingAverage(magsq); m_magsqSum += magsq; if (magsq > m_magsqPeak) { m_magsqPeak = magsq; } m_magsqCount++; Real demod = m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_demodGain; // [-1.0:1.0] m_sampleCount++; // AF processing if (m_movingAverage.asDouble() > m_squelchLevel) { if (m_squelchGate > 0) { if (m_squelchCount < m_squelchGate*2) { m_squelchCount++; } m_squelchDelayLine.write(demod); m_squelchOpen = m_squelchCount > m_squelchGate; } else { m_squelchOpen = true; } } else { if (m_squelchGate > 0) { if (m_squelchCount > 0) { m_squelchCount--; } m_squelchDelayLine.write(0); m_squelchOpen = m_squelchCount > m_squelchGate; } else { m_squelchOpen = false; } } if (m_squelchOpen) { if (m_squelchGate > 0) { sampleDSD = m_squelchDelayLine.readBack(m_squelchGate) * 32768.0f; // DSD decoder takes int16 samples sample = m_squelchDelayLine.readBack(m_squelchGate) * SDR_RX_SCALEF; // scale to sample size } else { sampleDSD = demod * 32768.0f; // DSD decoder takes int16 samples sample = demod * SDR_RX_SCALEF; // scale to sample size } } else { sampleDSD = 0; sample = 0; } m_dsdDecoder.pushSample(sampleDSD); if (m_settings.m_enableCosineFiltering) { // show actual input to FSK demod sample = m_dsdDecoder.getFilteredSample() * m_scaleFromShort; } if (m_sampleBufferIndex < (1<<17)-1) { m_sampleBufferIndex++; } else { m_sampleBufferIndex = 0; } m_sampleBuffer[m_sampleBufferIndex] = sample; if (m_sampleBufferIndex < samplesPerSymbol) { delayedSample = m_sampleBuffer[(1<<17) - samplesPerSymbol + m_sampleBufferIndex]; // wrap } else { delayedSample = m_sampleBuffer[m_sampleBufferIndex - samplesPerSymbol]; } if (m_settings.m_syncOrConstellation) { Sample s(sample, m_dsdDecoder.getSymbolSyncSample() * m_scaleFromShort * 0.84); m_scopeSampleBuffer.push_back(s); } else { Sample s(sample, delayedSample); // I=signal, Q=signal delayed by 20 samples (2400 baud: lowest rate) m_scopeSampleBuffer.push_back(s); } if (DSPEngine::instance()->hasDVSerialSupport()) { if ((m_settings.m_slot1On) && m_dsdDecoder.mbeDVReady1()) { if (!m_settings.m_audioMute) { DSPEngine::instance()->pushMbeFrame( m_dsdDecoder.getMbeDVFrame1(), m_dsdDecoder.getMbeRateIndex(), m_settings.m_volume * 10.0, m_settings.m_tdmaStereo ? 1 : 3, // left or both channels m_settings.m_highPassFilter, m_audioSampleRate/8000, // upsample from native 8k &m_audioFifo1); } m_dsdDecoder.resetMbeDV1(); } if ((m_settings.m_slot2On) && m_dsdDecoder.mbeDVReady2()) { if (!m_settings.m_audioMute) { DSPEngine::instance()->pushMbeFrame( m_dsdDecoder.getMbeDVFrame2(), m_dsdDecoder.getMbeRateIndex(), m_settings.m_volume * 10.0, m_settings.m_tdmaStereo ? 2 : 3, // right or both channels m_settings.m_highPassFilter, m_audioSampleRate/8000, // upsample from native 8k &m_audioFifo2); } m_dsdDecoder.resetMbeDV2(); } } // if (DSPEngine::instance()->hasDVSerialSupport() && m_dsdDecoder.mbeDVReady1()) // { // if (!m_settings.m_audioMute) // { // DSPEngine::instance()->pushMbeFrame(m_dsdDecoder.getMbeDVFrame1(), m_dsdDecoder.getMbeRateIndex(), m_settings.m_volume, &m_audioFifo1); // } // // m_dsdDecoder.resetMbeDV1(); // } m_interpolatorDistanceRemain += m_interpolatorDistance; } } if (!DSPEngine::instance()->hasDVSerialSupport()) { if (m_settings.m_slot1On) { int nbAudioSamples; short *dsdAudio = m_dsdDecoder.getAudio1(nbAudioSamples); if (nbAudioSamples > 0) { if (!m_settings.m_audioMute) { m_audioFifo1.write((const quint8*) dsdAudio, nbAudioSamples); } m_dsdDecoder.resetAudio1(); } } if (m_settings.m_slot2On) { int nbAudioSamples; short *dsdAudio = m_dsdDecoder.getAudio2(nbAudioSamples); if (nbAudioSamples > 0) { if (!m_settings.m_audioMute) { m_audioFifo2.write((const quint8*) dsdAudio, nbAudioSamples); } m_dsdDecoder.resetAudio2(); } } // int nbAudioSamples; // short *dsdAudio = m_dsdDecoder.getAudio1(nbAudioSamples); // // if (nbAudioSamples > 0) // { // if (!m_settings.m_audioMute) { // uint res = m_audioFifo1.write((const quint8*) dsdAudio, nbAudioSamples, 10); // } // // m_dsdDecoder.resetAudio1(); // } } if ((m_scopeXY != 0) && (m_scopeEnabled)) { m_scopeXY->feed(m_scopeSampleBuffer.begin(), m_scopeSampleBuffer.end(), true); // true = real samples for what it's worth } m_settingsMutex.unlock(); }