#include "../codec/codec.h" static inline f32 apply_volume_f32(f32 *data, size_t sample_count, s32 channel_count, f32 volume, f32 limit, f32 step) { for (u32 i = 0; i < sample_count; i++) { if (step != 0.f && i % channel_count == 0) { volume = CLAMP(volume + step, 0.f, limit); } f64 sample = (f64)data[i]; sample *= volume; data[i] = (f32)CLAMP(sample, -1.0, 1.0); } return volume; } static inline f32 apply_volume_s32(s32 *data, size_t sample_count, s32 channel_count, f32 volume, f32 limit, f32 step) { for (u32 i = 0; i < sample_count; i++) { if (step != 0.f && i % channel_count == 0) { volume = CLAMP(volume + step, 0.f, limit); } f64 sample = (f64)data[i]; sample *= volume; data[i] = (s32)CLAMP(sample, (f64)INT32_MIN, (f64)INT32_MAX); } return volume; } static inline f32 apply_volume_s16(s16 *data, size_t sample_count, s32 channel_count, f32 volume, f32 limit, f32 step) { for (u32 i = 0; i < sample_count; i++) { if (step != 0.f && i % channel_count == 0) { volume = CLAMP(volume + step, 0.f, limit); } f64 sample = (f64)data[i]; sample *= volume; data[i] = (s16)CLAMP(sample, (f64)INT16_MIN, (f64)INT16_MAX); } return volume; } static inline f32 apply_volume(u8 *data, size_t size, struct camu_audio_format *fmt, f32 volume, f32 user, f32 step) { size_t sample_count; f32 limit = MAX(user, volume); switch (camu_audio_format_bytes_per_sample(fmt)) { case 4: sample_count = size / 4; if (fmt->format == CAMU_SAMPLE_FORMAT_S32) { return apply_volume_s32((s32 *)data, sample_count, fmt->channel_count, volume, limit, step); } else if (fmt->format == CAMU_SAMPLE_FORMAT_FLT) { return apply_volume_f32((f32 *)data, sample_count, fmt->channel_count, volume, limit, step); } break; case 2: sample_count = size / 2; if (fmt->format == CAMU_SAMPLE_FORMAT_S16) { return apply_volume_s16((s16 *)data, sample_count, fmt->channel_count, volume, limit, step); } break; } return volume; }