/// <summary> /// 重采样--指针 /// </summary> /// <param name="channelDataSegment">重采样数据段信息</param> private void PrimitiveResample(ChannelDataSegment channelDataSegment) { try { int sample = channelDataSegment.Sample; int length = channelDataSegment.EndIndex - channelDataSegment.BegeinIndex; int segmentTargetCount = length / sample; if (length % sample != 0) { segmentTargetCount += 1; } segmentTargetCount = segmentTargetCount * 2; short[] result = new short[segmentTargetCount]; short[] srcData = channelDataSegment.SrcData; if (length <= segmentTargetCount) { if (length != result.Length) { result = new short[length]; } Array.Copy(srcData, channelDataSegment.BegeinIndex, result, 0, result.Length); } else { short lMaxValue, lMinValue; short tmpValue; int position = 0; int i, innerEndIndex; int endIndex = channelDataSegment.EndIndex; int currentEndIndex; if (channelDataSegment.Flag) { currentEndIndex = endIndex - sample; } else { currentEndIndex = endIndex; } for (i = channelDataSegment.BegeinIndex; i < currentEndIndex; i += sample) { innerEndIndex = i + sample; lMaxValue = srcData[i]; lMinValue = lMaxValue; for (int j = i + 1; j < innerEndIndex; j++) { tmpValue = srcData[j]; if (tmpValue > lMaxValue) { lMaxValue = tmpValue; } else if (tmpValue < lMinValue) { lMinValue = tmpValue; } } result[position] = lMinValue; result[position + 1] = lMaxValue; position += 2; } if (channelDataSegment.Flag) { //最后 一次 innerEndIndex = i; if (innerEndIndex > endIndex) { innerEndIndex = endIndex; } i -= sample; position -= 2; lMaxValue = srcData[i]; lMinValue = lMaxValue; for (int j = i + 1; j < innerEndIndex; j++) { tmpValue = srcData[j]; if (tmpValue > lMaxValue) { lMaxValue = tmpValue; } else if (tmpValue < lMinValue) { lMinValue = tmpValue; } } if (position >= 0) { result[position] = lMinValue; result[position + 1] = lMaxValue; } } } channelDataSegment.Result = result; } catch (Exception ex) { Loger.Error(ex); } }
/// <summary> /// 对声道FFT数据进行重采样 /// </summary> /// <param name="targetCount">目标数据个数</param> /// <param name="begeinIndex">原始数据起始索引</param> /// <param name="endIndex">原始数据结束索引</param> /// <returns>FFT中最大值</returns> internal short[] PrimitiveResample(int targetCount, int begeinIndex, int endIndex) { if (this._pcmData == null || targetCount >= this._pcmData.Length) { return(this._pcmData); } int srcCount = endIndex - begeinIndex;//原始数据个数 if (srcCount <= 0) { return(new short[0]); } int sampleCount; //采样数据个数 bool addinFlag = targetCount > srcCount; //是否需要重采样添加数据 if (addinFlag) { sampleCount = (int)srcCount; } else { sampleCount = targetCount; } int sampleSegmentCount = sampleCount / 2; //采样段数,因为是一段数据中取出最大值和最小值,所以目标点数除以2 if (sampleCount % 2 != 0) //如果目标数据个数为奇数,则采样个数+1 { sampleSegmentCount++; } short[] result; int reSample = srcCount / sampleSegmentCount; //采样率 if (reSample == 0) //如果采样率为0,则总的数据个数少于目标个数,则直接将原始数据拷贝到目标数组 { result = new short[sampleCount]; Array.Copy(this._pcmData, begeinIndex, result, 0, result.Length); return(result); } if (srcCount % sampleSegmentCount != 0) { reSample++; } int processorCount = Environment.ProcessorCount; //CPU核心数 int coreSampleSegmentCount = sampleSegmentCount / processorCount; //每一核分配到的采样段个数 if (sampleSegmentCount % processorCount != 0) { coreSampleSegmentCount++; } //计算数据段大小 int segDataSize = coreSampleSegmentCount * reSample;//采样数据段大小 //拆分数据段 List <ChannelDataSegment> segments = new List <ChannelDataSegment>(); int startIndex = begeinIndex; for (int i = 0; i < processorCount; i++) { ChannelDataSegment channelDataSegment = new ChannelDataSegment(); channelDataSegment.SrcData = this._pcmData; channelDataSegment.Sample = reSample; //计算索引位置 channelDataSegment.BegeinIndex = startIndex; channelDataSegment.EndIndex = startIndex + segDataSize; if (channelDataSegment.EndIndex > endIndex) { channelDataSegment.Flag = true; channelDataSegment.EndIndex = endIndex; } else { channelDataSegment.Flag = false; } segments.Add(channelDataSegment); //更新起始索引位置 startIndex = channelDataSegment.EndIndex; } //并行处理 Parallel.ForEach(segments, this.PrimitiveResample); //foreach (var segment in segments) //{ // this.RepeatSample(segment); //} //拼接数据 var resultLength = segments.Sum((item) => { return(item.Result.Length); }); result = new short[resultLength]; int dstIndex = 0; foreach (var segment in segments) { Array.Copy(segment.Result, 0, result, dstIndex, segment.Result.Length); dstIndex += segment.Result.Length; } return(result); }