diff options
| author | XANTRONIX Development | 2022-03-15 17:45:12 -0400 | 
|---|---|---|
| committer | XANTRONIX Development | 2022-03-15 17:45:12 -0400 | 
| commit | 1bbe0659cfc4f1ea17e2c05869578959cc11fdfc (patch) | |
| tree | 7a7e90e7fb3b31861810922bedb62de37fc078ab /src | |
| parent | 61af5fa6dfe680e67f1c5b904667b1a9060e0804 (diff) | |
| download | xas-1bbe0659cfc4f1ea17e2c05869578959cc11fdfc.tar.gz xas-1bbe0659cfc4f1ea17e2c05869578959cc11fdfc.tar.bz2 xas-1bbe0659cfc4f1ea17e2c05869578959cc11fdfc.zip | |
Implement polyphonic synth streams
Implement polyphonic synth streams by allowing one to create a new audio
source passing multiple streams at once, wherein each synth is sampled
and merged with the final stream output
Diffstat (limited to 'src')
| -rw-r--r-- | src/synth.c | 89 | 
1 files changed, 89 insertions, 0 deletions
| diff --git a/src/synth.c b/src/synth.c index 596539f..56bbe5b 100644 --- a/src/synth.c +++ b/src/synth.c @@ -4,6 +4,11 @@  #include <xas/synth.h> +struct poly { +    xas_synth **synths; +    size_t count; +}; +  static int16_t sample_sine(xas_synth *synth) {      int16_t ret;      static float tau = 2.0f * M_PI; @@ -220,3 +225,87 @@ xas_audio_stream *xas_synth_stream_new(xas_synth *synth) {                                            synth->buffer_size,                                            synth);  } + +static ssize_t poly_fill(struct poly *poly, int16_t *samples, size_t count) { +    size_t s; + +    for (s=0; s<count; s++) { +        samples[s] = 0; + +        size_t i; + +        for (i=0; i<poly->count; i++) { +            xas_synth *synth = poly->synths[i]; + +            samples[s] += synth->sample(synth); +        } +    } + +    return count; +} + +static void poly_cleanup(struct poly *poly) { +    free(poly->synths); +    free(poly); +} + +xas_audio_stream *xas_synth_stream_new_poly(xas_synth **synths, +                                                size_t count) { +    struct poly *poly; +    size_t i; + +    xas_audio_format format; +    size_t buffer_size; + +    if (count == 0) { +        errno = EINVAL; + +        goto error_invalid_count; +    } + +    format      = synths[0]->format; +    buffer_size = synths[0]->buffer_size; + +    if ((poly = malloc(sizeof(*poly))) == NULL) { +        goto error_malloc_poly; +    } + +    if ((poly->synths = malloc(count * sizeof(xas_synth *))) == NULL) { +        goto error_malloc_synths; +    } + +    for (i=0; i<count; i++) { +        if (!xas_audio_format_eq(synths[i]->format, format)) { +            errno = EINVAL; + +            goto error_invalid_format; +        } + +        if (synths[i]->buffer_size != buffer_size) { +            errno = EINVAL; + +            goto error_invalid_buffer_size; +        } + +        poly->synths[i] = synths[i]; +    } + +    poly->count = count; + +    return xas_audio_stream_new_source((xas_audio_fill)poly_fill, +                                         (xas_audio_cleanup)poly_cleanup, +                                         format, +                                         buffer_size, +                                         poly); + +error_invalid_buffer_size: +error_invalid_format: +    free(poly->synths); + +error_malloc_synths: +    free(poly); + +error_malloc_poly: +error_invalid_count: +    return NULL; +} | 
 
    