#c# #unity3d #audio #waveform
Вопрос:
У меня есть визуализатор формы волны, который я пытаюсь сделать для некоторого редактирования звука, и мне нужно иметь возможность прокручивать форму волны. Код, который я в настоящее время использую, взят из этого вопроса и работает после того, как я внес некоторые изменения, позволяющие указать время начала и окончания звука:
public Texture2D PaintWaveformSpectrum(AudioClip audio, int textWidth, int textHeight, int audioStart, int audioEnd, Color col) {
Texture2D tex = new Texture2D(textWidth, textHeight, TextureFormat.RGBA32, false);
float[] samples = new float[audioLength];
float[] waveform = new float[textWidth];
audio.GetData(samples, 0);
int packSize = ((audioEnd - audioStart) / textWidth) 1;
if (audioStart != 0) {
audioStart = packSize % audioStart;
}
int s = 0;
for (int i = audioStart; i < audioEnd; i = packSize) {
waveform[s] = Mathf.Abs(samples[i]);
s ;
}
for (int x = 0; x < textWidth; x ) {
for (int y = 0; y < textHeight; y ) {
tex.SetPixel(x, y, Color.gray);
}
}
for (int x = 0; x < waveform.Length; x ) {
for (int y = 0; y <= waveform[x] * ((float)textHeight * .75f); y ) {
tex.SetPixel(x, (textHeight / 2) y, col);
tex.SetPixel(x, (textHeight / 2) - y, col);
}
}
tex.Apply();
return tex;
}
Однако проблема здесь в том, что, когда я прокручиваю звук, форма сигнала меняется. Он действительно прокручивается, но проблема в том, что теперь он показывает разные значения в форме сигнала. Это связано с тем, что выборок значительно больше, чем пикселей, поэтому необходимо уменьшить выборку. На данный момент выбран каждый n-й образец, но проблема в другой начальной точке, будут выбраны разные образцы. Изображения ниже для сравнения (дополнительно, вот видео. Вот как я хочу, чтобы свиток выглядел):
Как вы можете видеть, они немного отличаются. Общая структура есть, но форма волны в конечном счете отличается.
Я думал, что это будет легко исправить — сдвинуть начальное значение звука до ближайшего packSize
(т. Е. audioStart = packSize % audioStart
Когда audioStart != 0
), но это не сработало. Все та же проблема все еще имела место.
Если у кого-нибудь есть какие-либо предложения о том, как я могу поддерживать согласованность формы сигнала при прокрутке, я был бы очень признателен.
Ответ №1:
Несмотря на многолетний опыт программирования, я все еще не могу правильно округлить число. Все было так просто.
Линия
if (audioStart != 0) {
audioStart = packSize % audioStart;
}
должно быть
audioStart = (int) Mathf.Round(audioStart / packSize) * packSize;
Также необходимо добавить 1 дополнительный байт waveform
, так как в половине случаев округление приведет к включению одного дополнительного образца. Как таковой, waveform
следует определить как:
float[] waveform = new float[textWidth 1];
Это решает проблему, и образцы выбираются последовательно. Я не совсем уверен, как таким программам, как audacity, удается получать красивые формы сигналов, которые не являются очень шумными (сравнение ниже для той же песни: моя сверху, audacity ниже), но это для другого вопроса.