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();