mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Call the sound effect mixer directly from Mix instead of pushing the samples from background audio.
This commit is contained in:
1 parent
830679503d
commit
19f4eadeb1
4 files changed
+130
-93
No files matched your search
+84
-65
@@ -257,49 +257,6 @@ BackgroundAudio::~BackgroundAudio() {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) {
|
||||
size_t bytes;
|
||||
uint8_t *data = g_VFS.ReadFile(path.c_str(), &bytes);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RIFFReader reader(data, (int)bytes);
|
||||
|
||||
WavData wave;
|
||||
wave.Read(reader);
|
||||
|
||||
delete [] data;
|
||||
|
||||
if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame != 4) {
|
||||
ERROR_LOG(AUDIO, "Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int16_t *samples = new int16_t[2 * wave.numFrames];
|
||||
memcpy(samples, wave.raw_data, wave.numFrames * wave.raw_bytes_per_frame);
|
||||
|
||||
return new BackgroundAudio::Sample(samples, wave.numFrames);
|
||||
}
|
||||
|
||||
void BackgroundAudio::LoadSamples() {
|
||||
samples_.resize((size_t)UI::UISound::COUNT);
|
||||
samples_[(size_t)UI::UISound::BACK] = std::unique_ptr<Sample>(LoadSample("sfx_back.wav"));
|
||||
samples_[(size_t)UI::UISound::SELECT] = std::unique_ptr<Sample>(LoadSample("sfx_select.wav"));
|
||||
samples_[(size_t)UI::UISound::CONFIRM] = std::unique_ptr<Sample>(LoadSample("sfx_confirm.wav"));
|
||||
samples_[(size_t)UI::UISound::TOGGLE_ON] = std::unique_ptr<Sample>(LoadSample("sfx_toggle_on.wav"));
|
||||
samples_[(size_t)UI::UISound::TOGGLE_OFF] = std::unique_ptr<Sample>(LoadSample("sfx_toggle_off.wav"));
|
||||
|
||||
UI::SetSoundCallback([](UI::UISound sound) {
|
||||
g_BackgroundAudio.PlaySFX(sound);
|
||||
});
|
||||
}
|
||||
|
||||
void BackgroundAudio::PlaySFX(UI::UISound sfx) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
plays_.push_back(PlayInstance{ sfx, 0, 64, false });
|
||||
}
|
||||
|
||||
void BackgroundAudio::Clear(bool hard) {
|
||||
if (!hard) {
|
||||
fadingOut_ = true;
|
||||
@@ -372,28 +329,6 @@ bool BackgroundAudio::Play() {
|
||||
}
|
||||
}
|
||||
|
||||
// Mix in menu sound effects. Terribly slow mixer but meh.
|
||||
if (!plays_.empty()) {
|
||||
for (int i = 0; i < sz * 2; i += 2) {
|
||||
std::vector<PlayInstance>::iterator iter = plays_.begin();
|
||||
while (iter != plays_.end()) {
|
||||
PlayInstance inst = *iter;
|
||||
auto sample = samples_[(int)inst.sound].get();
|
||||
if (!sample || iter->offset >= sample->length_) {
|
||||
iter->done = true;
|
||||
iter = plays_.erase(iter);
|
||||
} else {
|
||||
if (!iter->done) {
|
||||
buffer[i] += sample->data_[inst.offset * 2] * inst.volume >> 8;
|
||||
buffer[i + 1] += sample->data_[inst.offset * 2 + 1] * inst.volume >> 8;
|
||||
}
|
||||
iter->offset++;
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System_AudioPushSamples(buffer, sz);
|
||||
|
||||
if (at3Reader_ && fadingOut_ && volume_ <= 0.0f) {
|
||||
@@ -431,3 +366,87 @@ void BackgroundAudio::Update() {
|
||||
sndLoadPending_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int16_t Clamp16(int32_t sample) {
|
||||
if (sample < -32767) return -32767;
|
||||
if (sample > 32767) return 32767;
|
||||
return sample;
|
||||
}
|
||||
|
||||
void SoundEffectMixer::Mix(int16_t *buffer, int sz, int sampleRateHz) {
|
||||
// Mix in menu sound effects. Terribly slow mixer but meh.
|
||||
if (plays_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (std::vector<PlayInstance>::iterator iter = plays_.begin(); iter != plays_.end(); ) {
|
||||
auto sample = samples_[(int)iter->sound].get();
|
||||
for (int i = 0; i < sz * 2; i += 2) {
|
||||
if (!sample || iter->offset >= sample->length_) {
|
||||
iter->done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Clamping add on top. Not great, we should be mixing at higher bitrate instead. Oh well.
|
||||
int left = buffer[i];
|
||||
int right = buffer[i + 1];
|
||||
|
||||
left = Clamp16(left + (sample->data_[iter->offset * 2] * iter->volume >> 8));
|
||||
right = Clamp16(right + (sample->data_[iter->offset * 2 + 1] * iter->volume >> 8));
|
||||
|
||||
buffer[i] = left;
|
||||
buffer[i + 1] = right;
|
||||
|
||||
iter->offset++;
|
||||
}
|
||||
|
||||
if (iter->done) {
|
||||
iter = plays_.erase(iter);
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEffectMixer::Play(UI::UISound sfx) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
plays_.push_back(PlayInstance{ sfx, 0, 64, false });
|
||||
}
|
||||
|
||||
Sample *SoundEffectMixer::LoadSample(const std::string &path) {
|
||||
size_t bytes;
|
||||
uint8_t *data = g_VFS.ReadFile(path.c_str(), &bytes);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RIFFReader reader(data, (int)bytes);
|
||||
|
||||
WavData wave;
|
||||
wave.Read(reader);
|
||||
|
||||
delete[] data;
|
||||
|
||||
if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame != 4) {
|
||||
ERROR_LOG(AUDIO, "Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int16_t *samples = new int16_t[2 * wave.numFrames];
|
||||
memcpy(samples, wave.raw_data, wave.numFrames * wave.raw_bytes_per_frame);
|
||||
|
||||
return new Sample(samples, wave.numFrames);
|
||||
}
|
||||
|
||||
void SoundEffectMixer::LoadSamples() {
|
||||
samples_.resize((size_t)UI::UISound::COUNT);
|
||||
samples_[(size_t)UI::UISound::BACK] = std::unique_ptr<Sample>(LoadSample("sfx_back.wav"));
|
||||
samples_[(size_t)UI::UISound::SELECT] = std::unique_ptr<Sample>(LoadSample("sfx_select.wav"));
|
||||
samples_[(size_t)UI::UISound::CONFIRM] = std::unique_ptr<Sample>(LoadSample("sfx_confirm.wav"));
|
||||
samples_[(size_t)UI::UISound::TOGGLE_ON] = std::unique_ptr<Sample>(LoadSample("sfx_toggle_on.wav"));
|
||||
samples_[(size_t)UI::UISound::TOGGLE_OFF] = std::unique_ptr<Sample>(LoadSample("sfx_toggle_off.wav"));
|
||||
|
||||
UI::SetSoundCallback([](UI::UISound sound) {
|
||||
g_BackgroundAudio.SFX().Play(sound);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user