Я никогда не использовал указатели раньше, и теперь мне нужно, и хотя я их прочитал, я до сих пор не знаю, как их использовать! Я использую сторонний продукт (Mitov Signal Lab), и я использую элемент управления, в котором есть событие, которое позволит мне перехватить данные. Когда я вхожу в событие, у меня есть доступ к «args», и один из операторов возвращает указатель. Теперь это указывает на буфер из 4096 двойных значений (один - действительное число, а следующее - воображаемое число и т. Д.). Так что это код:C# указатели на указатели
private void genericComplex1_ProcessData(object Sender, Mitov.SignalLab.ProcessComplexNotifyArgs Args)
{
unsafe
{
IntPtr pointer = Args.InBuffer.Read();
// now what???? I want to get each double value, do some calculations on them
// and return them to the buffer.
}
args.sendOutPutData = true;
}
Я предполагаю, что мне нужно присвоить указатель на Args.InBuffer.Read() Но я попробовал несколько примеров, я видел, и я просто получаю ошибки. Я использую visual studio 2010, и я компилирую с/unsafe. Вот обновление. Существуют дополнительные методы, такие как Args.Inbuffer.Write() и Args.Inbuffer.Modify(), но я до сих пор не могу понять, как обращаться к отдельным компонентам буфера.
Хорошо, вот подробности. Я использовал Marshall.copy. Вот код:
private void genericComplex1_ProcessData(object Sender, Mitov.SignalLab.ProcessComplexNotifyArgs Args)
{
//used to generate a phase corrected Q signal
//equations:
// real = real
// imaginary = (1 + amplitudeimbalance)(real*cos(phaseImbalance) + imaginary*sin(phaseImbalance)
//but amplitude imbalance is already corrected therefore
//imaginary = real * cos(phaseCorrection) + imaginary*sin(phaseCorrection)
double real;
double imaginary;
double newImaginary;
var bufferSize = Convert.ToInt32(Args.InBuffer.GetSize());
Mitov.SignalLab.ComplexBuffer ComplexDataBuffer = new Mitov.SignalLab.ComplexBuffer(bufferSize);
ComplexDataBuffer.Zero();
IntPtr pointer = Args.InBuffer.Read();
IntPtr pointer2 = ComplexDataBuffer.Write();
var data = new double[8192];
Marshal.Copy(pointer, data, 0, 8192);
for (int i = 0; i < 8192; i+=2)
{
data[i] = data[i];
data[i + 1] = data[i] * Math.Cos(phaseCorrection) + data[i+1] * Math.Sin(phaseCorrection);
}
Marshal.Copy(data, 0, pointer2, 8192);
Args.SendOutputData = false;
genericComplex1.SendData(ComplexDataBuffer);
}
Теперь это не работает. Причина в том, что это занимает слишком много времени. Я отбираю звук со звуковой карты со скоростью 192 000 выборок в секунду. Событие выше срабатывает каждый раз, когда имеется доступный буфер 4096. Таким образом, каждые 20 миллисекунд поступает новый буфер. Затем этот буфер отправляется в процедуру быстрого преобразования Фурье, которая создает график силы сигнала по частоте. Мнимые данные фактически совпадают с реальными данными, но сдвинуты по фазе на 90 градусов. Так оно и есть в совершенном мире. Однако фаза никогда не бывает на 90 градусов из-за дисбаланса в сигнале, разных электронных дорожек, разного кода и т. Д. Таким образом, необходим поправочный коэффициент, и это то, что делают уравнения. Теперь, если я заменю
data[i] = data[i];
data[i + 1] = data[i] * Math.Cos(phaseCorrection) + data[i+1] * Math.Sin(phaseCorrection);
с
data[i] = data[i];
data[i+1] = data[i+1];
он работает нормально.
Так что мне понадобятся указатели. Но будет ли это значительно быстрее или функции sin и cosine просто затянутся слишком долго? Cn Я отправляю данные непосредственно на процессор (теперь это становится небезопасным!).
Этот метод 'Read' действительно возвращает' IntPtr' или указатель, потому что это не одно и то же? – jmcilhinney
Привет, Да, это IntPtr – Tom
@ Посмотрите мой обновленный ответ на аспекты производительности. –