void plVertCoder::IEncodeNormal(hsStream* S, const unsigned char*& src) { if (S->getVer().isLive()) { S->writeByte(FloatToByte(((((float*)src)[0] + 1.0f) / 2.0f) * 256.0f)); S->writeByte(FloatToByte(((((float*)src)[1] + 1.0f) / 2.0f) * 256.0f)); S->writeByte(FloatToByte(((((float*)src)[2] + 1.0f) / 2.0f) * 256.0f)); } else { S->writeShort(FloatToShort(((float*)src)[0] * 32767.0f)); S->writeShort(FloatToShort(((float*)src)[1] * 32767.0f)); S->writeShort(FloatToShort(((float*)src)[2] * 32767.0f)); } src += sizeof(float) * 3; }
void Sampler::_fillBuffer(float *s, unsigned int len, SRC_TYPE typ) { float * fb; if(len > bufferLen) SetBufferSize(len); usedBufferLen = len; fb = floatBuffer; len *= inChans; while(len--) *(fb++) = *(s++); if(needShort) FloatToShort(); }
static void ConvertFloatToInteger(void *outdata, float **pcm, int channels, size_t n) { size_t j; int i; SYS_ASSERT(outdata); for(i=0;i<channels;i++) { const float *mono = pcm[i]; ogg_int16_t *ptr = (ogg_int16_t *)outdata + i; for(j=0;j<n;j++,ptr+=channels,mono++) { *ptr = FloatToShort(*mono); } } }
bool tASPMaster::DataPacketReceived(const tASPInputParameters& inputParams, tReceivedSoundingInformation& info, tASPOutputData& ASPOutputData, bool sonarMaster, bool structureMaster, SonarCommon::eStructureTransducerType StructureXDCRType) { tSonarFrequencyAndChannel soundingFrequency = info.m_SonarInfo.m_SonarFrequency; //eSonarFrequency SonarFrequency = FrequencyHzToSonarFrequency(PingConfigUsed.m_Frequency_Hz); Assert(soundingFrequency.m_Frequency >= 0 && soundingFrequency.m_Frequency < eSonarFrequency_MaxNumLocalFrequencies); //eSonarChannel Channel = IsPrimaryFreq ? eSonarChannel_Primary : eSonarChannel_Secondary; bool Debug = false; float ChartFeetPerRangeCell = (info.m_SonarInfo.m_LowerLimit - info.m_SonarInfo.m_UpperLimit) / info.m_SonarInfo.m_ChartRangeCells.size(); float DigitalFeetPerRangeCell = info.m_SonarInfo.m_DigitalLimit / info.m_SonarInfo.m_DigitalRangeCells.size(); bool AutoDepthRange = m_ASPMasterSettings.m_AutoDepthRange; //DbgPrintf("Dsize=%i, Csize=%i", DigitalRangeCells.size(), ChartRangeCells.size()); eSonarChannel sonarChannel = info.m_SonarInfo.m_SonarChannel; if(sonarChannel >= eSonarChannel_NumChannels) sonarChannel = (eSonarChannel)(eSonarChannel_NumChannels - 1); if(sonarChannel < 0) sonarChannel = (eSonarChannel)0; tSonarFrequencyAndChannel desiredSonarFrequency; if(sonarChannel == eSonarChannel_Primary) desiredSonarFrequency = m_ASPMasterSettings.m_FrequencyIndex; else desiredSonarFrequency = m_ASPMasterSettings.m_AltFrequencyIndex; int customFreqHz = 0; if(desiredSonarFrequency.m_Frequency == eSonarFrequency_CustomDSP1) { if(sonarChannel == eSonarChannel_Primary) { customFreqHz = m_ASPMasterSettings.m_CustomFrequencyHz; } else { customFreqHz = m_ASPMasterSettings.m_AltCustomFrequencyHz; } } int IntegrationCycles = info.m_PingConfigUsed.m_IntegrationCycles; tHorizontalCorrelation::SmoothCompensationUgliness((unsigned char *)info.m_SonarInfo.m_ChartRangeCells.data(), info.m_SonarInfo.m_ChartRangeCells.size(), info.m_SonarInfo.m_ChartRangeCells[0], m_cReceiverA2DBits, m_cTotalReceiverDynamicRange_dB, IntegrationCycles); //~~~~~~~~~~~~~~ UMMM... what if we have 200kHz on two seperate channels or something??! ASPOutputData.m_AutosenseRangeCell = (tRangeCell)m_AutoSensitivity[soundingFrequency.m_Frequency].GetAutoSenseValue(); ASPOutputData.m_DigitalAutosenseRangeCell = (tRangeCell)m_AutoSensitivity[soundingFrequency.m_Frequency].GetDigitalAutoSenseValue(); eSonarFrequencyEnum frequency = soundingFrequency.m_Frequency; if( frequency == eSonarFrequency_CustomDSP1) { frequency = FrequencyHzToSonarFrequency(info.m_PingConfigUsed.m_Frequency_Hz); } int RVGValue = GetRVGValue(frequency, m_ASPMasterSettings.m_PrimaryLowerFt); bool sonarStopped = m_ASPMasterSettings.m_StopSonar; //DbgPrintf("SonarInfo: digitalLimit=%g, downLimit=%g", info.m_SonarInfo.m_DigitalLimit, info.m_SonarInfo.m_LowerLimit); bool DigitalColumnUsable = false; if(info.m_SonarInfo.m_DigitalLimit > 1 && sonarMaster && !sonarStopped) DigitalColumnUsable = true; bool ChartColumnUsable = false; if(info.m_SonarInfo.m_LowerLimit > 1 && sonarMaster) ChartColumnUsable = true; eSonarChannel channelUsedForDigital = sonarChannel; bool usingDownscanForDigital = false; if((!sonarMaster || sonarStopped) && structureMaster) channelUsedForDigital = eSonarChannel_Downscan; bool LastDepthValid = m_DepthValid[channelUsedForDigital]; if(DigitalColumnUsable) { //~~~~~~~~~~~~~~~~~~~ // Make digital smart enough to not use no burst length data...~~~~~~~~~~~ // Incorporate SS data here too... Might be present when sonar is not and might have data when sonar does not... //LastDepthValid = m_DepthValid[sonarChannel]; // Note - digital uses chart rangecells for debug only! m_DepthValid[sonarChannel] = m_DigitalDepth[sonarChannel].Scan( (tRangeCell *)info.m_SonarInfo.m_ChartRangeCells.data(), info.m_SonarInfo.m_ChartRangeCells.size(), ChartFeetPerRangeCell, info.m_SonarInfo.m_UpperLimit, info.m_SonarInfo.m_LowerLimit, soundingFrequency.m_Frequency, (const tRangeCell *)info.m_SonarInfo.m_DigitalRangeCells.constData(), DigitalFeetPerRangeCell, RVGValue, ASPOutputData.m_DigitalAutosenseRangeCell, m_SpeedKn, m_SpeedValid, (unsigned char)info.m_SonarInfo.m_ChartRangeCells.data()[0], Debug, SearchDepthLimit(soundingFrequency.m_Frequency), m_BottomDepth[sonarChannel], m_SurfaceDepth[sonarChannel], m_TopBottomDepth[sonarChannel] ); // TODO - If this depth is valid, lets setup the other digital classes with the same info... //DbgPrintf("----->Digital Limit:%f ",info.m_SonarInfo.m_DigitalLimit); //DbgPrintf("Freq %i, Depth=%g (%c)", sonarFrequency, BottomDepth, m_DepthValid[Channel] ? 'y' : 'n'); } else if(structureMaster && info.m_SonarInfo.m_DigitalLimit > 1) { tRangeCell structDownAutoSenseRangeCell = (tRangeCell)m_ASP2[info.m_StructureInfo.m_StructureDownFrequency.m_Frequency].StructureNoiseFloor(); //LastDepthValid = m_DepthValid[eSonarChannel_Downscan]; int structRVGValue = GetRVGValue(info.m_StructureInfo.m_StructureDownFrequency.m_Frequency, m_ASPMasterSettings.m_DownscanLowerFt); tRangeCellArray expandedDownRangeCells; expandedDownRangeCells.resize(tDigitalDepth::m_cDigitalDepthColumnHeight); // If the downscan chart column size is larger than the digital column size, then some assumptions // throughout the code have broken and we probably have a bigger problem than the digital depth not working. int DownScanDataSize = info.m_StructureInfo.m_DownRangecells.size(); Assert(DownScanDataSize <= tDigitalDepth::m_cDigitalDepthColumnHeight); if(DownScanDataSize > tDigitalDepth::m_cDigitalDepthColumnHeight) { DownScanDataSize = tDigitalDepth::m_cDigitalDepthColumnHeight; } memcpy(expandedDownRangeCells.data(), info.m_StructureInfo.m_DownRangecells.data(), DownScanDataSize); ExpandRangeCellsInPlace(expandedDownRangeCells.size(), DownScanDataSize,(tRangeCell *)expandedDownRangeCells.data()); float structDownFeetPerRangeCell = info.m_StructureInfo.m_DownRange / expandedDownRangeCells.size(); float structChartFeetPerRangeCell = info.m_StructureInfo.m_DownRange / info.m_StructureInfo.m_DownRangecells.size(); m_DepthValid[eSonarChannel_Downscan] = m_DigitalDepth[eSonarChannel_Downscan].Scan( (tRangeCell *)info.m_StructureInfo.m_DownRangecells.data(), info.m_StructureInfo.m_DownRangecells.size(), structChartFeetPerRangeCell, 0, info.m_StructureInfo.m_DownRange, info.m_StructureInfo.m_StructureDownFrequency.m_Frequency, (const tRangeCell *)expandedDownRangeCells.constData(), structDownFeetPerRangeCell, structRVGValue, structDownAutoSenseRangeCell, m_SpeedKn, m_SpeedValid, (unsigned char)info.m_StructureInfo.m_DownRangecells.data()[0], Debug, SearchDepthLimit(info.m_StructureInfo.m_StructureDownFrequency.m_Frequency), m_BottomDepth[eSonarChannel_Downscan], m_SurfaceDepth[eSonarChannel_Downscan], m_TopBottomDepth[eSonarChannel_Downscan] ); usingDownscanForDigital = true; int bottomIndex = FloatToLong(info.m_StructureInfo.m_DownRangecells.size() * (m_BottomDepth[eSonarChannel_Downscan] - 0) / (info.m_StructureInfo.m_DownRange - 0)); m_ASP2[info.m_StructureInfo.m_StructureDownFrequency.m_Frequency].CalculateStructureNoiseFloor(info.m_StructureInfo.m_DownRangecells, bottomIndex, info.m_StructureInfo.m_DownRange < 50); } eSonarASP NoiseRejection = static_cast<eSonarASP>(m_ASPMasterSettings.m_NoiseRejection); float visibleLowerLimit = 0; float searchDepth = 0; if(sonarMaster && !sonarStopped) { searchDepth = m_DigitalDepth[sonarChannel].GetSearchDepth(desiredSonarFrequency.m_Frequency, visibleLowerLimit, SearchDepthLimit(desiredSonarFrequency.m_Frequency)); switch(sonarChannel) { case eSonarChannel_Primary: visibleLowerLimit = m_ASPMasterSettings.m_PrimaryLowerFt; break; case eSonarChannel_Secondary: visibleLowerLimit = m_ASPMasterSettings.m_SecondaryLowerFt; break; default: Assert(false); break; } } else { tSonarFrequencyAndChannel desiredStructFrequency; if(sonarChannel == eSonarChannel_Primary) desiredStructFrequency = m_ASPMasterSettings.m_SidescanFrequencyIndex; searchDepth = m_DigitalDepth[eSonarChannel_Downscan].GetSearchDepth(desiredStructFrequency.m_Frequency, visibleLowerLimit, SearchDepthLimit(desiredStructFrequency.m_Frequency)); } if(visibleLowerLimit < 5) visibleLowerLimit = 5; float sideLimit = 0; float downLimit = 0; float downRange = 0; float sideRange = 0; if(info.m_StructureInfo.m_DownRangecells.size() > 0 && structureMaster && !m_ASPMasterSettings.m_SidescanStopSonar && StructureXDCRType != SonarCommon::eStrucTransducerType_Invalid) { downRange = m_ASPMasterSettings.m_DownscanLowerFt; downLimit = SonarCommon::ChartSideToSideLimit(downRange); if(StructureXDCRType != SonarCommon::eStrucTransducerType_DownOnly) { sideRange = m_ASPMasterSettings.m_SidescanLowerFt; sideLimit = SonarCommon::ChartSideToSideLimit(sideRange); } //DbgPrintf("Struct XID voltage = %i", info.m_StructureInfo.m_XIDVoltage100x); } bool DigitalSoundingOnly; float SampleLowerLimit; float Depth; int PingSpeed = m_ASPMasterSettings.m_PingSpeed; // The GetLimits call will modify this value if we're in search mode. Cache this locally for use below since m_ASPMasterSettings.m_PingSpeed can change async. from this call. m_PingLimitsSelector.GetLimits(ASPOutputData.m_DigitalLimit_ft, ASPOutputData.m_ChartLimit_ft, SampleLowerLimit, Depth, DigitalSoundingOnly, PingSpeed, downLimit, visibleLowerLimit, searchDepth, channelUsedForDigital, m_BottomDepth[channelUsedForDigital], m_DepthValid[channelUsedForDigital], m_DigitalDepth[channelUsedForDigital].IsSolidLock(), sideLimit, m_ASPMasterSettings.m_ChartManualMode, m_ASPMasterSettings.m_SidescanChartManualMode); float ChartRange = m_ASPMasterSettings.m_PrimaryLowerFt - m_ASPMasterSettings.m_PrimaryUpperFt; // 12/07/31 -- CGB: When sonar is not running we need to set the range to the down limit otherwise we could be setting the ping rate too large (NSW-11259). if((!sonarMaster || sonarStopped) && structureMaster) { ChartRange = downLimit; } tShortArray NoiseData; NoiseData.resize(info.m_SonarInfo.m_NoiseRangeCells.size() / 2); memcpy(NoiseData.data(), info.m_SonarInfo.m_NoiseRangeCells.constData(), info.m_SonarInfo.m_NoiseRangeCells.size()); int DigitalLine = m_DigitalDepth[sonarChannel].GetDigitalLine(); int SNR_dB = (DigitalLine - m_ASP2[soundingFrequency.m_Frequency].NoiseFloor()) * m_cTotalReceiverDynamicRange_dB / 255; if(!m_DepthValid[channelUsedForDigital]) { SNR_dB = 0; } bool limitGainClipDetect = (NoiseRejection == eSonarASP_Off) || m_ASPMasterSettings.m_ChartManualMode; int gain_dB = FloatToLong(info.m_PingConfigUsed.m_Gain_dB100x / 100.0F); int gainReductionFromMaxGain_dB = info.m_Hardware.m_MaxGain_dB - gain_dB; ASPOutputData.m_SideRange_ft = sideLimit; ASPOutputData.m_DownRange_ft = downLimit; //DbgPrintf("digitalLimit=%g, downLimit=%g", ASPOutputData.m_DigitalLimit_ft, downLimit); //~~~~~~~~~~~~~~ UMMM... what if we have 200kHz on two seperate channels or something??! ASPOutputData.m_SonarPingConfig = m_ASP2[desiredSonarFrequency.m_Frequency].SetupPing(inputParams, desiredSonarFrequency, !ChartColumnUsable, DigitalSoundingOnly, SampleLowerLimit, Depth, ChartRange, ASPOutputData.m_DigitalLimit_ft, PingSpeed, NoiseRejection, info.m_Debug, limitGainClipDetect, NoiseData, info.m_SonarInfo.m_ChartRangeCells, info.m_SonarInfo.m_UpperLimit, info.m_SonarInfo.m_LowerLimit, RVGValue, gainReductionFromMaxGain_dB, info.m_Hardware, m_SpeedKn, m_SpeedValid, SNR_dB, downLimit, sideLimit, downRange, sideRange, m_ASPMasterSettings.m_SidescanFrequencyIndex, m_DCOffset, customFreqHz, visibleLowerLimit, m_ASPMasterSettings.m_StopSonar, info.m_PingConfigUsed.m_CompensationOffset); // DbgPrintf("NoiseFloor=%i New=%i (LastAvg=%i)", m_ASP2[sonarFrequency].NoiseFloor(), NewAutoThreshold, ASPOutputData.m_AutosenseRangeCell); if(StructureXDCRType == SonarCommon::eStrucTransducerType_Invalid) { ASPOutputData.m_SonarPingConfig.m_StructureDownBurstLength_us = 0; ASPOutputData.m_SonarPingConfig.m_StructureSideBurstLength_us = 0; // Setting mimimum range, since a value of zero is discarded by CSM ASPOutputData.m_DownRange_ft = 5; ASPOutputData.m_SideRange_ft = 5; } else if(StructureXDCRType == SonarCommon::eStrucTransducerType_DownOnly) { ASPOutputData.m_SonarPingConfig.m_StructureSideBurstLength_us = 0; // Setting mimimum range, since a value of zero is discarded by CSM ASPOutputData.m_SideRange_ft = 5; } bool matchDownAndTraditionalAutorange = false; // AC~~~~~~~~~~ Move this somewhere else??? if(structureMaster) { if(m_ASPMasterSettings.m_SidescanAutoRange && sideRange > 0) { ASPOutputData.m_UpdateSidescanLowerFt_FromAutoRange = m_RangeSelector.SelectSidescanRange(info.m_StructureInfo.m_LeftRangecells, info.m_StructureInfo.m_RightRangecells, info.m_StructureInfo.m_SideRange, m_BottomDepth[channelUsedForDigital], m_DepthValid[channelUsedForDigital], m_ASPMasterSettings.m_SidescanLowerFt, ASPOutputData.m_SidescanLowerFt_FromAutoRange); } // Why do we want to check if the ChartColumn is usable for the downscan auto range and not for the conv. sonar? // the down chart is always usable when the conv. sonar data is used for the digital calculation if(((/*ChartColumnUsable &&*/ DigitalColumnUsable) || usingDownscanForDigital) && m_ASPMasterSettings.m_DownscanAutoRange && m_DepthValid[channelUsedForDigital]) { // Only auto range off the secondary frequency if the primary depth is invalid... if(sonarChannel == eSonarChannel_Primary || !m_DepthValid[eSonarChannel_Primary]) { // NSW-24479: Set flag to sync downscan range with traditional here, sync will be performed after traditional auto-range below, if traditional is not the server then it will not try to sync anyway matchDownAndTraditionalAutorange = true; if((sonarMaster == false) || ((sonarMaster == true) && (AutoDepthRange == false)) || (usingDownscanForDigital == true)) { ASPOutputData.m_UpdateDownscanLowerFt_FromAutoRange = m_RangeSelector.SelectDownscanRange(m_BottomDepth[channelUsedForDigital], m_ASPMasterSettings.m_DownscanLowerFt, ASPOutputData.m_DownscanLowerFt_FromAutoRange); } } } //else //{ // DbgPrintf("No conditions to do auto-downrange: ChartcolumnUsable=%i,DigitalColumnUsable=%i,UsingDownForDig=%i,AutoDepthRange=%i,DepthValid=%i", ChartColumnUsable ? 1 : 0, DigitalColumnUsable ? 1 : 0, usingDownscanForDigital ? 1 : 0, m_ASPMasterSettings.m_DownscanAutoRange() ? 1 : 0, m_DepthValid[channelUsedForDigital] ? 1: 0); //} } // Need to calculate SurfaceCellIndex before than AutoSense calculation..NSW-17342 float fIndex; if(ChartColumnUsable == true) { fIndex = (m_SurfaceDepth[sonarChannel] - info.m_SonarInfo.m_UpperLimit) / ChartFeetPerRangeCell; } else { fIndex = 0; } ASPOutputData.m_SurfaceCellIndex = FloatToShort(qBound<float>(SHRT_MIN, fIndex, SHRT_MAX)); ValidateAndLimitIntValue(ASPOutputData.m_SurfaceCellIndex, 0, info.m_SonarInfo.m_ChartRangeCells.size()); //~~~~~~~~~~~~~~ UMMM... what if we have 200kHz on two separate channels or something??! ASPOutputData.m_AutosenseRangeCell = (tRangeCell)m_AutoSensitivity[soundingFrequency.m_Frequency].CalculateAutoSense(m_ASP2[soundingFrequency.m_Frequency].NoiseFloor(), m_ASP2[soundingFrequency.m_Frequency].ShortTimeNoiseFloor() , RVGValue, desiredSonarFrequency.m_Frequency, DigitalLine, m_SpeedKn, m_SpeedValid, m_BottomDepth[sonarChannel], m_DepthValid[sonarChannel], m_cTotalReceiverDynamicRange_dB, ASPOutputData.m_SurfaceCellIndex, ChartRange); ASPOutputData.m_DigitalLine = (tRangeCell)m_DigitalDepth[sonarChannel].GetDigitalLine(); //*******************************************************************/ // Auto ranging code here //*******************************************************************/ ASPOutputData.m_UpdatePrimaryLowerFt_FromAutoRange = false; ASPOutputData.m_UpdateSecondaryLowerFt_FromAutoRange = false; if(sonarMaster) { if(DigitalColumnUsable && AutoDepthRange && m_DepthValid[sonarChannel]) { // Only auto range off the secondary frequency if the primary depth is invalid... if(sonarChannel == eSonarChannel_Primary || !m_DepthValid[eSonarChannel_Primary]) { // Autoranging off the primary channel. ASPOutputData.m_UpdatePrimaryLowerFt_FromAutoRange = m_RangeSelector.SelectSonarRange(m_BottomDepth[sonarChannel], m_ASPMasterSettings.m_PrimaryLowerFt, ASPOutputData.m_PrimaryLowerFt_FromAutoRange); ASPOutputData.m_UpdateSecondaryLowerFt_FromAutoRange = m_RangeSelector.SelectSonarRange(m_BottomDepth[sonarChannel], m_ASPMasterSettings.m_SecondaryLowerFt, ASPOutputData.m_SecondaryLowerFt_FromAutoRange); if(matchDownAndTraditionalAutorange == true) { float primaryLowerFt = m_ASPMasterSettings.m_PrimaryLowerFt; if(ASPOutputData.m_UpdatePrimaryLowerFt_FromAutoRange == true) { primaryLowerFt = ASPOutputData.m_PrimaryLowerFt_FromAutoRange; } // Need to match whatever the primary is or will be... ASPOutputData.m_UpdateDownscanLowerFt_FromAutoRange = m_RangeSelector.SelectDownscanRangeFromPrimaryAuto(primaryLowerFt, ASPOutputData.m_DownscanLowerFt_FromAutoRange); } if(ASPOutputData.m_UpdatePrimaryLowerFt_FromAutoRange && !LastDepthValid) { // AC - 2/16/2010 - If we are just locking on and range change, then // reset the ASP filters... for(int i = 0; i < eSonarFrequency_MaxNumLocalFrequencies; i++) { m_ASP2[i].ResetFilters(); } } } } } //ASPOutputData.m_SurfaceCellIndex = FloatToShort((m_SurfaceDepth[sonarChannel] - info.m_SonarInfo.m_UpperLimit) / ChartFeetPerRangeCell); ASPOutputData.m_TopBottomCellIndex = 0; //if(m_DepthValid[Channel]) { float fIndex = (m_TopBottomDepth[sonarChannel] - info.m_SonarInfo.m_UpperLimit) / ChartFeetPerRangeCell; ASPOutputData.m_TopBottomCellIndex = FloatToShort(qBound<float>(SHRT_MIN, fIndex, SHRT_MAX)); if(ASPOutputData.m_TopBottomCellIndex <= 0) ASPOutputData.m_TopBottomCellIndex = 1; //DbgPrintf("TopBottom=%i", ASPOutputData.m_TopBottomCellIndex); } if(ASPOutputData.m_TopBottomCellIndex >= info.m_SonarInfo.m_ChartRangeCells.size()) ASPOutputData.m_TopBottomCellIndex = info.m_SonarInfo.m_ChartRangeCells.size() - 1; if(ASPOutputData.m_SurfaceCellIndex < 0) ASPOutputData.m_SurfaceCellIndex = 0; if(ASPOutputData.m_SurfaceCellIndex > ASPOutputData.m_TopBottomCellIndex) ASPOutputData.m_SurfaceCellIndex = ASPOutputData.m_TopBottomCellIndex; //*******************************************************************/ // Fish ID called here //*******************************************************************/ if(ChartColumnUsable && channelUsedForDigital == sonarChannel) { if(m_DepthValid[sonarChannel]) { m_FishID[sonarChannel].Setup(ChartFeetPerRangeCell, info.m_SonarInfo.m_UpperLimit); tRangeCell FishSense = ASPOutputData.m_AutosenseRangeCell; if(FishSense + RVGValue < 255) FishSense = (tRangeCell)(FishSense + RVGValue); else FishSense = 255; m_FishID[sonarChannel].FindFish((const tRangeCell *)info.m_SonarInfo.m_ChartRangeCells.constData(), info.m_SonarInfo.m_ChartRangeCells.size(), FishSense, ASPOutputData.m_SurfaceCellIndex, ASPOutputData.m_TopBottomCellIndex, true); } } // Debug stuff... //~~~~~~~~~~~~~~ UMMM... what if we have 200kHz on two seperate channels or something??! ASPOutputData.m_AverageOutOfBandNoise = m_ASP2[desiredSonarFrequency.m_Frequency].GetAverageOutOfBandNoise(); ASPOutputData.m_InBandNoise = m_ASP2[desiredSonarFrequency.m_Frequency].GetInBandNoise(); ASPOutputData.m_PeakOutOfBandNoise = m_ASP2[desiredSonarFrequency.m_Frequency].GetPeakOutOfBandNoise(); ASPOutputData.m_PeakOutOfBandFrequencyAngle = m_ASP2[desiredSonarFrequency.m_Frequency].GetPeakOutOfBandFrequencyAngle(); ASPOutputData.m_PingAdder_ms = m_ASP2[desiredSonarFrequency.m_Frequency].GetPingAdder_ms(); Assert(info.m_SonarInfo.m_UpperLimit >= 0); Assert(info.m_SonarInfo.m_LowerLimit > info.m_SonarInfo.m_UpperLimit); if(/*usingDownscanForDigital*/channelUsedForDigital == eSonarChannel_Downscan && info.m_SonarInfo.m_LowerLimit > 1) ChartColumnUsable = true; return ChartColumnUsable; }