123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687moduleSystem=structexternalenv_logger_init_raw:unit->unit="env_logger_init"letis_initialized=reffalseletenv_logger_init()=ifnot!is_initializedthen(is_initialized:=true;env_logger_init_raw())endmoduleWav=structexternalread_wav_file_mono_exn_raw:string->floatarray="read_wav_file_mono"letread_wav_file_mono_exnpath=(* TODO: This array can't be indexed with [Array.get] but values can be
obtained with (say) [Array.iter]. This is possibly a bug in the ocaml
rust bindings for the [floatarray] special case. *)letbroken_array=read_wav_file_mono_exn_rawpathinFloat.Array.of_seq(Array.to_seqbroken_array)endmoduleOutput_stream=structtypetexternalcreate_with_downsample_32:int32->t="create_output_stream_with_downsample"externalsample_rate_hz_32:t->int32="sample_rate_hz"letsample_rate_hzt=sample_rate_hz_32t|>Int32.to_intexternalnum_channels_32:t->int32="num_channels"letnum_channelst=num_channels_32t|>Int32.to_intexternalset_buffer_padding_32:t->int32->unit="set_buffer_padding"letset_buffer_paddingtbuffer_padding=set_buffer_padding_32t(Int32.of_intbuffer_padding)letcreate?(downsample=1)()=letstream=create_with_downsample_32(Int32.of_intdownsample)inset_buffer_paddingstream2500;streamexternalsamples_behind_32:t->int32="samples_behind"letsamples_behindt=samples_behind_32t|>Int32.to_intexternalsend_sample:t->float->unit="send_sample"endmoduleMidi_input=structtypetexternalcreate:unit->t="create_midi_input"externalmidi_port_names_raw:t->stringarray="midi_port_names"externalget_num_midi_ports_raw:t->int32="get_num_midi_ports"externalis_midi_input_available_raw:t->bool="is_midi_input_available"externalmidi_port_connect_raw:t->int32->unit="midi_port_connect"externalmidi_port_drain_messages_raw:t->int32array="midi_port_drain_messages"letport_namest=midi_port_names_rawt|>Array.to_listletget_num_portst=get_num_midi_ports_rawt|>Int32.to_intletport_connecttindex=letnum_ports=get_num_portstinifindex<num_portsthenifis_midi_input_available_rawtthenmidi_port_connect_rawt(Int32.of_intindex)elsefailwith"Midi input may only be used to connect to a single port (ever)"elsefailwith(Printf.sprintf"Midi port index %d is out of range (there are %d midi ports)"indexnum_ports)letport_drain_messages_to_char_arrayt=midi_port_drain_messages_rawt|>Array.map(funi32->char_of_int(Int32.to_inti32))end