-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
058abcf
commit f387b66
Showing
6 changed files
with
163 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
cmake_minimum_required(VERSION 3.21) | ||
|
||
target_sources(cchip8 | ||
PRIVATE beeper.cpp) | ||
|
||
target_include_directories(cchip8 PRIVATE include) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// | ||
// Created by cleve on 1/16/2022. | ||
// | ||
|
||
#include "sound/beeper.h" | ||
|
||
#include <cmath> | ||
#include <stdexcept> | ||
|
||
using namespace std; | ||
|
||
cchip8::sound::beeper::beeper() | ||
{ | ||
SDL_AudioSpec spec; | ||
|
||
spec.freq = FREQUENCY; | ||
spec.format = AUDIO_S16SYS; | ||
spec.channels = 1; | ||
spec.samples = 2048; | ||
spec.callback = callback; | ||
spec.userdata = this; | ||
|
||
SDL_AudioSpec obtained; | ||
|
||
// you might want to look for errors here | ||
if (SDL_OpenAudio(&spec, &obtained) != 0) | ||
{ | ||
throw runtime_error{ SDL_GetError() }; | ||
} | ||
|
||
// start play audio | ||
SDL_PauseAudio(0); | ||
} | ||
|
||
cchip8::sound::beeper::~beeper() | ||
{ | ||
SDL_CloseAudio(); | ||
} | ||
|
||
void cchip8::sound::beeper::beep(double freq, int duration) | ||
{ | ||
SDL_LockAudio(); | ||
beep_segs_.emplace(freq, duration * FREQUENCY / 1000); | ||
SDL_UnlockAudio(); | ||
} | ||
|
||
void cchip8::sound::beeper::wait() | ||
{ | ||
int size = 0; | ||
do | ||
{ | ||
SDL_Delay(20); | ||
SDL_LockAudio(); | ||
size = beep_segs_.size(); | ||
SDL_UnlockAudio(); | ||
} while (size > 0); | ||
} | ||
|
||
void cchip8::sound::beeper::sample(std::span<Sint16> stream) | ||
{ | ||
int i = 0; | ||
while (i < stream.size()) | ||
{ | ||
|
||
if (beep_segs_.empty()) | ||
{ | ||
while (i < stream.size()) | ||
{ | ||
stream[i] = 0; | ||
i++; | ||
} | ||
return; | ||
} | ||
auto& bo = beep_segs_.front(); | ||
|
||
int samples_count = std::min(i + bo.second, (int)stream.size()); | ||
bo.second -= samples_count - i; | ||
|
||
while (i < samples_count) | ||
{ | ||
stream[i] = AMPLITUDE * std::sin(v_ * 2 * 3.1415926f / FREQUENCY); | ||
i++; | ||
v_ += bo.first; | ||
} | ||
|
||
if (bo.second == 0) | ||
{ | ||
beep_segs_.pop(); | ||
} | ||
} | ||
} | ||
|
||
void cchip8::sound::beeper::callback(void* b, Uint8* s, int len) | ||
{ | ||
auto* stream = (Sint16*)s; | ||
int length = len / 2; | ||
auto* bp = (beeper*)b; | ||
|
||
bp->sample({ stream, (size_t)length }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// | ||
// Created by cleve on 1/16/2022. | ||
// | ||
|
||
#pragma once | ||
|
||
#include <queue> | ||
#include <utility> | ||
#include <span> | ||
|
||
#include <SDL.h> | ||
#include <SDL_audio.h> | ||
|
||
namespace cchip8::sound | ||
{ | ||
class beeper | ||
{ | ||
public: | ||
static constexpr int AMPLITUDE = 28000; | ||
static constexpr int FREQUENCY = 44100; | ||
|
||
beeper(); | ||
|
||
~beeper(); | ||
|
||
beeper(beeper&&) = delete; | ||
|
||
beeper(const beeper&) = delete; | ||
|
||
beeper& operator=(const beeper&) = delete; | ||
|
||
void beep(double freq,int duration); | ||
|
||
void wait(); | ||
|
||
private: | ||
void sample(std::span<Sint16> stream); | ||
static void callback(void*,Uint8*,int); | ||
|
||
double v_{}; | ||
std::queue<std::pair<double, int>> beep_segs_{}; | ||
}; | ||
} |