mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-08 14:16:52 +02:00
closed #13 pitch & gain support, fix volume value
This commit is contained in:
@@ -194,7 +194,14 @@ struct Controller {
|
|||||||
TR::SoundInfo &b = level->soundsInfo[a];
|
TR::SoundInfo &b = level->soundsInfo[a];
|
||||||
if (b.chance == 0 || (rand() & 0x7fff) <= b.chance) {
|
if (b.chance == 0 || (rand() & 0x7fff) <= b.chance) {
|
||||||
int index = b.offset + rand() % b.flags.count;
|
int index = b.offset + rand() % b.flags.count;
|
||||||
Sound::play(level->getSampleStream(index), pos, (float)b.volume / 0xFFFF, 0.0f, flags | ((b.flags.replay == 1) ? Sound::REPLAY : 0), entity * 1000 + index);
|
float volume = (float)b.volume / 0x7FFF;
|
||||||
|
float pitch = b.flags.pitch ? (0.9f + randf() * 0.2f) : 1.0f;
|
||||||
|
if (b.flags.mode == 1) flags |= Sound::UNIQUE;
|
||||||
|
if (b.flags.mode == 2) flags |= Sound::REPLAY;
|
||||||
|
if (b.flags.mode == 3) flags |= Sound::SYNC;
|
||||||
|
if (b.flags.gain) volume = max(0.0f, volume - randf() * 0.25f);
|
||||||
|
if (b.flags.fixed) flags &= ~Sound::PAN;
|
||||||
|
Sound::play(level->getSampleStream(index), pos, volume, pitch, flags, entity * 1000 + index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
src/sound.h
38
src/sound.h
@@ -145,9 +145,6 @@ namespace Sound {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double samples[28];
|
|
||||||
#ifdef DECODE_VAG
|
#ifdef DECODE_VAG
|
||||||
struct VAG : Decoder {
|
struct VAG : Decoder {
|
||||||
uint8 pred, shift, flags;
|
uint8 pred, shift, flags;
|
||||||
@@ -311,10 +308,9 @@ double samples[28];
|
|||||||
enum Flags {
|
enum Flags {
|
||||||
LOOP = 1,
|
LOOP = 1,
|
||||||
PAN = 2,
|
PAN = 2,
|
||||||
REPLAY = 4,
|
UNIQUE = 4,
|
||||||
REVERB_NEAR = 8,
|
REPLAY = 8,
|
||||||
REVERB_MIDDLE = 16,
|
SYNC = 16,
|
||||||
REVERB_FAR = 32,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sample {
|
struct Sample {
|
||||||
@@ -450,17 +446,29 @@ double samples[28];
|
|||||||
FrameHI *result = new FrameHI[count];
|
FrameHI *result = new FrameHI[count];
|
||||||
memset(result, 0, sizeof(FrameHI) * count);
|
memset(result, 0, sizeof(FrameHI) * count);
|
||||||
|
|
||||||
Frame *buffer = new Frame[count];
|
int bufSize = count + count / 2;
|
||||||
|
Frame *buffer = new Frame[bufSize]; // + 50% for pitch
|
||||||
|
|
||||||
for (int i = 0; i < channelsCount; i++) {
|
for (int i = 0; i < channelsCount; i++) {
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(Frame) * count);
|
memset(buffer, 0, sizeof(Frame) * bufSize);
|
||||||
channels[i]->render(buffer, count);
|
channels[i]->render(buffer, int(count * channels[i]->pitch));
|
||||||
|
|
||||||
|
if (channels[i]->pitch == 1.0f) { // no pitch
|
||||||
for (int j = 0; j < count; j++) {
|
for (int j = 0; j < count; j++) {
|
||||||
result[j].L += buffer[j].L;
|
result[j].L += buffer[j].L;
|
||||||
result[j].R += buffer[j].R;
|
result[j].R += buffer[j].R;
|
||||||
}
|
}
|
||||||
|
} else { // has pitch (interpolate values for smooth wave)
|
||||||
|
float t = 0.0f;
|
||||||
|
for (int j = 0; j < count; j++, t += channels[i]->pitch) {
|
||||||
|
int idxA = int(t);
|
||||||
|
int idxB = (j == (count - 1)) ? idxA : (idxA + 1);
|
||||||
|
float k = t - idxA;
|
||||||
|
result[j].L += lerp(buffer[idxA].L, buffer[idxB].L, k);
|
||||||
|
result[j].R += lerp(buffer[idxA].R, buffer[idxB].R, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
@@ -502,23 +510,23 @@ double samples[28];
|
|||||||
|
|
||||||
Sample* play(Stream *stream, const vec3 &pos, float volume = 1.0f, float pitch = 0.0f, int flags = 0, int id = - 1) {
|
Sample* play(Stream *stream, const vec3 &pos, float volume = 1.0f, float pitch = 0.0f, int flags = 0, int id = - 1) {
|
||||||
if (!stream) return NULL;
|
if (!stream) return NULL;
|
||||||
|
if (volume > 0.001f) {
|
||||||
if (flags & REPLAY)
|
if (flags & (REPLAY | SYNC | UNIQUE))
|
||||||
for (int i = 0; i < channelsCount; i++)
|
for (int i = 0; i < channelsCount; i++)
|
||||||
if (channels[i]->id == id) {
|
if (channels[i]->id == id) {
|
||||||
channels[i]->pos = pos;
|
channels[i]->pos = pos;
|
||||||
// channels[i]->pitch = pitch; // TODO
|
channels[i]->pitch = pitch;
|
||||||
// channels[i]->gain = gain; // TODO
|
if (flags & (REPLAY | UNIQUE))
|
||||||
channels[i]->decoder->replay();
|
channels[i]->decoder->replay();
|
||||||
delete stream;
|
delete stream;
|
||||||
return channels[i];
|
return channels[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (channelsCount < SND_CHANNELS_MAX)
|
if (channelsCount < SND_CHANNELS_MAX)
|
||||||
return channels[channelsCount++] = new Sample(stream, pos, volume, pitch, flags, id);
|
return channels[channelsCount++] = new Sample(stream, pos, volume, pitch, flags, id);
|
||||||
|
|
||||||
LOG("! no free channels\n");
|
LOG("! no free channels\n");
|
||||||
|
}
|
||||||
delete stream;
|
delete stream;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user