Skip to content

Commit caff310

Browse files
committed
ANDROID: fix sound ramp handling
1 parent 8e9f059 commit caff310

File tree

1 file changed

+47
-26
lines changed

1 file changed

+47
-26
lines changed

src/platform/android/jni/audio.cpp

+47-26
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <cstdint>
1010
#include <cmath>
11+
#include <algorithm>
1112
#include <unistd.h>
1213

1314
#include "config.h"
@@ -20,46 +21,50 @@
2021
constexpr int32_t AUDIO_SAMPLE_RATE = 44100;
2122
constexpr float PI2 = 2.0f * M_PI;
2223
constexpr int SILENCE_BEFORE_STOP = kMillisPerSecond * 5;
23-
constexpr int MAX_RAMP = 350;
24+
constexpr int MAX_RAMP = 450;
25+
constexpr int RAMP_SCALE = 10;
2426
int instances = 0;
2527

2628
struct Sound {
27-
Sound(int blockSize, int frequency, int millis, int volume);
29+
Sound(int blockSize, bool fadeIn, int frequency, int millis, int volume);
2830
~Sound();
2931

3032
bool ready() const;
3133
float sample();
32-
void sync(Sound *previous);
34+
void sync(Sound *previous, bool lastSound, int blockSize);
3335

3436
private:
3537
uint32_t _duration;
3638
uint32_t _samples;
3739
uint32_t _sampled;
38-
uint32_t _ramp;
40+
uint32_t _rest;
41+
uint32_t _fadeIn;
42+
uint32_t _fadeOut;
3943
float _amplitude;
4044
float _increment;
4145
float _phase;
4246
};
4347

44-
Sound::Sound(int blockSize, int frequency, int millis, int volume) :
48+
Sound::Sound(int blockSize, bool fadeIn, int frequency, int millis, int volume) :
4549
_duration(millis),
4650
_samples(AUDIO_SAMPLE_RATE * millis / 1000),
4751
_sampled(0),
48-
_ramp(_samples / 10),
52+
_rest(0),
53+
_fadeIn(0),
54+
_fadeOut(0),
4955
_amplitude((float)volume / 100.0f),
5056
_increment(PI2 * (float)frequency / AUDIO_SAMPLE_RATE),
5157
_phase(0) {
5258
instances++;
5359

54-
if (frequency != 0) {
55-
_ramp = 0;
56-
} else if (_ramp > MAX_RAMP) {
57-
_ramp = MAX_RAMP;
58-
}
59-
60-
// align sample size with burst-size
61-
if (_ramp != 0 && _samples > blockSize) {
62-
_samples = (_samples / blockSize) * blockSize;
60+
if (fadeIn) {
61+
_fadeIn = std::min((int)_samples / RAMP_SCALE, MAX_RAMP);
62+
} else if (frequency == 0) {
63+
_rest = std::min((int)_samples / RAMP_SCALE, MAX_RAMP);
64+
// align sample size with burst-size
65+
if (_rest != 0 && _samples > blockSize) {
66+
_samples = (_samples / blockSize) * blockSize;
67+
}
6368
}
6469
}
6570

@@ -82,29 +87,45 @@ float Sound::sample() {
8287
_sampled++;
8388
_phase = fmod(_phase + _increment, PI2);
8489

85-
if (_ramp != 0) {
86-
if (_sampled < _ramp) {
90+
if (_fadeIn != 0 && _sampled < _fadeIn) {
91+
// fadeIn from silence
92+
result *= (float)(_sampled) / (float)_fadeIn;
93+
} else if (_rest != 0) {
94+
if (_sampled < _rest) {
8795
// fadeOut the previous sound
88-
result *= (float)(_ramp - _sampled) / (float)_ramp;
89-
} else if (_samples - _sampled < _ramp) {
90-
// fadeIn the next sound
91-
result *= (float)(_ramp - (_samples - _sampled)) / (float)_ramp;
96+
result *= (float)(_rest - _sampled) / (float)_rest;
97+
} else if (_samples - _sampled < _rest && _fadeOut == 0) {
98+
// fadeIn the next sound, but not when the final sound
99+
result *= (float)(_rest - (_samples - _sampled)) / (float)_rest;
92100
} else {
93101
result = 0;
94102
}
103+
} else if (_fadeOut != 0 && _samples - _sampled < _fadeOut) {
104+
// fadeOut to silence
105+
result *= (float)(_samples - _sampled) / (float)_fadeOut;
95106
}
96107
return result;
97108
}
98109

99110
//
100111
// Continues the same phase for the previous sound
101112
//
102-
void Sound::sync(Sound *previous) {
113+
void Sound::sync(Sound *previous, bool lastSound, int blockSize) {
103114
_phase = previous->_phase;
104-
if (_ramp != 0) {
105-
// for fadeOut/In
115+
if (_rest != 0) {
116+
// for fadeOut/In for adjoining silence
106117
_increment = previous->_increment;
107118
}
119+
if (lastSound) {
120+
// fade out non-silent sound to silence
121+
if (_samples > blockSize) {
122+
_samples = (_samples / blockSize) * blockSize;
123+
}
124+
_fadeOut = _samples / RAMP_SCALE;
125+
if (_fadeOut > MAX_RAMP) {
126+
_fadeOut = MAX_RAMP;
127+
}
128+
}
108129
}
109130

110131
Audio::Audio() {
@@ -195,7 +216,7 @@ DataCallbackResult Audio::onAudioReady(AudioStream *oboeStream, void *audioData,
195216
//
196217
void Audio::add(int frequency, int millis, int volume) {
197218
std::lock_guard<std::mutex> lock(_lock);
198-
_queue.push(new Sound(_stream->getFramesPerBurst(), frequency, millis, volume));
219+
_queue.push(new Sound(_stream->getFramesPerBurst(), _queue.empty(), frequency, millis, volume));
199220
_startNoSound = 0;
200221
}
201222

@@ -215,7 +236,7 @@ Sound *Audio::front() {
215236
_queue.pop();
216237
auto *next = _queue.front();
217238
if (next != nullptr) {
218-
next->sync(result);
239+
next->sync(result, _queue.size() == 1, _stream->getFramesPerBurst());
219240
}
220241
result = nullptr;
221242
}

0 commit comments

Comments
 (0)