#include #include #include #include "mossrose.h" #include "mossrose-mutex.h" #include "mossrose-channel.h" /* ~~~~~~~~~~~~~~~~ type definitions ~~~~~~~~~~~~~~~~ */ /* audio output */ struct audio_output_t { float l; float r; }; /* ~~~~~~~~~~~~~~~~ globals ~~~~~~~~~~~~~~~~ */ struct mossrose_globals_t { PaStream *stream; struct mossrose_channel_t *channels; int n_channels; } mossrose_global; struct audio_output_t build_sample() { struct audio_output_t out; out.l = 0; out.r = 0; /* loop variables */ struct mossrose_channel_t *chan; float chan_l, chan_r; for (int i=0; imutex)) != 0) { /* can't lock the mutex, this channel is being modified */ printf("can't lock channel %d\n", i); continue; } if (chan->n_samples == 0) { /* channel is not currently in use, skip */ } else { if (mossrose_channel_advance(&chan_l, &chan_r, chan) != 0) /* channel is done playing, reset */ mossrose_channel_reset(chan); else { out.l += chan_l; out.r += chan_r; } } mossrose_mutex_unlock(&(chan->mutex)); } return out; } static int callback( const void *input, void *output, unsigned long frame_count, const PaStreamCallbackTimeInfo *time_info, void *userdata) { struct audio_output_t *out = output; struct audio_output_t sample; for (int i=0; i 0) { return mossrose_channel_set(mossrose_global.channels+channel, left, right, len, 1); } else { struct mossrose_channel_t *chan; for (int i=0; i