sound: Fix frequency handling and add RPM rev test (#29)

- Change curr_frequency from uint32_t to double for precise frequency
  control
- Remove get_closest_frequency() and change phase calculation in engine
  sound to ensure continuous sine curve
- Add RPM revving test
This commit is contained in:
dafteran4 2026-02-12 20:29:10 +01:00 committed by GitHub
parent 696547dadf
commit a83ac2c670
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 47 additions and 27 deletions

View File

@ -80,7 +80,7 @@ int patestCallbackGearShift(const void* inputBuffer,
data->curr_duration += 1.0 / SAMPLE_RATE; data->curr_duration += 1.0 / SAMPLE_RATE;
if (data->curr_duration >= data->duration) { if (data->curr_duration >= data->duration) {
data->curr_duration = 0.0; data->curr_duration = 0.0;
data->curr_frequency = 0; data->curr_frequency = 0.0;
} }
*out++ = sample; *out++ = sample;

View File

@ -37,46 +37,38 @@ void gear_sound_stream(pa_stream *s, size_t length, void *userdata) {
data->curr_duration += 1.0 / SAMPLE_RATE; data->curr_duration += 1.0 / SAMPLE_RATE;
if (data->curr_duration >= data->duration) { if (data->curr_duration >= data->duration) {
data->curr_duration = 0.0; data->curr_duration = 0.0;
data->curr_frequency = 0; data->curr_frequency = 0.0;
} }
} }
pa_stream_write(s, buffer, length, NULL, 0LL, PA_SEEK_RELATIVE); pa_stream_write(s, buffer, length, NULL, 0LL, PA_SEEK_RELATIVE);
} }
double get_closest_frequency(size_t num_samples, double input_frequency) {
double samples_per_cycle = SAMPLE_RATE / input_frequency;
double adjusted_frequency = SAMPLE_RATE / (num_samples / floor(num_samples/samples_per_cycle) );
return adjusted_frequency;
}
void engine_sound_stream(pa_stream *s, size_t length, void *userdata) { void engine_sound_stream(pa_stream *s, size_t length, void *userdata) {
SoundData* data = (SoundData*)userdata; SoundData* data = (SoundData*)userdata;
double freq = data->curr_frequency; double freq = data->curr_frequency;
size_t num_samples = length / sizeof(int16_t); size_t num_samples = length / sizeof(int16_t);
freq = get_closest_frequency( num_samples, freq );
//size_t num_samples = (size_t) (DURATION * SAMPLE_RATE); //size_t num_samples = (size_t) (DURATION * SAMPLE_RATE);
int16_t buffer[num_samples]; int16_t buffer[num_samples];
//double t = 0; //double t = 0;
for (size_t i = 0; i < num_samples; i++) { for (size_t i = 0; i < num_samples; i++) {
double t = data->phase; double t = data->phase;
double sample = ((double)data->curr_amplitude/100) * 32767.0 * sin( 2.0 * M_PI * freq * t ); double sample = ((double)data->curr_amplitude/100) * 32767.0 * sin( 2.0 * M_PI * t );
buffer[i] = (int16_t)sample; buffer[i] = (int16_t)sample;
t += 1.0 / SAMPLE_RATE; t += freq / SAMPLE_RATE;
if (t >= SAMPLE_RATE) { if (t >= 1.0) {
t = 0; t -= floor(t);
} }
data->phase = t; data->phase = t;
} }
data->phase = round(data->phase);
pa_stream_write(s, buffer, length, NULL, 0LL, PA_SEEK_RELATIVE); pa_stream_write(s, buffer, length, NULL, 0LL, PA_SEEK_RELATIVE);
} }

View File

