Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

foc_play_audio_samples in the C API does not block #796

Open
datacrystals opened this issue Jan 22, 2025 · 0 comments
Open

foc_play_audio_samples in the C API does not block #796

datacrystals opened this issue Jan 22, 2025 · 0 comments

Comments

@datacrystals
Copy link

Recently, I've been trying to implement some code that uses the foc_play_audio_samples function provided in the "vesc_c_if.h" interface, to recreate the sounds of various locomotive traction inverters, however there appears to be a bug where this function does not block. I'm running this on VESC FW 6.05, 3Shul CL350, 14S, QS205 (probably?) DD hub motor.

// Play the samples from the current buffer
if (inverter_enabled) {
    VESC_IF->foc_play_audio_samples(buffers[consumer_index], BUFFER_LENGTH, sample_rate, amplitude);
}
samples_consumed += BUFFER_LENGTH;

Assuming it is intended to function like the lisp version, the documentation says:

--

foc-play-samples

Platforms | Firmware -- | -- ESC | 6.05+
(foc-play-samples samples freq voltage)

Use the motor to play sampled audio. Works while the motor is running. Samples is a byte-array with samples, where each sample has the range -128 to 127. Freq is the sampling frequency and voltage is the voltage amplitude the samples will be played at.

The caller is responsible for making sure that the sample buffer stays valid until it is consumed. Internally this function has two buffers and when both buffers are full the function will block until a buffer is free. For smooth playback, it is important to keep feeding this function with buffers faster than it consumes the sample

--

However, even when using three buffers, and filling them much faster than the provided sample rate (1khz sine wave, ~700k samples/s generated, sample rate is 44.1k samples/s) there is very obvious clipping and stuttering sounds which seem to be caused by the buffers never blocking, and thus being constantly overwritten. Furthermore, this appears to be the culprit because adding the following largely resolves the issue (there is still some stuttering but minor, caused by the timer being slightly off, or the samples playing slightly sooner or later than expected):

float sleep_time = (float)BUFFER_LENGTH / sample_rate * 1000.0f * 1000.0f;
VESC_IF->sleep_us((uint32_t)sleep_time);

Is this expected behavior and I'm using the code wrong, or is it a bug?

As a minor side note, playing samples with the function even at low amplitude (~200mV) results in a very dramatic drop in motor torque (~2/3x), despite the phase amps being roughly the same. Sampled audio is a sawtooth wave at 2khz, 25k samples/s. At higher speeds, the motor (large direct drive hub motor) experiences quite dramatic stuttering, even at the same low amplitude. Presumably the sawtooth wave injection is causing the motor to loose tracking under load at higher speeds?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant