Kirika/cgo/audio.h
2022-02-22 10:35:08 +01:00

121 lines
4.1 KiB
C

#include <stdint.h>
#include <string.h>
#include <math.h>
#define BITS_TO_DIV(b) (float)((1 << (b - 1)) - 1)
__attribute__((weak)) void audio_multiple_channels_to_mono(float* buffer, size_t buffer_len, int channels) {
float f;
switch(channels) {
case 1:
break;
case 2:
for (int i = 0; i < buffer_len; i += 2){
buffer[i/2] = buffer[i] + buffer[i+1];
}
break;
default:
for (int i = 0; i < buffer_len; i += channels){
f = buffer[i];
for (int j = 1; j < channels; ++j) {
f += buffer[i + j];
}
buffer[i/channels] = f / (float)channels;
}
}
}
__attribute__((weak)) void audio_multiple_channels_to_stereo(float* buffer, size_t buffer_len, float* out, int channels) {
float f;
int samples = 0;
float surroundMix = 1 / sqrt(2);
switch(channels) {
case 1: //mono, duplicate channels
for (int i = 0; i < buffer_len; i++){
out[i*2] = buffer[i];
out[i*2+1] = buffer[i];
}
break;
case 2: //copy
memcpy(out, buffer, sizeof(float) * buffer_len);
break;
case 3: //2.1, FL, FR, LFE
for (int i = 0; i < buffer_len; i += 3){
int FL = i;
int FR = i+1;
int LFE = i+2;
out[samples*2] = buffer[FL];
out[samples*2+1] = buffer[FR];
++samples;
}
case 5: //5.0, FL, FR, FC, RL, RR
for (int i = 0; i < buffer_len; i += 5){
int FL = i;
int FR = i+1;
int C = i+2;
int RL = i+3;
int RR = i+4;
out[samples*2] = buffer[FL] + surroundMix * buffer[C] + surroundMix * RL;
out[samples*2+1] = buffer[FR] + surroundMix * buffer[C] + surroundMix * RR;
++samples;
}
case 6: //5.1, FL, FR, FC, LFE, RL, RR
for (int i = 0; i < buffer_len; i += 6){
int FL = i;
int FR = i+1;
int C = i+2;
int LFE = i+3;
int RL = i+4;
int RR = i+5;
out[samples*2] = buffer[FL] + surroundMix * buffer[C] + surroundMix * RL;
out[samples*2+1] = buffer[FR] + surroundMix * buffer[C] + surroundMix * RR;
++samples;
}
break;
default: //no known formula, just take stereo out of it
for (int i = 0; i < buffer_len; i += channels){
out[samples*2] = buffer[i];
out[samples*2+1] = buffer[i+1];
++samples;
}
}
}
__attribute__((weak)) void audio_int32_to_float32(int32_t* restrict data, size_t data_len, float* restrict buffer, int bitDepth){
switch(bitDepth) {
case 16:
for (int i = 0; i < data_len; ++i){
buffer[i] = ((float)data[i]) / BITS_TO_DIV(16);
}
break;
case 24:
for (int i = 0; i < data_len; ++i){
buffer[i] = ((float)data[i]) / BITS_TO_DIV(24);
}
break;
default:
for (int i = 0; i < data_len; ++i){
buffer[i] = ((float)data[i]) / BITS_TO_DIV(bitDepth);
}
}
}
__attribute__((weak)) void audio_int16_to_float32(int16_t* restrict data, size_t data_len, float* restrict buffer, int bitDepth){
switch(bitDepth) {
case 16:
for (int i = 0; i < data_len; ++i){
buffer[i] = ((float)data[i]) / BITS_TO_DIV(16);
}
break;
default:
for (int i = 0; i < data_len; ++i){
buffer[i] = ((float)data[i]) / BITS_TO_DIV(bitDepth);
}
}
}
__attribute__((weak)) void audio_float32_to_int32(float* restrict data, size_t data_len, int32_t* restrict buffer, int bitDepth){
for (int i = 0; i < data_len; ++i){
buffer[i] = (int32_t)(data[i] * BITS_TO_DIV(bitDepth));
}
}