sointu/tests/test_render_samples_api.c
5684185+vsariola@users.noreply.github.com 00850c8001 code/text formatting and cleaning up whitespace
2023-09-24 10:47:54 +03:00

143 lines
4.3 KiB
C

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sointu.h>
#define BPM 100
#define SAMPLE_RATE 44100
#define LENGTH_IN_ROWS 16
#define SAMPLES_PER_ROW SAMPLE_RATE * 4 * 60 / (BPM * 16)
const int su_max_samples = SAMPLES_PER_ROW * LENGTH_IN_ROWS;
int main(int argc, char *argv[])
{
Synth *synth;
float *buffer;
const unsigned char commands[] = {SU_ENVELOPE_ID, // MONO
SU_ENVELOPE_ID, // MONO
SU_OUT_ID + 1, // STEREO
SU_ADVANCE_ID}; // MONO
const unsigned char values[] = {64, 64, 64, 80, 128, // envelope 1
95, 64, 64, 80, 128, // envelope 2
128};
int errcode;
int time;
int samples;
int totalrendered;
int retval;
// initialize Synth
synth = (Synth *)malloc(sizeof(Synth));
memset(synth, 0, sizeof(Synth));
memcpy(synth->Commands, commands, sizeof(commands));
memcpy(synth->Values, values, sizeof(values));
synth->NumVoices = 1;
synth->Polyphony = 0;
synth->RandSeed = 1;
// initialize Buffer
buffer = (float *)malloc(2 * sizeof(float) * su_max_samples);
// triger first voice
synth->SynthWrk.Voices[0].Note = 64;
synth->SynthWrk.Voices[0].Sustain = 1;
totalrendered = 0;
// First check that when we render using su_render with 0 time
// we get nothing done
samples = su_max_samples;
time = 0;
errcode = su_render(synth, buffer, &samples, &time);
if (errcode != 0)
goto fail;
if (samples > 0)
{
printf("su_render rendered samples, despite it should not\n");
goto fail;
}
if (time > 0)
{
printf("su_render advanced time, despite it should not\n");
goto fail;
}
// Then check that when we render using su_render with 0 samples,
// we get nothing done
samples = 0;
time = INT32_MAX;
errcode = su_render(synth, buffer, &samples, &time);
if (errcode != 0)
goto fail;
if (samples > 0)
{
printf("su_render rendered samples, despite it should not\n");
goto fail;
}
if (time > 0)
{
printf("su_render advanced time, despite it should not\n");
goto fail;
}
// Then check that each time we call render, only SAMPLES_PER_ROW
// number of samples are rendered
for (int i = 0; i < 16; i++)
{
// Simulate "small buffers" i.e. render a buffer with 1 sample
// check that buffer full
samples = 1;
time = INT32_MAX;
errcode = su_render(synth, &buffer[totalrendered * 2], &samples, &time);
if (errcode != 0)
goto fail;
totalrendered += samples;
if (samples != 1)
{
printf("su_render should have return 1, as it should have believed buffer is full");
goto fail;
}
if (time != 1)
{
printf("su_render should have advanced the time also by one");
goto fail;
}
samples = SAMPLES_PER_ROW - 1;
time = INT32_MAX;
errcode = su_render(synth, &buffer[totalrendered * 2], &samples, &time);
if (errcode != 0)
goto fail;
totalrendered += samples;
if (samples != SAMPLES_PER_ROW - 1)
{
printf("su_render should have return SAMPLES_PER_ROW - 1, as it should have believed buffer is full");
goto fail;
}
if (time != SAMPLES_PER_ROW - 1)
{
printf("su_render should have advanced the time also by SAMPLES_PER_ROW - 1");
goto fail;
}
if (i == 8)
synth->SynthWrk.Voices[0].Sustain = 0;
}
if (totalrendered != su_max_samples)
{
printf("su_render should have rendered a total of su_max_samples");
goto fail;
}
retval = 0;
finish:
free(synth);
free(buffer);
return retval;
fail:
if (errcode > 0)
{
if ((errcode & 0xFF00) != 0)
printf("FPU stack was not empty on exit\n");
if ((errcode & 0x04) != 0)
printf("FPU zero divide\n");
if ((errcode & 0x01) != 0)
printf("FPU invalid operation\n");
if ((errcode & 0x40) != 0)
printf("FPU stack error\n");
}
retval = 1;
goto finish;
}