Прокрутка формы сигнала

#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 ниже), но это для другого вопроса.

введите описание изображения здесь