Skip to content

Sound Manager to master #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d815b88
OpenAL cmake config
Wiesiek418 Feb 6, 2025
1f5c995
Constructors, Destructors [Sound, Source, Clip] and SoundListener
Wiesiek418 Feb 15, 2025
0928d0c
Load audio file OGG
Wiesiek418 Feb 23, 2025
5bb0282
Fix code format
Wiesiek418 Feb 23, 2025
47b5eff
Commit for test raytrace
Wiesiek418 Feb 25, 2025
ee5c287
Rebuild Sound Manager and playing sound
Wiesiek418 Feb 26, 2025
e675d64
Pause, Stop sound. Comments in manager
Wiesiek418 Feb 27, 2025
b22e01f
Delete sound thread
Wiesiek418 Mar 8, 2025
4b877ea
Changing the ums_sources parameter from sso name to sso object and ad…
Wiesiek418 Mar 10, 2025
6b8063e
Refactore and rebuild manager, soundClip, soundSource (soundClip key …
Wiesiek418 Mar 14, 2025
f151877
Rebuild of sound manager (WiP), change map to vector, shared/weak poi…
Wiesiek418 Mar 15, 2025
19a4cdc
Fix sound debug, detect expired pointer
Wiesiek418 Mar 23, 2025
dc90250
Replace throw to cerr in source, manager, clip
Wiesiek418 Mar 23, 2025
8e920eb
External public function from manager.cpp to functions.hpp and WiP gr…
Wiesiek418 Mar 24, 2025
634be22
Delete SoundGroupParameters and SoundGroupMovement, add functions.hpp…
Wiesiek418 Mar 28, 2025
d1b951c
Sound group as a offset in sso, adds all parameters, getting only mon…
Wiesiek418 Apr 1, 2025
c48d3b3
Fast commit before branch engine test
Wiesiek418 Apr 3, 2025
6f2a24f
Comments on sound hpp files
Wiesiek418 Apr 10, 2025
3f7a659
WiP load WAV file, add removeObject to SoundManager
Wiesiek418 Apr 11, 2025
3182ba2
Merge master to sound
Wiesiek418 Apr 11, 2025
83952e0
Hot fixs in sound system
Wiesiek418 Apr 15, 2025
4e74a7c
Hot fixes v2 sound system
Wiesiek418 Apr 15, 2025
cecbca1
WAV file support
Wiesiek418 Apr 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ find_package(Python REQUIRED COMPONENTS Interpreter)
find_package(Threads REQUIRED)
find_package(Freetype REQUIRED)
find_package(Vulkan REQUIRED)
find_package(OpenAL)

# Try: cmake . -B build && cmake --build build/
if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)
Expand All @@ -34,6 +35,19 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
endif()

if (NOT OpenAL_FOUND)
message(STATUS "OpenAL was NOT found, falling back to OpenAL-Soft!")

FetchContent_Declare(
openal-soft
GIT_REPOSITORY https://github.com/kcat/openal-soft
GIT_TAG 1.23.1
GIT_PROGRESS TRUE
)

FetchContent_MakeAvailable(openal-soft)
endif()

# Don't fail on systems without X11 libraries
if (UNIX)
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
Expand Down Expand Up @@ -104,12 +118,18 @@ compile_glsl_directory(
VULKAN_TARGET "vulkan1.2"
)

if(NOT DEFINED OpenAL_INCLUDE_DIRS)
set(OpenAL_INCLUDE_DIRS "${OpenAL_SOURCE_DIR}/include")
message(STATUS "Applying OpenAL include directory fix")
endif()

set(CHECKLIGHT_LIBRARIES
${glm_SOURCE_DIR} # Headers in ./glm
${glfw_SOURCE_DIR}/include # Headers in ./GLFW
${stb_SOURCE_DIR} # Headers in ./
${Vulkan_INCLUDE_DIRS} # Headers in ./vulcan
${vma_SOURCE_DIR}/include # Headers in ./
${OpenAL_INCLUDE_DIRS} # Headers in ./AL
)

add_library(checklight_common INTERFACE)
Expand All @@ -123,20 +143,23 @@ file(GLOB_RECURSE CHECKLIGHT_ENGINE_SOURCES "src/engine/*.cpp")
add_library(checklight_engine_system ${CHECKLIGHT_ENGINE_SOURCES})

file(GLOB_RECURSE CHECKLIGHT_RENDER_SOURCES "src/render/*.cpp")
add_library(checklight_render_system ${CHECKLIGHT_RENDER_SOURCES})
add_library(checklight_render_system ${CHECKLIGHT_RENDER_SOURCES} )

