2015-04-30 2 views
1

Я пытаюсь создать аудио визуализатор в движке Unity с помощью C#.Копирование значений из структуры происходит медленно?

Я также использую плагин FMOD, который имеет функции для извлечения звукового спектра воспроизводимого звука (например, громкости звука на разных частотах).

FMOD возвращает эти данные как структуру, содержащую зубчатый массив, причем первый массив является звуковым каналом (0 = слева, 1 = справа), а второй массив является томами для каждого частотного диапазона, являющимся значением поплавка между 0 и 1.

Мне нужно скопировать значения в этих массивах в свои собственные массивы с целью изменения и отображения данных. Я в настоящее время использую для цикла перебора массива и присвоить значения из левых и правых каналов на новые массивы, а также другой массив, который находит средний объем:

private int SAMPLE_SIZE = 512; 
private float[] spectrumLeft; 
private float[] spectrumRight; 
public float[] spectrumTotal; 

void Start() { 
    spectrumLeft = new float[SAMPLE_SIZE]; 
    spectrumRight = new float[SAMPLE_SIZE]; 
    spectrumTotal = new float[SAMPLE_SIZE]; 
} 

void Update() { 
    System.IntPtr data; 
    uint length; 
    result = spectrumFilter.getParameterData ((int)FMOD.DSP_FFT.SPECTRUMDATA, out data, out length); 
    FMOD.DSP_PARAMETER_FFT spectrumBuffer = new FMOD.DSP_PARAMETER_FFT(); 
    spectrumBuffer = (FMOD.DSP_PARAMETER_FFT) Marshal.PtrToStructure(data,typeof (FMOD.DSP_PARAMETER_FFT)); 

    for (int i = 0; i < SAMPLE_SIZE; i++) { 
     spectrumLeft[i] = spectrumBuffer.spectrum[0][i]; 
     spectrumRight[i] = spectrumBuffer.spectrum[1][i]; 
     spectrumTotal[i] = (spectrumLeft[i] + spectrumRight[i])/2f; 
    } 
} 

проблема: код запуск в for-loop выше невероятно медленный (он максимизирует мое ядро ​​процессора и заставляет программу работать медленно, когда я комментирую содержимое цикла, использование ЦП ниже 1%).

Поскольку FMOD возвращает данные в виде структуры в этом формате, я не могу изменить способ получения данных.

Есть ли лучший/более быстрый способ извлечения значений из структуры?

Обратите внимание, что я относительно новым для C#, и я могу отсутствовать что-то очевидное

+1

Без [хорошего, _minimal_, _complete_ кода примера] (http://stackoverflow.com/help/mcve), который надежно воспроизводит проблему, было бы трудно, если не невозможно, узнать, где ваше узкое место точно. Но первые две вещи, которые я постараюсь: используйте ['Buffer.BlockCopy()'] (https://msdn.microsoft.com/en-us/library/vstudio/system.buffer.blockcopy (v = vs.110) .aspx), чтобы скопировать данные в каждый из массивов 'spectrumLeft' и' spectrumRight' и посмотреть, имеет ли значение простое выражение 'spectrumTotal'. –

+0

http://stackoverflow.com/a/5099642/312725 это может помочь вам с копированием массива. По сути, это то же самое, что сказал @PeterDuniho, но объяснил подробно. –

+0

@PeterDuniho Я уверен, что это узкое место, я пробовал комментировать каждую из функций цикла for и даже заменять их другими функциями, и ничто не вызывает даже заметного попадания в производительность. Также по какой-либо причине Unity не имеет класса Buffer, поэтому я не могу использовать Buffer.BlockCopy() – SJTho

ответ

0

Хорошо, очень просто исправить я проглядел:

private int SAMPLE_SIZE = 512; 
private float[][] spectrum; 
public float[] spectrumTotal; 

void Start() { 
    spectrum = new float[2][]; 
    spectrum[0] = new float[SAMPLE_SIZE]; 
    spectrum[1] = new float[SAMPLE_SIZE]; 
    spectrumTotal = new float[SAMPLE_SIZE]; 
} 

void Update() { 
    System.IntPtr data; 
    uint length; 
    result = spectrumFilter.getParameterData ((int)FMOD.DSP_FFT.SPECTRUMDATA, out data, out length); 
    FMOD.DSP_PARAMETER_FFT spectrumBuffer = new FMOD.DSP_PARAMETER_FFT(); 
    spectrumBuffer = (FMOD.DSP_PARAMETER_FFT) Marshal.PtrToStructure(data,typeof (FMOD.DSP_PARAMETER_FFT)); 

    spectrum = spectrumBuffer.spectrum; 

    for (int i = 0; i < SAMPLE_SIZE; i++) { 
     spectrumTotal[i] = (spectrum[0][i] + spectrum[1][i])/2f; 
    } 
} 

Вместо перебора всего массива и назначения каждое значение один за другим, я просто объявил свой собственный зубчатый массив с тем же размером, что и тот, что был в структуре, и скопировал его за один раз. Затем я смогу прокрутить их и найти средний объем.

Однако меня все еще интересует, почему требуется столько времени, чтобы получить значение из массива в структуре, по сравнению с другим локальным массивом. Сделаем еще несколько исследований.

Глупые ошибки теперь, когда я вижу это, но спасибо, был поражен тем, как быстро люди опубликовали полезные ответы.

Смежные вопросы