@ -26,7 +26,7 @@ int gear_sound_set(SoundDevice* sounddevice, SimData* simdata)
} }
sounddevice->sounddata.last_gear = simdata->gear; sounddevice->sounddata.last_gear = simdata->gear;
slogt("set gear frequency to %i", sounddevice->sounddata.curr_frequency); slogt("set gear frequency to %f", sounddevice->sounddata.curr_frequency);
} }
@ -37,9 +37,9 @@ double modulate(SoundDevice* sounddevice, double raw_effect, SoundEffectModulati
{ {
case SOUND_EFFECT_MODULATION_FREQUENCY: case SOUND_EFFECT_MODULATION_FREQUENCY:
modulated_effect = ((sounddevice->sounddata.frequencyMax - sounddevice->sounddata.frequency) * raw_effect) + sounddevice->sounddata.frequency; modulated_effect = ((sounddevice->sounddata.frequencyMax - sounddevice->sounddata.frequency) * raw_effect) + sounddevice->sounddata.frequency;
sounddevice->sounddata.curr_frequency = trunc(modulated_effect); sounddevice->sounddata.curr_frequency = modulated_effect;
sounddevice->sounddata.curr_amplitude = sounddevice->sounddata.amplitude; sounddevice->sounddata.curr_amplitude = sounddevice->sounddata.amplitude;
slogt("set curr frequency to %i from raw effect %f and base frequency %i", sounddevice->sounddata.curr_frequency, raw_effect, sounddevice->sounddata.frequency); slogt("set curr frequency to %f from raw effect %f and base frequency %i", sounddevice->sounddata.curr_frequency, raw_effect, sounddevice->sounddata.frequency);
break; break;
case SOUND_EFFECT_MODULATION_AMPLIFY: case SOUND_EFFECT_MODULATION_AMPLIFY:
modulated_effect = ((sounddevice->sounddata.amplitudeMax - sounddevice->sounddata.amplitude) * raw_effect) + sounddevice->sounddata.amplitude; modulated_effect = ((sounddevice->sounddata.amplitudeMax - sounddevice->sounddata.amplitude) * raw_effect) + sounddevice->sounddata.amplitude;
@ -80,7 +80,7 @@ int sounddev_tyreslip_update(SimDevice* this, SimData* simdata)
} }
else else
{ {
sounddevice->sounddata.curr_frequency = 0; sounddevice->sounddata.curr_frequency = 0.0;
sounddevice->sounddata.curr_amplitude = 0; sounddevice->sounddata.curr_amplitude = 0;
sounddevice->sounddata.curr_duration = 0; sounddevice->sounddata.curr_duration = 0;
} }
@ -100,7 +100,7 @@ int sounddev_tyrelock_update(SimDevice* this, SimData* simdata)
} }
else else
{ {
sounddevice->sounddata.curr_frequency = 0; sounddevice->sounddata.curr_frequency = 0.0;
sounddevice->sounddata.curr_amplitude = 0; sounddevice->sounddata.curr_amplitude = 0;
sounddevice->sounddata.curr_duration = 0; sounddevice->sounddata.curr_duration = 0;
} }
@ -118,7 +118,7 @@ int sounddev_absbrakes_update(SimDevice* this, SimData* simdata)
} }
else else
{ {
sounddevice->sounddata.curr_frequency = 0; sounddevice->sounddata.curr_frequency = 0.0;
sounddevice->sounddata.curr_amplitude = 0; sounddevice->sounddata.curr_amplitude = 0;
sounddevice->sounddata.curr_duration = 0; sounddevice->sounddata.curr_duration = 0;
} }
@ -138,7 +138,7 @@ int sounddev_suspension_update(SimDevice* this, SimData* simdata)
} }
else else
{ {
sounddevice->sounddata.curr_frequency = 0; sounddevice->sounddata.curr_frequency = 0.0;
sounddevice->sounddata.curr_amplitude = 0; sounddevice->sounddata.curr_amplitude = 0;
sounddevice->sounddata.curr_duration = 0; sounddevice->sounddata.curr_duration = 0;
} }
@ -189,7 +189,7 @@ int sounddev_init(SoundDevice* sounddevice, const char* devname, MonocoqueTyreId
sounddevice->sounddata.phase = 0; sounddevice->sounddata.phase = 0;
sounddevice->sounddata.curr_amplitude = 0; sounddevice->sounddata.curr_amplitude = 0;
sounddevice->sounddata.curr_frequency = 0; sounddevice->sounddata.curr_frequency = 0.0;
const char* streamname= "Engine"; const char* streamname= "Engine";

View File

@ -26,7 +26,7 @@ typedef struct
uint32_t amplitude; uint32_t amplitude;
uint32_t amplitudeMax; uint32_t amplitudeMax;
double duration; double duration;
uint32_t curr_frequency; double curr_frequency;
uint32_t curr_amplitude; uint32_t curr_amplitude;
double curr_duration; double curr_duration;
double phase; double phase;

View File

@ -726,7 +726,35 @@ int tester(SimDevice* devices, int numdevices)
simdata->Yvelocity = 100; simdata->Yvelocity = 100;
simdata->Zvelocity = 0; simdata->Zvelocity = 0;
sleep(3); sleep(1);
fprintf(stdout, "Revving rpm from 1000 to 8000 and back\n");
for (int r = 0; r < 8000; r += 3)
{
simdata->rpms = 1000 + r;
for (int x = 0; x < numdevices; x++)
{
if (devices[x].initialized == true)
{
devices[x].update(&devices[x], simdata);
}
}
usleep(1000);
}
for (int r = 0; r < 8000; r += 3)
{
simdata->rpms = 9000 - r;
for (int x = 0; x < numdevices; x++)
{
if (devices[x].initialized == true)
{
devices[x].update(&devices[x], simdata);
}
}
usleep(1000);
}
fprintf(stdout, "Setting rpms to 1000\n"); fprintf(stdout, "Setting rpms to 1000\n");
simdata->rpms = 1000; simdata->rpms = 1000;