file(GLOB_RECURSE CHECKLIGHT_SHARED_SOURCES "src/shared/*.cpp")
add_library(checklight_shared_system ${CHECKLIGHT_SHARED_SOURCES})
add_library(checklight_shared_system ${CHECKLIGHT_SHARED_SOURCES} )

file(GLOB_RECURSE CHECKLIGHT_INPUT_SOURCES "src/input/*.cpp")
add_library(checklight_input_system ${CHECKLIGHT_INPUT_SOURCES})
add_library(checklight_input_system ${CHECKLIGHT_INPUT_SOURCES} )

file(GLOB_RECURSE CHECKLIGHT_SOUND_SOURCES "src/sound/*.cpp")
add_library(checklight_sound_system ${CHECKLIGHT_SOUND_SOURCES} )

add_library(checklight_external
lib/stb_image.cpp
lib/stb_image_write.cpp
lib/stb_vorbis.cpp
lib/vk_mem_alloc.cpp
)
)

target_include_directories(checklight_external PRIVATE
${CHECKLIGHT_LIBRARIES}
Expand Down Expand Up @@ -170,11 +193,18 @@ target_link_libraries(checklight_input_system PRIVATE
checklight_common
)

target_link_libraries(checklight_sound_system PRIVATE
checklight_common
OpenAL::OpenAL
checklight_external
)

target_link_libraries(checklight PRIVATE
checklight_common
checklight_render_system
checklight_shared_system
checklight_input_system
checklight_sound_system
checklight_engine_system
)

Expand Down
Binary file added assets/sounds/1.ogg
Binary file not shown.
Binary file added assets/sounds/2.ogg
Binary file not shown.
Binary file added assets/sounds/3.ogg
Binary file not shown.
Binary file added assets/sounds/4.ogg
Binary file not shown.
Binary file added assets/sounds/5.ogg
Binary file not shown.
Binary file added assets/sounds/testOGG.ogg
Binary file not shown.
Binary file added assets/sounds/testWAV.wav
Binary file not shown.
6 changes: 6 additions & 0 deletions src/external.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@
#include <glm/gtx/hash.hpp>
#include <glm/gtx/norm.hpp>


// OpenAL
#include <AL/al.h>
#include <AL/alc.h>


// Vulkan Format Database
#include "vk_format_info.hpp"

Expand Down
18 changes: 16 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

#include "render/render.hpp"
#include "input/input.hpp"
#include "engine/engine.hpp"
#include "sound/sound.hpp"

static void drawUserInterface(ImmediateRenderer& immediate, float width, float height) {
immediate.setSprite("assets/image/corners.png");
Expand Down Expand Up @@ -117,6 +117,18 @@ int main() {
.shadow = true
});

SoundListener::setPosition(0, 0, 0);
SoundManager& sm = SoundManager::getInstance();
auto sso = std::make_shared<SoundSourceObject>();
sm.addSource(sso);
sm.createSoundClipAndAddToSourceObject("assets/sounds/testWAV.wav", sso);
sso->setPosition(0, 0, 0);
sso->setMaxDistance(20);
sso->setReferenceDistance(1.0f);
sso->setRolloffFactor(1.0f);
sso->setMinGain(0.0f);
SoundListener::setDistanceModel(AL_INVERSE_DISTANCE);

while (!window.shouldClose()) {
window.poll();

Expand All @@ -135,9 +147,11 @@ int main() {
point_light->position = glm::vec3(3.0, 2.0, 18.0 * sin(glfwGetTime() / 8));
point_light->color = glm::vec3(sin(glfwGetTime() / 2) * 0.5 + 0.5, sin(glfwGetTime() / 3 + 2) * 0.5 + 0.5, sin(glfwGetTime() / 5 + 4) * 0.5 + 0.5);
system.getLightManager().flush();

// render the scene
system.draw();
sm.playSound(sso);
SoundListener::setPosition(current_board->getCamPos().x, current_board->getCamPos().y, current_board->getCamPos().z);
}

system.wait();
Expand Down
159 changes: 159 additions & 0 deletions src/sound/clip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#include "clip.hpp"

SoundClip::SoundClip(){
alGetError();
alGenBuffers(1, &buffer);

ALenum error;
if ((error = alGetError()) != AL_NO_ERROR){
std::cerr << ("Clip -> SCinit: Failed to generate buffers\n"); //throw exception
return;
}
}

SoundClip::~SoundClip(){
alDeleteBuffers(1, &buffer);
}

void SoundClip::loadOGGFile(const char* filename) {
// clean up errors
alGetError();

int channels, sample_rate;
short* output;

// get output, channels, sample rate from filename and size of the data
ALsizei size_block = stb_vorbis_decode_filename(filename, &channels, &sample_rate, &output);

if (size_block == -1) {
std::cerr << ("SoundClip -> OGG file load error\n");
return;
}
this->path = filename;

/// Check of the file has more than 2 channels. If it has, convert it to mono
if (channels >= 2) {
/// Resize to 1 channel
size_block /= channels;
short* output2 = new short[size_block];
/// Get data only from 1 channel
for (int i = 0;i < size_block;i++) {
output2[i] = output[i * channels];
}
delete[] output;
output = output2;
}

ALenum format = AL_FORMAT_MONO16;
ALsizei audio_size = size_block * sizeof(short);
// Create buffer
alBufferData(buffer, format, output, audio_size, sample_rate);
delete[] output;
ALenum error;
if ((error = alGetError()) != AL_NO_ERROR) {
std::cerr << ("Clip -> loadOGGFile: Failed to load file to buffer\n"); //throw exception
return;
}

printf("SoundClip -> OGG file loaded\n");
}

void SoundClip::loadWAVFile(const char* filename) {
alGetError();
/// WAV File Header
/// https://docs.fileformat.com/audio/wav/
/// http://soundfile.sapp.org/doc/WaveFormat/
struct WAVFile {
char chunk_ID[4];
uint32_t chunk_size;
char format[4];

char subchunk1_ID[4];
uint32_t subchunk1_size;
uint16_t audio_format;
uint16_t num_channels;
uint32_t sample_rate;
uint32_t byte_rate;
uint16_t block_align;
uint16_t bits_per_sample;

char subchunk2_ID[4];
uint32_t subchunk2_size;
};

std::ifstream wav_file(filename, std::ios::binary);
WAVFile wav_header;
/// Read header from file
wav_file.read(reinterpret_cast<char*>(&wav_header), sizeof(WAVFile));

ALsizei frequency = wav_header.sample_rate;
/// Read all audio data without header from file
short* data = new short[wav_header.subchunk2_size];
wav_file.read(reinterpret_cast<char*>(data), wav_header.subchunk2_size);
ALsizei audio_size = wav_header.subchunk2_size;

/// Check of the file has more than 2 channels. If it has, convert it to mono
if (wav_header.num_channels >= 2) {
/// Resize to 1 channel
audio_size /= wav_header.num_channels;
/// Get data only from 1 channel
short* output = new short[audio_size];
for (int i = 0; i < audio_size; i++) {
output[i] = data[i * wav_header.num_channels];
}
delete[] data;
data = output;
}

ALenum format;
if (wav_header.bits_per_sample == 8) {
format = AL_FORMAT_MONO8;
}
else if (wav_header.bits_per_sample == 16) {
format = AL_FORMAT_MONO16;
}
else {
std::cerr << ("SoundClip -> WAV file load error\n");
delete[] data;
return;
}

alBufferData(buffer, format, data, audio_size, frequency);
delete[] data;

ALenum error;
if ((error = alGetError()) != AL_NO_ERROR) {
std::cerr << ("Clip -> loadWAVFile: Failed to load file to buffer\n"); //throw exception
return;
}

printf("SoundClip -> WAV file loaded\n");
}

void SoundClip::loadAudio(const char* filename){
std::ifstream input_file(filename, std::ios::binary);
if (!input_file) {
std::cerr << ("SoundClip -> addAudio: File not found\n");
return;
}
char header[4];
input_file.read(header, 4);
input_file.close();

if (std::string(header, 4) == "OggS") {
loadOGGFile(filename);
}
else if (std::string(header, 4) == "RIFF" || std::string(header, 4) == "WAVE")
loadWAVFile(filename);
else
std::cerr << ("SoundClip -> addAudio: File not supported\n");
}

ALuint SoundClip::getBuffer() {
return buffer;
}

std::string SoundClip::getPath()
{
return path;
}
42 changes: 42 additions & 0 deletions src/sound/clip.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include "external.hpp"

//@TODO poprawic wczytywanie plikow audio stereo, kilka bufferow dla jednego pliku, rozdzielic kanaly na mono

/// Object to management of buffers
/// In this version provide management only on one buffer
class SoundClip {
private:

/// Pointer to id of buffers
ALuint buffer;
/// Path of buffer in buffer
std::string path;

protected:

/// Load ogg file to buffer
void loadOGGFile(const char* filename);
/// Load wav file to buffer
void loadWAVFile(const char* filename);

public:

SoundClip();
~SoundClip();

/// Method to create audio buffer for audio file
/// If the audio file has more than 1 channel, converts to mono
/// by extracting only one channel (first channel)
/// If you want to use other method to convert, overwrite loadOGGFile or loadWAVFile
/// Enable only OGG and WAV files
///
/// @param path Path to the audio file
void loadAudio(const char* path);

/// Get the buffer
ALuint getBuffer();

/// Get Path from the buffer
std::string getPath();
};
Loading