Статика и гудение при генерации и воспроизведении синусоидальных волн с SFML

Я пишу программу, которая должна воспроизводить много синтезированных синусоид в быстрой последовательности. Я использую C ++ и SFML для написания этой программы. Я создал класс для представления синтезатора. Он отвечает за генерацию синусоидальной волны и воспроизведение ее по одному аудиопотоку. Однако всякий раз, когда я использую приложение, я получаю много трескучих и трескучих звуков, которые смешиваются. Я не уверен, является ли это проблемой библиотеки, или я генерирую и подаваю в синусоиде неправильно. Вот мой код:

synth.h

#pragma once

#include <SFML/Audio.hpp>
#include <vector>
#include <mutex>

class Synth : public sf::SoundStream {
std::vector<sf::Int16> m_AudioData;
std::mutex m_Lock;

bool m_ClearData, m_Loaded, m_Started;

int m_Amplitude;

const float TAU = 6.28318;

public:
Synth(int);
Synth(const Synth&);

~Synth();

bool onGetData(sf::SoundStream::Chunk&) override;
void onSeek(sf::Time) override;

void makeSound(float, int);
bool busy();
};

synth.cpp

#include "synth.h"
Synth::Synth(int amplitude)
: m_Amplitude(amplitude)
, m_Loaded(false)
, m_ClearData(false)
, m_Started(false)
{
initialize(1, 44100);
}

Synth::Synth(const Synth& other)
: m_Amplitude(other.m_Amplitude)
, m_Loaded(false)
, m_ClearData(false)
, m_Started(false)
{
initialize(1, 44100);
}

Synth::~Synth() {
stop();
}

bool Synth::onGetData(Chunk &chunk) {
static const sf::Int16 empty[10] = { 0 };

m_Lock.lock();

if (m_Loaded) {
chunk.sampleCount = m_AudioData.size();
chunk.samples = m_AudioData.data();

m_ClearData = true;
m_Loaded = false;
}
else {
if (m_ClearData) {
m_AudioData.clear();
m_ClearData = false;
}

chunk.sampleCount = 10;
chunk.samples = empty;
}

m_Lock.unlock();

return true;
}

void Synth::onSeek(sf::Time) {}

void Synth::makeSound(float freq, int duration) {
m_Lock.lock();

m_ClearData = false;
m_Loaded = true;

m_AudioData.clear();

int sampleCount = duration * 44;
int amplitude = m_Amplitude;
for (int i = 0; i < sampleCount; i++) {
if (i < sampleCount / 5)
amplitude = floor(m_Amplitude * (i / (double)sampleCount) * 5);
else if (i > sampleCount / 2)
amplitude = floor(m_Amplitude * ((sampleCount - i) / (double)sampleCount));
else
amplitude = m_Amplitude;

m_AudioData.push_back(amplitude * sin(TAU * (freq / 44100) * i));
}

m_Lock.unlock();

if (!m_Started) {
play();
m_Started = true;
}
}

bool Synth::busy() {
bool isBusy = false;

if (m_Lock.try_lock()) {
isBusy = m_Loaded || m_ClearData;

m_Lock.unlock();
}

return isBusy;
}

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

Большое спасибо, открыта для любой другой стороны критики моего кода.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]