LINUX.ORG.RU

Подскажите алгоритм рисования waveform.


0

1

Алгоритм рисования вот такой http://www.learner.org/jnorth/images/graphics/s/RwOkaleeWaveform.gif хреновины.

Подсказывание должно происходить на условиях допустимости использования подсказанного в коммерческом или опенсорсном продукте (-;

Вопрос в том, как правильно и быстро нарисовать waveform, запихав на один экран 2-часовой файл.

Есть собственная реализация алгоритма, которая работает тормознее, чем Audacity. Читать чужие исходники, например Audacity - это нужно вемя и мозг, пока с этим проблемы. Вчера попробовал немного... Я догадываюсь, что у audacity похожий алгоритм на мой, просто у audacity ступенчатый зум по времени и каждую следующую степень зума он вычисляет на основе данных от предыдущей, а не с нуля, как у меня.

Мой алгоритм. 1) для данного уровня «временного масштаба» понять, сколько семплов сигнала влезает в один горизонтальный пиксель изображения.

2) Например 1024 семпла. Тогда читаем входной сигнал кусками по 1024 семпла.

3) Вычисляем для очередного «пакета» (1024 семпла) минимальное и максимальное значение амплитуды семпла. Эта пара значений будет основой для рисования одной вертикальной линии, которая графически описывает содержимое одного пакета в 1024 семплов. Примитивная идея в том, что если в течении 1024 семплов сигнал как-то мотало между -500 и +1500, то line(x, -500, x, +1500) (с масштабирующими коэффициентами) опишет этот кусок сигнала.

Масштаба, где в одном пикселе меньше 1 семпла у меня нет. В Audacity он есть, но это просто отдельный режим рисования с кружочками вокруг каждой точки и возможностью эти кружочки подвигать.

Если временной масштаб таков, что в одном пикселе - 1 или 2 семпла, то могут возникать визуальные разрывы. Рассмотрим простой случай - 1 семпл на пиксель. Вышеописанный алгоритм даст для каждого «пакета» (куда входит 1 семпл) такую пару min+max, где оба значения равны - точка, семпл-то один. Эти точки нужно бы соединить чем-то типа lineto. Я выполняю такой «пост-процессинг», где для каждого «пакета» min+max корректируются так, чтобы минимумы и максимумы соседних пакетов «встречались» на половине дистанции между ними - спасает.

Нагрузка на GUI всегда одинаковая - рисуется постоянное количество линий, определяемое шириной окна. Нормальные люди вообще кешируют этот график в виде цепочки прямоугольных pixmap-ов, чтобы не издеваться над графической библиотекой, вызывая line().

Нагрузка на процессор - в процедуре суммирования. Когда в одном горизонтальном пикселе картинки становится дофига семплов, начинается дофига работы по поиску минимумов и максимумов. Я догадываюсь, что каждый слой можно закешировать и считать соседние слои на базе соседних, но у меня временной масштаб не дискретный - нет слоёв. Когда в Audacity открываешь часовой файл в один экран и начинаешь его зумить по времени - всё летает, у меня вычисление картинки для нового временного масштаба гораздо тормознее.

Обсудите (-;

а может просто посчитать мощность сигнала, проинтегрировав по интервалу?

dikiy ★★☆☆☆
()
Ответ на: комментарий от dikiy

От этого не легче в вычислительном плане. Наоборот тяжелее - операция умножения появляется.

Погуглил я на эту тему, короче. Народ делает пример как я, просто ещё кеширует слои «зума» - 256 - 512 - 1024... Каждый следующий слой легко вычисляется на базе предыдущего.

kiverattes ★☆
() автор топика
Ответ на: комментарий от Harald

Да какая разница как эта хрень называется) Важно понимать о какой хрени идёт речь, а не как её зовут )

kiverattes ★☆
() автор топика

1) Для первоначального отображения можно использовать каждый n-ный сэмпл, потом считывать остальную информацию/корректировать в фоне

2) Большая часть программ для работы со звуком создают т.н. peak-файл, в котором, как я думаю, и содержится информация для быстрой отрисовки любого произвольного фрагмента.

Как там организоваются данные внутри - увы, не скажу. Но по идее, он должен позволять с минимальной сложностью выдавать по координатам начала, конца и физическим размерам отображаемого отрезка нужные данные.

lazyklimm ★★★★★
()
Ответ на: комментарий от lazyklimm

Для первоначального отображения можно использовать каждый n-ный сэмпл,

нельзя. Хуже совет трудно придумать.

mashina ★★★★★
()
Ответ на: комментарий от mashina

я же сказал «для первоначального», не считать же на каждый чих rms. Можешь предложить вариант быстрее?

Тем более, что в случае реальной живой волны, а не синусоиды какой, вряд ли картина радикально изменится.

lazyklimm ★★★★★
()
Ответ на: комментарий от lazyklimm

я же сказал «для первоначального»

с таким же успехом можешь «для первоначального» отображать рэндомный мусор. Как нужно делать ТС ниже(выше) уже написал.

mashina ★★★★★
()
Ответ на: комментарий от mashina

Насчёт первоначального lazyklimm прав, хорош срацца.

kiverattes ★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.