Раздел выпуска конверта ADSR не работаетC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Раздел выпуска конверта ADSR не работает

Сообщение Anonymous »

Я пытаюсь создать синтезатор цифрового звука с нуля на C++, используя комбинацию ресурсов. Я использую функции из raylib для воспроизведения необработанного аудиопотока. Вот код:

Код: Выделить всё

#include 
#include 
#include 
#include "raylib/raylib.h"

using namespace std;

#define SIGNAL_SIZE 1024
#define SAMPLE_RATE 44100
#define BITS_PER_SAMPLE 16
#define NUM_KEYS 15

#define AMPLITUDE 8000

const float BASE_FREQUENCY = 220.0f;
const float twelfthRootOf2 = pow(2.0f, 1.0f / 12.0f);

float signal[SIGNAL_SIZE];

const float deltaTime = 1 / (float)SAMPLE_RATE;
double elapsedTime = 0.0;

struct ADSREnvelope {
double attackTime;
double decayTime;
double releaseTime;

double startAmplitude;
double sustainAmplitude;

double keydownTime;
double keyupTime;

bool notePressed;

ADSREnvelope() {
attackTime = 1.0;
decayTime = 0.01;
releaseTime = 1.0;
startAmplitude = 1.0;
sustainAmplitude = 0.8;
keydownTime = 0.0;
keyupTime = 0.0;
notePressed = false;
}

void keydown(double _keydownTime) {
keydownTime = _keydownTime;
notePressed = true;
}

void keyup(double _keyupTime) {
keyupTime = _keyupTime;
notePressed = false;
}

double getAmplitude(double currTime) {
double currAmp = 0.0;
double lifetime = currTime - keydownTime;

if (notePressed) {
if (lifetime  attackTime && lifetime  (attackTime + decayTime)) {
currAmp = sustainAmplitude;
}
}
else {
currAmp = (((currTime - keyupTime) / releaseTime) * (0 - sustainAmplitude)) + sustainAmplitude;
}

if (currAmp < 0.00001) {
currAmp = 0;
}

return currAmp;
}
};

ADSREnvelope envelope;

vector keysPressed(NUM_KEYS, false);
vector phases(NUM_KEYS, 0.0f);

float squareWave(float phase) {
float output = sinf(2 * PI * phase);
if (output < 0) {
return -1;
}
else {
return 1;
}
}

float triangleWave(float phase) {
return asinf(sinf(2 * PI * phase));
}

float sawWave(float phase) {
return (2 * phase) - 1;
}

void updateStream(void* buffer, unsigned int frames) {
short* d = (short*)buffer;
float prevSample = 0.0f;

for (unsigned int n = 0; n < frames; n++) {
float sample = 0.0f;
int activeKeys = 0;
for (int i = 0; i < NUM_KEYS; i++) {
if (keysPressed[i]) {
float currFrequency = BASE_FREQUENCY * pow(twelfthRootOf2, i);
float increment = currFrequency / SAMPLE_RATE;

sample += sawWave(phases[i]);
phases[i] += increment;

if (phases[i] > 1.0f) {
phases[i] -= 1.0f;
}

activeKeys++;
}
}
if (activeKeys > 0) {
sample /= activeKeys;
sample *= 1.3;
prevSample = sample;
}
else {
sample = prevSample;
}
d[n] = envelope.getAmplitude(elapsedTime) * AMPLITUDE * sample;

elapsedTime += deltaTime;
}
}

int main(void)
{
const int screenWidth = 800;
const int screenHeight = 450;

InitWindow(screenWidth, screenHeight, "noyz");
SetTargetFPS(60);

// AUDIO
InitAudioDevice();
SetAudioStreamBufferSizeDefault(SIGNAL_SIZE);
AudioStream stream = LoadAudioStream(SAMPLE_RATE, BITS_PER_SAMPLE, 1);
SetAudioStreamCallback(stream, updateStream);
PlayAudioStream(stream);

vector notes = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"  };
KeyboardKey keys[] = { KEY_Z, KEY_S, KEY_X, KEY_C, KEY_F, KEY_V, KEY_G, KEY_B, KEY_N, KEY_J, KEY_M, KEY_K, KEY_COMMA, KEY_L, KEY_PERIOD };

int startEnvelope = false;

while (!WindowShouldClose())
{
bool play = false;
string chord = "";
for (int i = 0; i < 15; i++) {
if (IsKeyDown(keys[i])) {
//outputFrequency = BASE_FREQUENCY * pow(twelfthRootOf2, i);
play = true;
keysPressed[i] = true;
chord += notes[i] + " - ";
}
else {
keysPressed[i] = false;
}
}

if (play) {
if (!envelope.notePressed) {
envelope.keydown(elapsedTime);
}
}
else {
if (envelope.notePressed) {
envelope.keyup(elapsedTime);
}
}

BeginDrawing();
ClearBackground(BLACK);
Vector2 txtDim = MeasureTextEx(GetFontDefault(), chord.c_str(), 32, 0);
DrawText(chord.c_str(), 400 - (txtDim.x / 2), 225 - (txtDim.y / 2), 32, RAYWHITE);
EndDrawing();
}

CloseWindow();

return 0;
}
Все части конверта работают нормально, кроме Release. Звук просто обрывается. Я возился с кодом, внося различные изменения, пытаясь заставить его работать, но он продолжает отключаться. LLM тоже не смогли это исправить (Клод Код). Наконец я решил, что это может быть проблема с типом данных, и внимательно просмотрел код, но на самом деле не нашел таких ошибок. Теперь в отчаянии я обращаюсь к StackOverflow. Пожалуйста, помогите.

Подробнее здесь: https://stackoverflow.com/questions/797 ... ot-working
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»