Ugrás a tartalomhoz

synthesizer

A Wikiszótárból, a nyitott szótárból

Főnév

synthesizer (tsz. synthesizers)

  1. (informatika) szintetizátor
#include <SDL2/SDL.h>
#include <cmath>
#include <iostream>
#include <map>

const int SAMPLE_RATE = 44100;
const int AMPLITUDE = 28000;
const double TWO_PI = 6.28318530718;

// Frequency mapping for one octave (C4 to B4)
std::map<SDL_Keycode, double> keyToFreq = {
    {SDLK_a, 261.63},  // C4
    {SDLK_s, 293.66},  // D4
    {SDLK_d, 329.63},  // E4
    {SDLK_f, 349.23},  // F4
    {SDLK_g, 392.00},  // G4
    {SDLK_h, 440.00},  // A4
    {SDLK_j, 493.88}   // B4
};

double currentFreq = 0.0;
double phase = 0.0;

// Audio callback function
void audioCallback(void* userdata, Uint8* stream, int len) {
    Sint16* buffer = (Sint16*)stream;
    int length = len / 2; // 16-bit audio

    for (int i = 0; i < length; ++i) {
        if (currentFreq > 0) {
            buffer[i] = static_cast<Sint16>(AMPLITUDE * std::sin(phase));
            phase += TWO_PI * currentFreq / SAMPLE_RATE;
            if (phase > TWO_PI) phase -= TWO_PI;
        } else {
            buffer[i] = 0; // Silence when no key is pressed
        }
    }
}

int main() {
    if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0) {
        std::cerr << "SDL Init Failed: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_AudioSpec desiredSpec = {};
    desiredSpec.freq = SAMPLE_RATE;
    desiredSpec.format = AUDIO_S16SYS;
    desiredSpec.channels = 1;
    desiredSpec.samples = 4096;
    desiredSpec.callback = audioCallback;

    if (SDL_OpenAudio(&desiredSpec, NULL) < 0) {
        std::cerr << "SDL OpenAudio Failed: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return 1;
    }

    SDL_PauseAudio(0); // Start audio playback

    bool running = true;
    SDL_Event event;

    while (running) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                running = false;
            } else if (event.type == SDL_KEYDOWN) {
                auto it = keyToFreq.find(event.key.keysym.sym);
                if (it != keyToFreq.end()) {
                    currentFreq = it->second;
                }
            } else if (event.type == SDL_KEYUP) {
                auto it = keyToFreq.find(event.key.keysym.sym);
                if (it != keyToFreq.end() && currentFreq == it->second) {
                    currentFreq = 0.0;
                }
            }
        }
    }

    SDL_CloseAudio();
    SDL_Quit();
    return 0;
}
compile

g++ synth.cpp -o synth -lSDL2 -std=c++17