Я пытаюсь создать программу, используя Qt (c ++), которая может записывать звук с моего микрофона, используя QAudioinput и QIODevice.
Теперь я хочу визуализировать мой сигнал
Любая помощь будет оценена. Спасибо
[Edit1] — скопировано из вашего комментария (Спектре)
это как я разделяю ценности
for ( int i = 0, j = 0; i < countSamples ; ++j)
{
YVectorRight[j]=Samples[i++];
YVectorLeft[j] =Samples[i++];
}
после того, как я построю YvectorRight и YvectorLeft. Я не вижу, как запустить только один канал
Он сделал это несколько лет назад для студентов во время урока. Я надеюсь, что вы знаете, как работают осциллографы, поэтому вот только основы:
временная база
fsmpl
частота дискретизации входного сигнала [Гц]Попробуйте использовать как можно больше (44100,48000, ???)
поэтому максимальная обнаруженная частота fsmpl/2
это дает вам вершину оси времени. Нижний предел определяется длиной буфера
рисовать
Создайте функцию, которая будет визуализировать ваш буфер выборки с указанного начального адреса (внутри буфера) с помощью:
Это можно сделать, изменив начальный адрес или просто сместив кривую по оси X
уровень
Создать функцию, которая будет эмулировать уровень функциональность. Так что поиск буфера от начального адреса и остановки, если амплитуда пересекает уровень. У вас может быть больше режимов, но вы должны реализовать следующие основы:
( < lvl ) -> ( > lvl )
( > lvl ) -> ( < lvl )
Есть много других возможностей для уровня, таких как глюк, относительный край, …
предварительный просмотр
Вы можете собрать все это, например, так: у вас есть start address
переменная, поэтому выборка данных в некоторый буфер непрерывно и по вызову таймера level
с start address
(и обновить его). Тогда назовите ничью с новым start address
и добавить timebase period
в start address
(конечно с точки зрения ваших образцов)
многоканальный
я использую Линия IN, поэтому у меня есть стереовход (A, B = слева, справа), поэтому я могу добавить некоторые другие вещи, такие как:
A,B
,никто)x
ось A
, y
ось B
это создает знаменитые чебышевские образы, которые хороши для зависимых синусоидальных сигналов. Обычно образуются круги, эллипсы, искаженные петли …разное
Вы можете добавить фильтры для каналов, эмулирующих емкость или заземление входа и многое другое
графический интерфейс пользователя
Вам нужно много настроек, я предпочитаю аналоговые ручки вместо кнопок / полос прокрутки / ползунков, как на реальном осциллографе
Вот несколько скриншотов моего осциллографа:
Вот скриншот моего генератора:
И, наконец, после добавления некоторых БПФ также Spectrum Analyzer
PS.
Btw. У меня есть эти три приложения как связываемые классы подокна C ++ (Borland)
Надеюсь, это поможет, если вам нужна помощь, просто прокомментируйте меня
Триггер [Edit1]
Вы запускаете все каналы одновременно, но условие запуска проверяется обычно только с одного. Теперь реализация проста, например, условие триггера быть A (левый) канал поднимается над уровнем так:
Сначала сделайте непрерывное воспроизведение без написанного триггера, вот так:
for ( int i = 0, j = 0; i < countSamples ; ++j)
{
YVectorRight[j]=Samples[i++];
YVectorLeft[j] =Samples[i++];
}
// here draw or FFT,draw buffers YVectorRight,YVectorLeft
Добавить триггер
Чтобы добавить условие триггера, просто найдите образец, который соответствует ему, и начните рисовать из него, чтобы изменить его на что-то вроде этого.
// static or global variables
static int i0=0; // actual start for drawing
static bool _copy_data=true; // flag that new samples need to be copied
static int level=35; // trigger level value datatype should be the same as your samples...
int i,j;
for (;;)
{
// copy new samples to buffer if needed
if (_copy_data)
for (_copy_data=false,i=0,j=0;i<countSamples;++j)
{
YVectorRight[j]=Samples[i++];
YVectorLeft[j] =Samples[i++];
}
// now search for new start
for (i=i0+1;i<countSamples>>1;i++)
if (YVectorLeft[i-1]<level) // lower then level before i
if (YVectorLeft[i]>=level) // higher then level after i
{
i0=i;
break;
}
if (i0>=(countSamples>>1)-view_samples) { i0=0; _copy_data=true; continue; }
break;
}
// here draw or FFT,draw buffers YVectorRight,YVectorLeft from i0 position
view_samples
размер просматриваемых / обрабатываемых данных (для одного или нескольких экранов) должен быть в несколько раз меньше (countSamples>>1)
Других решений пока нет …