mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-07 05:37:01 +02:00
closed #13 pitch & gain support, fix volume value
This commit is contained in:
@@ -193,8 +193,15 @@ struct Controller {
|
||||
|
||||
TR::SoundInfo &b = level->soundsInfo[a];
|
||||
if (b.chance == 0 || (rand() & 0x7fff) <= b.chance) {
|
||||
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);
|
||||
int index = b.offset + rand() % b.flags.count;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
66
src/sound.h
66
src/sound.h
@@ -144,10 +144,7 @@ namespace Sound {
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
double samples[28];
|
||||
#ifdef DECODE_VAG
|
||||
struct VAG : Decoder {
|
||||
uint8 pred, shift, flags;
|
||||
@@ -311,10 +308,9 @@ double samples[28];
|
||||
enum Flags {
|
||||
LOOP = 1,
|
||||
PAN = 2,
|
||||
REPLAY = 4,
|
||||
REVERB_NEAR = 8,
|
||||
REVERB_MIDDLE = 16,
|
||||
REVERB_FAR = 32,
|
||||
UNIQUE = 4,
|
||||
REPLAY = 8,
|
||||
SYNC = 16,
|
||||
};
|
||||
|
||||
struct Sample {
|
||||
@@ -350,7 +346,7 @@ double samples[28];
|
||||
stream->read(waveFmt);
|
||||
stream->seek(size - sizeof(waveFmt));
|
||||
} else if (type == FOURCC("data")) {
|
||||
if (waveFmt.format == 1) decoder = new PCM(stream, waveFmt.channels, waveFmt.samplesPerSec, size, waveFmt.sampleBits);
|
||||
if (waveFmt.format == 1) decoder = new PCM(stream, waveFmt.channels, waveFmt.samplesPerSec, size, waveFmt.sampleBits);
|
||||
#ifdef DECODE_ADPCM
|
||||
if (waveFmt.format == 2) decoder = new ADPCM(stream, waveFmt.channels, size, waveFmt.block);
|
||||
#endif
|
||||
@@ -450,16 +446,28 @@ double samples[28];
|
||||
FrameHI *result = new 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++) {
|
||||
|
||||
memset(buffer, 0, sizeof(Frame) * count);
|
||||
channels[i]->render(buffer, count);
|
||||
memset(buffer, 0, sizeof(Frame) * bufSize);
|
||||
channels[i]->render(buffer, int(count * channels[i]->pitch));
|
||||
|
||||
for (int j = 0; j < count; j++) {
|
||||
result[j].L += buffer[j].L;
|
||||
result[j].R += buffer[j].R;
|
||||
if (channels[i]->pitch == 1.0f) { // no pitch
|
||||
for (int j = 0; j < count; j++) {
|
||||
result[j].L += buffer[j].L;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
if (!stream) return NULL;
|
||||
if (volume > 0.001f) {
|
||||
if (flags & (REPLAY | SYNC | UNIQUE))
|
||||
for (int i = 0; i < channelsCount; i++)
|
||||
if (channels[i]->id == id) {
|
||||
channels[i]->pos = pos;
|
||||
channels[i]->pitch = pitch;
|
||||
if (flags & (REPLAY | UNIQUE))
|
||||
channels[i]->decoder->replay();
|
||||
delete stream;
|
||||
return channels[i];
|
||||
}
|
||||
|
||||
if (flags & REPLAY)
|
||||
for (int i = 0; i < channelsCount; i++)
|
||||
if (channels[i]->id == id) {
|
||||
channels[i]->pos = pos;
|
||||
// channels[i]->pitch = pitch; // TODO
|
||||
// channels[i]->gain = gain; // TODO
|
||||
channels[i]->decoder->replay();
|
||||
delete stream;
|
||||
return channels[i];
|
||||
}
|
||||
if (channelsCount < SND_CHANNELS_MAX)
|
||||
return channels[channelsCount++] = new Sample(stream, pos, volume, pitch, flags, id);
|
||||
|
||||
|
||||
if (channelsCount < SND_CHANNELS_MAX)
|
||||
return channels[channelsCount++] = new Sample(stream, pos, volume, pitch, flags, id);
|
||||
|
||||
LOG("! no free channels\n");
|
||||
LOG("! no free channels\n");
|
||||
}
|
||||
delete stream;
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user