Skip to content

Instantly share code, notes, and snippets.

@andraantariksa
Created January 19, 2020 16:31
Show Gist options
  • Save andraantariksa/4699b7754b4fc1c31f504b9353c7d1f0 to your computer and use it in GitHub Desktop.
Save andraantariksa/4699b7754b4fc1c31f504b9353c7d1f0 to your computer and use it in GitHub Desktop.
#include <SDL.h>
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <ctime>
#include <stdexcept>
#include <vector>
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(Uint8* 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;
std::vector<Music*> musics;
public:
MusicEngine();
std::vector<Music*> getMusics();
void start();
void add(Music*);
void dispatch();
static void playback(void*, Uint8*, int);
};
MusicEngine mg;
void MusicEngine::playback(void* user_data, Uint8* stream, int len)
{
std::memset(stream, 0, len);
std::vector<Music*> musics = mg.getMusics();
for (auto it = musics.begin(); it != musics.end(); ++it)
{
Uint8* buffer = new Uint8[len];
(*it)->stream(buffer, len);
for (int i = 0; i < len; ++i)
{
stream[i] += buffer[i];
}
delete buffer;
}
}
MusicEngine::MusicEngine()
{
}
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_S16;
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)
{
this->musics.push_back(music);
}
std::vector<Music*> MusicEngine::getMusics()
{
return this->musics;
}
void MusicEngine::dispatch()
{
SDL_PauseAudioDevice(this->playback_device_id, SDL_FALSE);
while(true)
{
SDL_LockAudioDevice(this->playback_device_id);
// Pause, resume, etc
SDL_UnlockAudioDevice(this->playback_device_id);
}
SDL_PauseAudioDevice(this->playback_device_id, SDL_TRUE);
}
int main()
{
if(SDL_Init(SDL_INIT_AUDIO) < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
return 1;
}
mg.start();
Music imperial_march("ImperialMarch.txt");
Music star_wars_theme("StarWarsTheme.txt");
mg.add(&imperial_march);
mg.add(&star_wars_theme);
mg.dispatch();
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment