public override void Convert(AudioFrame inFrame, AudioFrame outFrame) { if (kernelCount > 1 && kernelCount != inFrame.format.Channels) { throw new ArgumentException($"{nameof(inFrame)}的数据行数和卷积核个数不一致", nameof(inFrame)); } var inFormat = inFrame.format; var inSamples = inFrame.sampleCount; var outSamples = convs[0].GetOutLength(inSamples); var outFormat = inFormat; if (resampler == null && inFormat.SampleFormat != AVSampleFormat.DoublePlanar) { outFormat = new AudioFormat(inFormat.SampleRate, inFormat.ChannelLayout, inFormat.SampleFormat.ToPlanar()); resampler = new AudioResampler(inFormat, outFormat); } if (resampler != null) { resampler.Resample(inFrame, tempInput); inFrame = tempInput; } outFrame.Resize(outFormat, outSamples); for (int i = 0; i < kernelCount; i++) { convs[kernelCount == 1 ? 0 : i].Convolve((double *)inFrame.datas[i], inSamples, (double *)outFrame.datas[i], outSamples); } }
public static void Merge(AudioFrame outFrame, params AudioFrame[] inFrames) { if (inFrames.Length == 0) { return; } var format = inFrames[0].format; for (int i = 1; i < inFrames.Length; i++) { if (format != inFrames[i].format) { throw new ArgumentException($"{nameof(inFrames)}的所有元素的{nameof(Format)}必须一致", nameof(inFrames)); } } int outSampleCount = inFrames.Sum(frame => frame.sampleCount); outFrame.format = format; outFrame.Resize(outSampleCount); int offset = 0; for (int i = 0; i < inFrames.Length; i++) { FF.av_samples_copy(outFrame.datas, inFrames[i].datas, offset, 0, inFrames[i].sampleCount, format.Channels, format.SampleFormat); offset += inFrames[i].sampleCount; } }
public static void ToPlanar(AudioFrame inOutFrame) { AudioResampler resampler = GetPlanarResampler(inOutFrame.format); if (resampler == null) { return; } var samples = inOutFrame.SampleCount; int bytes = resampler.GetOutBytes(samples); packedCache.Resize(bytes); var data = packedCache.data; Buffer.MemoryCopy((void *)inOutFrame.datas[0], (void *)data, bytes, bytes); int lineBytes = resampler.Destination.GetLineBytes(samples); inOutFrame.format = resampler.Destination; inOutFrame.Resize(samples); fixed(IntPtr *input = inOutFrame.datas) { resampler.Resample((IntPtr)(&data), samples, (IntPtr)input, samples); } inOutFrame.sampleCount = samples; }
public void CopyToNoResize(int srcSampleOffset, int srcSampleCount, AudioFrame dstFrame, int dstSampleOffset = 0) { if (dstFrame.format != format) { throw new ArgumentException("目标帧格式不一致", nameof(dstFrame)); } FF.av_samples_copy(dstFrame.datas, datas, dstSampleOffset, srcSampleOffset, srcSampleCount, format.Channels, format.SampleFormat); }
public void ResampleFinal(AudioFrame outFrame) { int outSamples = GetOutSampleCount(0); outFrame.format = Destination; outFrame.Resize(outSamples); outSamples = Resample(null, 0, outFrame.datas, outSamples); outFrame.sampleCount = outSamples; }
protected override void Dispose(bool disposing) { if (disposing) { delay?.Dispose(); newInFrame?.Dispose(); delay = null; newInFrame = null; } }
public override void Convert(AudioFrame inFrame, AudioFrame outFrame) { if (!inFrame.IsEmpty) { Resample(inFrame, outFrame); } else { ResampleFinal(outFrame); } }
protected override void Dispose(bool disposing) { if (disposing) { resampler?.Dispose(); resampler = null; tempFrame?.Dispose(); tempFrame = null; } base.Dispose(disposing); }
internal void InternalResample(AudioFrame frame) { int inSamples = frame.frame->NbSamples; int outSamples = GetOutSampleCount(inSamples); frame.format = Destination; frame.Resize(outSamples); fixed(IntPtr *output = frame.datas) { outSamples = Resample((IntPtr)frame.frame->ExtendedData, inSamples, (IntPtr)output, outSamples); } frame.sampleCount = outSamples; }
protected override void Dispose(bool disposing) { if (disposing) { resampler?.Dispose(); tempInput.Dispose(); if (convs != null) { Array.ForEach(convs, conv => conv.Dispose()); } resampler = null; tempInput = null; convs = null; } }
/* * [delay data], [in data] * ↓(merge) * [new in data(+new delay data)] * ↓(convert) * [out data] */ public sealed override void Convert(AudioFrame inFrame, AudioFrame outFrame) { if (delay == null) { delay = new AudioFrame(inFrame.format); } if (!delay.IsEmpty) { if (newInFrame == null) { newInFrame = new AudioFrame(); } AudioFrame.Merge(newInFrame, delay, inFrame); inFrame = newInFrame; } InternalConvert(inFrame, outFrame, out int delaySampleCount); delay.sampleCount = delaySampleCount; inFrame.CopyTo(inFrame.sampleCount - delaySampleCount, delaySampleCount, delay); }
public void Resample(AudioFrame inFrame, AudioFrame outFrame) { if (inFrame == null) { ResampleFinal(outFrame); return; } if (!Source.Equals(inFrame.format)) { throw new ArgumentException("输入帧的格式和重采样器的源格式不一致", nameof(inFrame)); } int inSamples = inFrame.SampleCount; int outSamples = GetOutSampleCount(inSamples); outFrame.format = Destination; outFrame.Resize(outSamples); outSamples = Resample(inFrame.datas, inSamples, outFrame.datas, outSamples); outFrame.sampleCount = outSamples; }
private void Init(AVCodecID codecID, BitRate bitRate) { outFormat = MatchSupportedFormat(codecID, InFormat); if (!InFormat.Equals(OutFormat)) { resampler = new AudioResampler(InFormat, OutFormat); tempFrame = new AudioFrame(); } codecContext->SampleFmt = outFormat.SampleFormat; codecContext->SampleRate = outFormat.SampleRate; codecContext->ChannelLayout = outFormat.ChannelLayout; codecContext->Channels = outFormat.Channels; codecContext->BitRate = bitRate.Value; var rates = codecContext->Flags; int result = FF.avcodec_open2(codecContext, codec, null); if (result < 0) { throw new FFmpegException(result); } }
public static void ToPacked(AudioFrame inOutFrame) { AudioResampler resampler = GetPackedResampler(inOutFrame.format); if (resampler == null) { return; } var samples = inOutFrame.SampleCount; int bytes = resampler.GetOutBytes(samples); packedCache.Resize(bytes); var data = packedCache.data; fixed(IntPtr *input = inOutFrame.datas) { resampler.Resample((IntPtr)input, samples, (IntPtr)(&data), samples); } inOutFrame.format = resampler.Destination; inOutFrame.Update(samples, packedCache.data); }
public abstract void Convert(AudioFrame inFrame, AudioFrame outFrame);
protected abstract void InternalConvert(AudioFrame inFrame, AudioFrame outFrame, out int delay);
public void CopyTo(int srcSampleOffset, int srcSampleCount, AudioFrame dstFrame) { dstFrame.Resize(format, srcSampleCount); FF.av_samples_copy(dstFrame.datas, datas, 0, srcSampleOffset, srcSampleCount, format.Channels, format.SampleFormat); }