Показать аудио сигнал и масштаб - PullRequest
0 голосов
/ 04 января 2011

Я могу отображать сигнал, но не знаю, как реализовать увеличение сигнала.Есть идеи?

Спасибо piccolo

Ответы [ 2 ]

0 голосов
/ 15 февраля 2012

Работая над этим прямо сейчас, c # с небольшим linq, но должно быть достаточно легко читать и понимать.Идея здесь состоит в том, чтобы иметь массив значений с плавающей запятой от -1 до 1, представляющих амплитуду для каждого семпла в файле WAV.Затем, зная, сколько выборок в секунду, нам нужен коэффициент масштабирования - сегменты в секунду.На этом этапе вы просто уменьшаете точки данных и сглаживаете их.чтобы действительно увеличить масштаб, дайте образцы в секунду из 1000, чтобы уменьшить масштаб, возможно, 5-10.Обратите внимание, что сейчас я просто делаю нормальное усреднение, где это должно быть обновлено, чтобы быть намного более эффективным и, вероятно, использовать среднеквадратичное (среднеквадратичное) усреднение, чтобы сделать его идеальным.

private List<float> BuildAverageSegments(float[] aryRawValues, int iSamplesPerSecond, int iSegmentsPerSecond)
            {
                double nDurationInSeconds = aryRawValues.Length/(double) iSamplesPerSecond;
                int iNumSegments = (int)Math.Round(iSegmentsPerSecond*nDurationInSeconds);
                int iSamplesPerSegment = (int) Math.Round(aryRawValues.Length/(double) iNumSegments); // total number of samples divided by the total number of segments
                List<float> colAvgSegVals = new List<float>();

                for(int i=0; i<iNumSegments-1; i++)
                {
                    int iStartIndex = i * iSamplesPerSegment;
                    int iEndIndex = (i + 1) * iSamplesPerSegment;
                    float fAverageSegVal = aryRawValues.Skip(iStartIndex).Take(iEndIndex - iStartIndex).Average();
                    colAvgSegVals.Add(fAverageSegVal);
                }

                return colAvgSegVals;
            }

Вне этого выВам нужно получить аудио в формате WAV, вы должны быть в состоянии найти источник повсюду, чтобы прочитать эти данные, а затем использовать что-то вроде этого для преобразования необработанных байтовых данных в число с плавающей точкой - опять-таки это ужасно грубо и неэффективно, но ясно

 public float[] GetFloatData()
        {
            //Scale Factor - SignificantBitsPerSample
            if (Data != null && Data.Length > 0)
            {
                float nMaxValue = (float) Math.Pow((double) 2, SignificantBitsPerSample);
                float[] aryFloats = new float[Data[0].Length];

                for (int i = 0; i < Data[0].Length; i++ )
                {
                    aryFloats[i] = Data[0][i]/nMaxValue;
                }
                return aryFloats;
            }
            else
            {
                return null;
            }
        } 
0 голосов
/ 04 января 2011

Под масштабом я полагаю, вы имеете в виду горизонтальное увеличение, а не вертикальное.Аудио редакторы делают это, сканируя wavform, разбивая его на временные окна, где каждый пиксель в X представляет некоторое количество выборок.Это может быть дробное число, но вы можете избежать использования дробных коэффициентов масштабирования, не слишком раздражая пользователя.После небольшого уменьшения максимального значения всегда положительное целое число, а минимального значения всегда отрицательное целое.

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

Это медленный процесс, поэтому профессиональные редакторы аудио сохраняют предварительно рассчитанную таблицу минимальных и максимальных значений.значения при некотором фиксированном коэффициенте масштабирования.Это может быть в 512/1 или 1024/1.Когда вы рисуете с коэффициентом масштабирования> 1024 выборок / пиксель, вы используете предварительно рассчитанную таблицу.если вы ниже этого соотношения, вы получаете данные непосредственно из файла.Если вы не сделаете этого, вы обнаружите, что при уменьшении масштаба код рисования становится слишком медленным.

Стоит написать код, который обрабатывает все каналы файла за один проход при выполнениимедлительность этого сканирования заставит всю вашу программу чувствовать себя вялой, здесь важен дисковый ввод-вывод, процессор легко справляется, поэтому простой код C ++ хорош для построения таблиц min / max, но вы не хотитепросмотрите файл более одного раза, и вы хотите сделать это последовательно.

После того, как вы получите таблицы min / max, сохраните их.Вы хотите вернуться к диску как можно меньше, и многие причины, по которым вы хотите перекрасить окно, не требуют повторного сканирования ваших таблиц min / max.Стоимость памяти для их хранения не так высока по сравнению с диском, в первую очередь для их построения.

Затем вы рисуете форму волны, рисуя серию вертикальных линий шириной 1 пиксель между максимальными значениями.значение и минимальное значение для времени, представленного этим пикселем.Это должно быть довольно быстро, если вы рисуете из предварительно построенных таблиц мин / макс.

Ответ https://stackoverflow.com/users/234815/John%20Knoeller

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...