+ /*
+ * Copy data and move edit flags to commit flags
+ * ------------------------------------------------------------- */
+ audio_lock();
+
+ v3_copy( vg_audio.external_listener_pos, vg_audio.internal_listener_pos );
+ v3_copy( vg_audio.external_listener_ears, vg_audio.internal_listener_ears );
+ v3_copy( vg_audio.external_lister_velocity,
+ vg_audio.internal_listener_velocity );
+ vg_audio.internal_global_volume = vg_audio.external_global_volume;
+
+ for( int i=0; i<AUDIO_CHANNELS; i++ ){
+ audio_channel *ch = &vg_audio.channels[i];
+
+ if( !ch->allocated )
+ continue;
+
+ if( ch->activity == k_channel_activity_alive ){
+ if( (ch->cursor >= ch->source_length) &&
+ !(ch->flags & AUDIO_FLAG_LOOP) )
+ {
+ ch->activity = k_channel_activity_end;
+ }
+ }
+
+ /* process relinquishments */
+ if( (ch->activity != k_channel_activity_reset) && ch->_.relinquished ){
+ if( (ch->activity == k_channel_activity_end)
+ || (ch->_.volume == 0.0f)
+ || (ch->activity == k_channel_activity_error) )
+ {
+ ch->_.relinquished = 0;
+ ch->allocated = 0;
+ ch->activity = k_channel_activity_reset;
+ continue;
+ }
+ }
+
+ /* process new channels */
+ if( ch->activity == k_channel_activity_reset ){
+ ch->_ = ch->editable_state;
+ ch->cursor = 0;
+ ch->source_length = 0;
+ ch->activity = k_channel_activity_wake;
+ }
+
+ if( ch->editble_state_write_mask & AUDIO_EDIT_OWNERSHIP )
+ ch->_.relinquished = ch->editable_state.relinquished;
+ else
+ ch->editable_state.relinquished = ch->_.relinquished;
+
+
+ if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME ){
+ ch->_.volume = ch->editable_state.volume;
+ ch->_.volume_target = ch->editable_state.volume;
+ }
+ else{
+ ch->editable_state.volume = ch->_.volume;
+ }
+
+
+ if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME_SLOPE ){
+ ch->volume_movement_start = ch->_.volume;
+ ch->volume_movement = 0;
+
+ ch->_.volume_target = ch->editable_state.volume_target;
+ ch->_.volume_rate = ch->editable_state.volume_rate;
+ }
+ else{
+ ch->editable_state.volume_target = ch->_.volume_target;
+ ch->editable_state.volume_rate = ch->_.volume_rate;
+ }
+
+
+ if( ch->editble_state_write_mask & AUDIO_EDIT_SAMPLING_RATE )
+ ch->_.sampling_rate = ch->editable_state.sampling_rate;
+ else
+ ch->editable_state.sampling_rate = ch->_.sampling_rate;
+
+
+ if( ch->editble_state_write_mask & AUDIO_EDIT_LFO_ATTACHMENT ){
+ ch->_.lfo = ch->editable_state.lfo;
+ ch->_.lfo_amount = ch->editable_state.lfo_amount;
+ }
+ else{
+ ch->editable_state.lfo = ch->_.lfo;
+ ch->editable_state.lfo_amount = ch->_.lfo_amount;
+ }
+
+
+ if( ch->editble_state_write_mask & AUDIO_EDIT_SPACIAL )
+ v4_copy( ch->editable_state.spacial_falloff,ch->_.spacial_falloff );
+ else
+ v4_copy( ch->_.spacial_falloff,ch->editable_state.spacial_falloff );
+
+
+ /* currently readonly, i guess */
+ ch->editable_state.pan_target = ch->_.pan_target;
+ ch->editable_state.pan = ch->_.pan;
+ ch->editble_state_write_mask = 0x00;
+ }
+
+ for( int i=0; i<AUDIO_LFOS; i++ ){
+ audio_lfo *lfo = &vg_audio.oscillators[ i ];
+
+ if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_WAVE ){
+ lfo->_.wave_type = lfo->editable_state.wave_type;
+
+ if( lfo->_.wave_type == k_lfo_polynomial_bipolar ){
+ lfo->_.polynomial_coefficient =
+ lfo->editable_state.polynomial_coefficient;
+ lfo->sqrt_polynomial_coefficient =
+ sqrtf(lfo->_.polynomial_coefficient);
+ }
+ }
+
+ if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_PERIOD ){
+ if( lfo->_.period ){
+ float t = lfo->time;
+ t/= (float)lfo->_.period;
+
+ lfo->_.period = lfo->editable_state.period;
+ lfo->time = lfo->_.period * t;
+ }
+ else{
+ lfo->time = 0;
+ lfo->_.period = lfo->editable_state.period;
+ }
+ }
+
+ lfo->editble_state_write_mask = 0x00;
+ }
+
+ dsp_update_tunings();
+ audio_unlock();
+
+ /*
+ * Process spawns
+ * ------------------------------------------------------------- */
+ for( int i=0; i<AUDIO_CHANNELS; i++ ){
+ audio_channel *ch = &vg_audio.channels[i];
+
+ if( ch->activity == k_channel_activity_wake ){
+ if( audio_channel_load_source( ch ) )
+ ch->activity = k_channel_activity_alive;
+ else
+ ch->activity = k_channel_activity_error;
+ }
+ }