////////////////////////////////
// SOUND: Functions

MR4TH_SYMBOL_STATIC DSP_Signal*
sound_signal_from_channel(Arena *arena, SOUND_Data *data, U64 channel_idx){
  ArenaTemp scratch = arena_get_scratch(&arena, 1);
  
  DSP_Signal *result = 0;
  if (channel_idx < data->channel_count){
    // allocate output samples
    F32 *samples = push_array(arena, F32, data->sample_count);
    
    BOP_Data *samples_buffer =
      bop_ptr(scratch.arena, sizeof(F32), data->sample_count, samples);
    
    // pull out channel data
    void *channel_raw = data->channels[channel_idx];
    BOP_Data *channel_buffer =
      bop_ptr(scratch.arena, data->bytes_per_value,
              data->sample_count, channel_raw);
    
    // write to samples ~ converting to F32
    if (1 <= data->value_kind &&
        data->value_kind <= 64){
      U32 numbits = data->value_kind;
      bop_f32_from_signed(samples_buffer, channel_buffer, numbits);
    }
    else{
      switch (data->value_kind){
        case SOUND_ValueKind_Float16: break;
        
        case SOUND_ValueKind_Float32:
        {
          MemoryCopy(samples, channel_raw, sizeof(F32)*data->sample_count);
        }break;
        
        case SOUND_ValueKind_Float64:
        {
          bop_f32_from_f64(samples_buffer, channel_buffer);
        }break;
      }
    }
    
    // construct result signal
    result = dsp_new_ptr(arena, samples, data->sample_count, data->samples_per_second);
  }
  
  arena_release_scratch(&scratch);
  
  return(result);
}

