Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# AccessViolationException与声音缓冲区转换_C#_Type Conversion_Access Violation_Naudio_Asio - Fatal编程技术网

C# AccessViolationException与声音缓冲区转换

C# AccessViolationException与声音缓冲区转换,c#,type-conversion,access-violation,naudio,asio,C#,Type Conversion,Access Violation,Naudio,Asio,我正在使用Naudio AsioOut对象将数据从输入缓冲区传递到我的delayProc()函数,然后再传递到输出缓冲区 delayProc()需要float[]缓冲区类型,这可以使用e.GetAsInterleavedSamples()实现。问题是我需要将其重新转换为多维IntPtr,为此我使用asiosamplecovertor类 当我尝试应用该效果时,它显示了一个错误:AccessViolationException在AsioSampleConvertor类的代码上 因此,我认为问题在于从

我正在使用Naudio AsioOut对象将数据从输入缓冲区传递到我的
delayProc()
函数,然后再传递到输出缓冲区

delayProc()
需要
float[]
缓冲区类型,这可以使用
e.GetAsInterleavedSamples()
实现。问题是我需要将其重新转换为多维
IntPtr
,为此我使用
asiosamplecovertor

当我尝试应用该效果时,它显示了一个错误:AccessViolationException
AsioSampleConvertor
类的代码上

因此,我认为问题在于从
float[]
IntPtr[]
的转换

我给你一些代码:

OnAudioAvailable()

delayProc()

private float[]delayProc(float[]sourceBuffer,int sampleCount,float delay)
{
如果(OldBuf==null)
{
OldBuf=新浮点[采样计数];
}
float[]BufDly=新的float[(int)(采样计数*延迟)];
int delayLength=(int)(BufDly.Length-(BufDly.Length/delay));
for(int j=sampleCount-delayLength;j
亚洲采样转换器

public static void ConvertorFloatToInt2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
{
    unsafe
    {
        float* inputSamples = (float*)inputInterleavedBuffer;
        int* leftSamples = (int*)asioOutputBuffers[0];
        int* rightSamples = (int*)asioOutputBuffers[1];

        for (int i = 0; i < nbSamples; i++)
        {
            *leftSamples++ = clampToInt(inputSamples[0]);
            *rightSamples++ = clampToInt(inputSamples[1]);
            inputSamples += 2;
        }
    }
}
public static void convertor floatToInt2通道(IntPtr inputInterleavedBuffer,IntPtr[]asiooutputbuffer,intnbchannels,intnbsamples)
{
不安全的
{
float*inputSamples=(float*)inputInterleavedBuffer;
int*leftSamples=(int*)asioOutputBuffers[0];
int*rightSamples=(int*)asioOutputBuffers[1];
对于(int i=0;i
ClampToInt()

private static int clampToInt(双采样值)
{
sampleValue=(sampleValue<-1.0)?-1.0:(sampleValue>1.0)?1.0:sampleValue;
返回值(整数)(样本值*2147483647.0);
}

如果您需要其他代码,请询问。

当您调用
Convertor FloatToInt2通道时
您正在通过所有通道传入样本总数,然后尝试读取那么多对样本。因此,您试图从输入缓冲区中读取两倍于实际数量的样本。使用不安全代码,您试图解决的问题远远超过了分配的块的末尾,这会导致访问冲突

转换器floatToInt2通道
方法中的
for
循环更改为:

for (int i = 0; i < nbSamples; i += 2)
for(int i=0;i
这将阻止代码尝试读取源内存块中实际存在的项目数的两倍


顺便提一句,你为什么在这里胡乱分配全局内存和使用不安全的代码?为什么不将它们作为托管阵列处理?处理数据本身的速度不会慢很多,而且可以节省在非托管内存中复制数据的所有开销

试试这个:

public static void FloatMonoToIntStereo(float[] samples, float[] leftChannel, float[] rightChannel)
{
    for (int i = 0, j = 0; i < samples.Length; i += 2, j++)
    {
        leftChannel[j] = (int)(samples[i] * Int32.MaxValue);
        rightChannel[j] = (int)(samples[i + 1] * Int32.MaxValue);
    }
}
public static void FloatMonoToIntStereo(float[]示例,float[]左通道,float[]右通道)
{
对于(int i=0,j=0;i
在我的机器上,每秒处理约1200万个样本,将样本转换为整数并分割通道。如果我为每一组结果分配缓冲区,速度大约是这个速度的一半。当我写这篇文章是为了使用不安全的代码,
AllocHGlobal
等等时,大约又是一半


永远不要认为不安全的代码更快。

我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。
private static int clampToInt(double sampleValue)
{
    sampleValue = (sampleValue < -1.0) ? -1.0 : (sampleValue > 1.0) ? 1.0 : sampleValue;
    return (int)(sampleValue * 2147483647.0);
}
for (int i = 0; i < nbSamples; i += 2)
public static void FloatMonoToIntStereo(float[] samples, float[] leftChannel, float[] rightChannel)
{
    for (int i = 0, j = 0; i < samples.Length; i += 2, j++)
    {
        leftChannel[j] = (int)(samples[i] * Int32.MaxValue);
        rightChannel[j] = (int)(samples[i + 1] * Int32.MaxValue);
    }
}