Сопоставьте данные аудиоклипа с пикселями массива из GetRawTextureData?

#c# #unity3d #textures #render-to-texture

Вопрос:

GetRawTextureData() возвращает линейный (одномерный) массив всех пикселей в текстуре.

Аудиоклипы содержат чередующиеся (слева и справа) данные в одномерном массиве, так что индексы представляют x (или время), и каждое значение является либо громкостью левого и правого сигнала в этот x/время. Четные числа = слева и нечетные = справа.

Есть ли простой способ отобразить это в NativeArray, который возвращается из GetRawTextureData()

То, что я пробовал, фокусируется только на показе левого сигнала, но дает странные вертикальные результаты:

 void FillTextureOne (Texture2D wav_tex, float[] firstWave ) {
    var texdata = wav_tex.GetRawTextureData<Color32>( );
    for ( int i = 0; i < firstWave.Length ; i =2 )
    {
        var positionnew =  i/2 * 256    ( firstWave[i]   1 ) * 128 ;
        texdata[( int )positionnew ] = black;
    }
    wav_tex.Apply( );
}
 

размер текстуры 256 x 256. Массив данных аудиоклипа имеет длину 512, в котором хранятся значения в диапазоне от -1 до 1, и умножаются на 128 после добавления единицы в неудачной попытке расположить их в диапазоне от 0 до 256 по вертикали.

Комментарии:

1. Я не знаю, как это работает, но x (ширина y *) определяет местоположение.

Ответ №1:

Если я понимаю решение, которое вас смущает, вот краткое объяснение того, почему оно работает. Чтобы правильно отобразить 2D — массив в 1D-массив, вам нужно будет взять width и height из 2D-массива, а затем взять их продукт, чтобы получить правильный размер вашего 1D-массива. Следующий шаг-убедиться, что ваш 2D-массив находится в том, в row order or column order котором будет решаться, как вы получаете доступ к своей информации. Как только это будет выяснено, существуют два уравнения, которые позволят вам получить доступ к 1D-массиву в формате 2D-массива, используя его ширину и высоту, а не сингулярный индекс. Для простоты я буду использовать ваши индексаторы x и y снова вместе с width И. height

Для Массивов Порядка Строк

 yourOneDimensionalArray[width * x   y]
 

Для Массивов Порядка Столбцов

 yourOneDimensionalArray[height * y   x]
 

Подумайте о 1D-массиве как о потенциальном 2D-массиве, если разбить его на равные части. В зависимости от порядка вашей матрицы, она будет определять длину строки или столбца в зависимости от того, насколько велик разрыв или сколько частей вы можете разделить.

Более наглядное объяснение:

 1 2 3 4 5 6 7 8 9 is a 1D array of size 1x9

1 2 3
4 5 6 is a 2D array row order of size 3x3
7 8 9

1 4 7 
2 5 8 is a 2D array column order of size 3x3
3 6 9

If we want to access the number 6 in these arrays, we would do as follows:
1DArray[5]
2DRowArray[1][2]
2DColumnArray[2][1]

From the previous equations, we can now take the indexes we have to see how they relate.

2DRowArray is row 1, column 2 or x = 1, y = 2 and our width is 3, so we take 1 * 3   2, which is 3   2 = 5 or our 1D index

Similarly, the 2DColumnArray is row 2, column 1 or x = 2, y = 1 and our height is 3, so we take 1 * 3   2, which is 3   2 = 5 or our 1D index.
 

Я мог бы расширить это визуальное решение до 256x256 сетки, но я думаю 3x3 , что идея должна быть понятна так же хорошо. Дайте мне знать, если у вас все еще есть вопросы.

Комментарии:

1. работает ли y * ширина x только для меня, потому что сетка квадратная?

2. @В замешательстве Нет! Вы также можете сопоставить неквадратичный 2D — массив с 1D-массивом. В моем примере просто уберите нижнюю строку, и способ найти 6 все равно приведет к тому же ответу. Аналогично, уберите последний столбец в матрице столбцов, и вы получите тот же ответ.

3. Думайте об этом как о здании, и вы пытаетесь найти комнату на определенном этаже из лифта — Комната X на этаже Y, это 2D массив. Теперь представьте, что все эти многоэтажные этажи превратились в одно длинное здание. Вместо того, чтобы подниматься на Y этажей, теперь вы просто пройдете по Y этажам, а затем все равно найдете свой X. Однако, поскольку сейчас этажей нет, но вы знаете предыдущую высоту и какой этаж вы хотели, вы все равно можете найти точный X или нужную вам комнату, взяв высоту * Y X.

4. Извините, я хотел спросить вот что: вы предлагаете ширину * x или высоту * y, но у меня работает ширина y*. Если моя текстура не квадратная (например, 256 x 90), я думаю, что она не должна работать так, как я это делаю.

5. Не хотел тебя смущать. Причина, по которой существует два уравнения, зависит от того, как упакован 2D-массив. Я считаю, что большинство 2D-массивов имеют порядок строк, так что да, текущее уравнение, с которым вы работаете, скорее всего, не будет работать с неквадратичным, используя функцию, которую вы используете. Чтобы быть уверенным, если вы сможете передать неквадратную текстуру и посмотреть, выйдет ли она за рамки, вы узнаете.

Ответ №2:

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

Комментарии:

1. Это рассчитанные синусоидальные, пилообразные, треугольные и квадратные волны, которые рисуются в виде выборок до 1024 индексированных выборок каждая, до или после использования функцией Unity «OnAudioFilterRead». Есть ли способ выполнить все эти вычисления кривой в виде вычислительных шейдеров И эффективно получить конечные массивы OnAudioFilterRead ??

2. Да, все это можно сделать с помощью вычислительных шейдеров.

3. Я не вижу , как можно эффективно выполнить конечную кривую для процессора и оперативной OnAudioFilterRead памяти, начиная с вычислений. Это обратная проблема здесь, где есть blit для GPU, через Apply — что в данном случае довольно эффективно, потому что это делается один раз для всех изменений.