Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <SDL.h>
- #include <cstdio>
- #include <iostream>
- #include <string>
- #include <cstring>
- #include <fstream>
- #include <ctime>
- #include <stdexcept>
- #include <vector>
- #include <SDL2/SDL_mixer.h>
- namespace Hx { namespace Audio {
- template <typename T>
- T clamp(T val, T max, T min)
- {
- if (val > max)
- {
- return max;
- }
- else if (val < min)
- {
- return min;
- }
- else
- {
- return val;
- }
- }
- class Music
- {
- private:
- FILE *file;
- const char* filename;
- Uint32 file_size;
- public:
- Music(const char* filename)
- {
- this->filename = filename;
- this->file = fopen(this->filename, "rb");
- fseek(this->file, 0L, SEEK_END);
- this->file_size = ftell(this->file);
- rewind(this->file);
- }
- ~Music() noexcept(false)
- {
- if (fclose(this->file) == 0)
- {
- throw std::runtime_error("Closing file error");
- }
- }
- size_t stream(Uint16* buffer, int length)
- {
- return fread(buffer, 1, length, this->file);
- }
- Uint32 size()
- {
- return this->file_size;
- }
- };
- class MusicEngine
- {
- private:
- SDL_AudioSpec playback_spec_given;
- SDL_AudioDeviceID playback_device_id;
- int buffer_byte_position;
- static std::vector<Music*> musics;
- public:
- MusicEngine();
- void start();
- void pauseDevice();
- void unpauseDevice();
- void lock();
- void unlock();
- static void playback(void*, Uint8*, int);
- void add(Music*);
- static std::vector<Music*> getMusics();
- };
- void MusicEngine::playback(void* user_data, Uint8* stream_real, int len)
- {
- Uint16* stream = (Uint16*) stream_real;
- std::memset(stream, 0, len);
- std::vector<Music*> musics = MusicEngine::getMusics();
- Uint16* buffer = new Uint16[len];
- for (auto it = musics.begin(); it != musics.end(); ++it)
- {
- (*it)->stream(buffer, len);
- for (int i = 0; i < len / (sizeof(Uint16) / sizeof(Uint8)); ++i)
- {
- // http://www.vttoth.com/CMS/index.php/technical-notes/68
- // stream[i] = stream[i] + buffer[i];
- stream[i] = (Uint16) clamp((Uint32) stream[i] + (Uint32) buffer[i], 65536U, 0U);
- }
- }
- delete[] buffer;
- }
- MusicEngine::MusicEngine()
- {
- }
- std::vector<Music*> MusicEngine::musics;
- void MusicEngine::start()
- {
- this->buffer_byte_position = 0;
- this->playback_device_id = 0;
- // Open the audio device
- SDL_AudioSpec playback_spec_desired;
- SDL_zero(playback_spec_desired);
- playback_spec_desired.freq = 44100;
- playback_spec_desired.format = AUDIO_U16;
- playback_spec_desired.channels = 2;
- playback_spec_desired.samples = 4096;
- playback_spec_desired.callback = MusicEngine::playback;
- this->playback_device_id = SDL_OpenAudioDevice(nullptr, SDL_FALSE,
- &playback_spec_desired, &this->playback_spec_given, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
- if (this->playback_device_id == 0)
- {
- throw std::runtime_error(SDL_GetError());
- }
- }
- void MusicEngine::add(Music* music)
- {
- MusicEngine::musics.push_back(music);
- }
- std::vector<Music*> MusicEngine::getMusics()
- {
- return MusicEngine::musics;
- }
- void MusicEngine::unpauseDevice()
- {
- SDL_PauseAudioDevice(this->playback_device_id, SDL_FALSE);
- }
- void MusicEngine::pauseDevice()
- {
- SDL_PauseAudioDevice(this->playback_device_id, SDL_TRUE);
- }
- void MusicEngine::unlock()
- {
- SDL_UnlockAudioDevice(this->playback_device_id);
- }
- void MusicEngine::lock()
- {
- SDL_LockAudioDevice(this->playback_device_id);
- }
- } }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement