몰입하는 개발자

An immersive developer/researcher

개발자 김모립

그래픽스 opengl 소리

jiankimr 2024. 5. 24. 17:03

Windows에서 OpenAL과 libsndfile 설치하기

Windows에서는 vcpkg 패키지 매니저를 사용하여 라이브러리를 설치할 수 있습니다. vcpkg를 설치한 후 OpenAL과 libsndfile을 설치합니다.

 

  1. vcpkg 설치:
sh
코드 복사
git clone https://github.com/microsoft/vcpkg cd vcpkg .\bootstrap-vcpkg.bat
  1. 라이브러리 설치:
sh
코드 복사
.\vcpkg.exe install openal-soft libsndfile
.\vcpkg.exe integrate install

 

 

  1. vcpkg 통합 확인: vcpkg 통합이 성공적으로 완료되었는지 확인합니다. vcpkg integrate install 명령어를 실행하면, Visual Studio가 vcpkg로 설치된 라이브러리를 자동으로 인식합니다.

 

경로: C:\CG\Codes\vc\projects\Homework_07\vcpkg

 

 

 

 

코드

#include <iostream>
#include <vector>
#include <AL/al.h>
#include <AL/alc.h>
#include <sndfile.h>
#include <GLFW/glfw3.h>

// OpenAL error checking
void check_al_error(const std::string& message) {
    ALenum error = alGetError();
    if (error != AL_NO_ERROR) {
        std::cerr << "OpenAL error (" << message << "): " << error << std::endl;
    }
}

// Load a WAV file into an OpenAL buffer
ALuint load_wav(const char* filename) {
    SF_INFO sf_info;
    SNDFILE* sndfile = sf_open(filename, SFM_READ, &sf_info);
    if (!sndfile) {
        std::cerr << "Could not open audio file: " << filename << std::endl;
        return 0;
    }

    std::vector<short> samples(sf_info.frames * sf_info.channels);
    sf_read_short(sndfile, samples.data(), samples.size());
    sf_close(sndfile);

    ALenum format;
    if (sf_info.channels == 1)
        format = AL_FORMAT_MONO16;
    else if (sf_info.channels == 2)
        format = AL_FORMAT_STEREO16;
    else {
        std::cerr << "Unsupported channel count: " << sf_info.channels << std::endl;
        return 0;
    }

    ALuint buffer;
    alGenBuffers(1, &buffer);
    check_al_error("alGenBuffers");

    alBufferData(buffer, format, samples.data(), samples.size() * sizeof(short), sf_info.samplerate);
    check_al_error("alBufferData");

    return buffer;
}

int main() {
    // Initialize GLFW
    if (!glfwInit()) {
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    // Create a windowed mode window and its OpenGL context
    GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL with OpenAL", nullptr, nullptr);
    if (!window) {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    // Make the window's context current
    glfwMakeContextCurrent(window);

    // Initialize OpenAL
    ALCdevice* device = alcOpenDevice(nullptr);
    if (!device) {
        std::cerr << "Failed to open OpenAL device" << std::endl;
        return -1;
    }
    ALCcontext* context = alcCreateContext(device, nullptr);
    alcMakeContextCurrent(context);

    // Load background music and effect sound
    ALuint bgmBuffer = load_wav("background_music.wav");
    ALuint effectBuffer = load_wav("effect_sound.wav");

    ALuint bgmSource;
    alGenSources(1, &bgmSource);
    alSourcei(bgmSource, AL_BUFFER, bgmBuffer);
    alSourcei(bgmSource, AL_LOOPING, AL_TRUE); // Loop background music
    alSourcePlay(bgmSource);

    ALuint effectSource;
    alGenSources(1, &effectSource);
    alSourcei(effectSource, AL_BUFFER, effectBuffer);

    // Main loop
    while (!glfwWindowShouldClose(window)) {
        // Render here
        glClear(GL_COLOR_BUFFER_BIT);

        // Check for specific trigger (e.g., key press)
        if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
            alSourcePlay(effectSource); // Play effect sound
        }

        // Swap front and back buffers
        glfwSwapBuffers(window);

        // Poll for and process events
        glfwPollEvents();
    }

    // Clean up OpenAL
    alDeleteSources(1, &bgmSource);
    alDeleteSources(1, &effectSource);
    alDeleteBuffers(1, &bgmBuffer);
    alDeleteBuffers(1, &effectBuffer);
    alcMakeContextCurrent(nullptr);
    alcDestroyContext(context);
    alcCloseDevice(device);

    // Clean up GLFW
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}