Qt4 и SFML распознавание и обработка основного тона

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

Я намерен использовать SFML для обработки звука и QT4 для графического интерфейса. У меня будет виджет, полученный из соответствующих классов QObject и SFML.

Вопрос: Как определить высоту входа микрофона с помощью SFML? Можно ли просто сохранить часть ввода в объекте sf::sound и вызвать его метод getPitch()?

2 ответа

Решение

Как выясняется, в SFML нет встроенных алгоритмов для определения высоты тона. Спасибо LBg за то, что мой разум работает в правильном направлении. SFML предоставляет только инструменты, необходимые для записи звуков и сохранения их в буфере.

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

Хотя в SFML нет встроенного алгоритма fft, в нем есть инструменты, необходимые для получения звукового буфера. Мне придется проверить и посмотреть, является ли это наиболее кроссплатформенным способом ведения дел.

Можно ли просто сохранить часть ввода в объекте sf::sound и вызвать его метод getPitch()?

GetPitch() от sf::SoundSource вернет значение, которое вы использовали на SetPitch(pitch) или по умолчанию 1.0f, Это для редактирования звука, а не для получения информации о нем. Я думаю, что единственный способ сделать это - получить массив звуковых образцов и обработать его с помощью какого-то алгоритма. Вы можете получить этот массив с ним:

sf::SoundBufferRecorder recorder;
recorder.Start();
// ...
recorder.Stop();
const sf::SoundBuffer& buffer = recorder.GetBuffer();

size_t           sample_count       = buffer.GetSamplesCount();
const sf::Int16* samples            = buffer.GetSamples();
unsigned int     samples_per_second = buffer.GetSampleRate();
Другие вопросы по тегам