Skip to content

Commit 3dc11d0

Browse files
committed
Add audio callback example
1 parent e6cf76a commit 3dc11d0

File tree

7 files changed

+112
-11
lines changed

7 files changed

+112
-11
lines changed

examples/audio/audio_raw_stream.ml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
open Raylib
2+
3+
let width = 800.
4+
let max_samples = 512
5+
let frequency = ref 440.0
6+
let audio_frequency = ref 440.0
7+
let data = Array.make max_samples 0.0
8+
let sine_idx = ref 0.0
9+
10+
let audio_input_callback buf (frames : Unsigned.uint) =
11+
audio_frequency := !frequency +. ((!audio_frequency -. !frequency) *. 0.95);
12+
13+
let incr = !audio_frequency /. 44100.0 in
14+
let shortbuf = Ctypes.(coerce (ptr void) (ptr short) buf) in
15+
let iframes = Unsigned.UInt.to_int frames in
16+
let d = Ctypes.CArray.from_ptr shortbuf iframes in
17+
for i = 0 to iframes - 1 do
18+
Ctypes.CArray.set d i
19+
(int_of_float (23000.0 *. sin (2.0 *. Float.pi *. !sine_idx)));
20+
sine_idx := !sine_idx +. incr;
21+
if Float.compare !sine_idx 1.0 > 0 then sine_idx := !sine_idx -. 1.0
22+
done;
23+
()
24+
25+
let setup () =
26+
init_window (int_of_float width) 450
27+
"raylib [audio] example - raw audio streaming";
28+
init_audio_device ();
29+
set_audio_stream_buffer_size_default 4096;
30+
let stream = load_audio_stream 44100 16 1 in
31+
Raylib_callbacks.set_audio_stream_callback stream audio_input_callback;
32+
play_audio_stream stream;
33+
set_target_fps 30;
34+
(stream, 1.0)
35+
36+
let rec run (stream, old_frequency) =
37+
if window_should_close () then (
38+
unload_audio_stream stream;
39+
close_audio_device ();
40+
close_window ())
41+
else
42+
let mouse_pos = get_mouse_position () in
43+
44+
if is_mouse_button_down MouseButton.Left then (
45+
let fp = Vector2.y mouse_pos in
46+
let pan = Vector2.x mouse_pos /. width in
47+
set_audio_stream_pan stream pan;
48+
frequency := 40.0 +. fp);
49+
50+
if !frequency <> old_frequency then (
51+
let wavelength = 22050.0 /. !frequency |> int_of_float in
52+
let wavelength =
53+
if wavelength > max_samples / 2 then max_samples / 2
54+
else if wavelength < 1 then 1
55+
else wavelength
56+
in
57+
58+
(* write sine wave *)
59+
for i = 0 to (wavelength * 2) - 1 do
60+
let value =
61+
sin Float.(pi *. 2.0 *. of_int i /. of_int wavelength) *. 32000.0
62+
in
63+
Array.set data i value
64+
done;
65+
for j = wavelength * 2 to max_samples - 1 do
66+
Array.set data j 0.0
67+
done);
68+
69+
begin_drawing ();
70+
clear_background Color.raywhite;
71+
draw_text
72+
(Format.sprintf "sine frequency: %i" (int_of_float !frequency))
73+
(get_screen_width () - 220)
74+
10 20 Color.red;
75+
draw_text "click mouse button to change frequency or pan" 10 10 20
76+
Color.darkgray;
77+
78+
for i = 0 to int_of_float width - 1 do
79+
let y =
80+
250.0
81+
+. 50.0
82+
*. Array.get data (i * max_samples / int_of_float width)
83+
/. 32000.0
84+
in
85+
draw_pixel_v (Vector2.create (float_of_int i) y) Color.red
86+
done;
87+
88+
end_drawing ();
89+
run (stream, !frequency)
90+
91+
let () = setup () |> run

examples/audio/dune

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@
77
(name audio_music_stream)
88
(modules Audio_music_stream)
99
(libraries raylib))
10+
11+
(executable
12+
(name audio_raw_stream)
13+
(modules Audio_raw_stream)
14+
(libraries raylib raylib-callbacks))

src/c/raygui/functions.ml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,8 @@ module Functions (F : Ctypes.FOREIGN) = struct
171171
(* List View with extended parameters *)
172172
let _list_view_ex =
173173
foreign "GuiListViewEx"
174-
(Raylib.Rectangle.t
175-
@-> ptr (const string)
176-
@-> int @-> ptr int @-> ptr int @-> int @-> returning int)
174+
(Raylib.Rectangle.t @-> ptr string @-> int @-> ptr int @-> ptr int @-> int
175+
@-> returning int)
177176

178177
(* Message Box control, displays a message *)
179178
let _message_box =

src/c/raylib_callbacks/functions.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module Functions (F : Ctypes.FOREIGN) = struct
55
open Raylib_c.Types
66

77
let audio_callback =
8-
Foreign.funptr Ctypes.(ptr void @-> uint @-> returning void)
8+
Foreign.funptr ~thread_registration:true ~runtime_lock:true
9+
Ctypes.(ptr void @-> uint @-> returning void)
910

1011
let set_audio_stream_callback =
1112
foreign "SetAudioStreamCallback"

src/callbacks/dune

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
(library
2-
(name callbacks)
2+
(name raylib_callbacks)
33
(public_name raylib-callbacks)
4-
(libraries raylib raylib_callbacks_c))
4+
(libraries raylib raylib_callbacks_c ctypes-foreign))
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,26 @@
33
type audio_callback = unit Ctypes.ptr -> Unsigned.uint -> unit
44

55
val set_audio_stream_callback : Raylib.AudioStream.t -> audio_callback -> unit
6-
(** [set_audio_stream_callback stream callback] Audio thread callback to request new data*)
6+
(** [set_audio_stream_callback stream callback] Audio thread callback to request
7+
new data*)
78

89
val attach_audio_stream_processor :
910
Raylib.AudioStream.t -> audio_callback -> unit
10-
(** [attach_audio_stream_processor stream processor] Attach audio stream processor to stream, receives the samples as 'float'*)
11+
(** [attach_audio_stream_processor stream processor] Attach audio stream
12+
processor to stream, receives the samples as 'float'*)
1113

1214
val detach_audio_stream_processor :
1315
Raylib.AudioStream.t -> audio_callback -> unit
14-
(** [detach_audio_stream_processor stream processor] Detach audio stream processor from stream*)
16+
(** [detach_audio_stream_processor stream processor] Detach audio stream
17+
processor from stream*)
1518

1619
val attach_audio_mixed_processor : audio_callback -> unit
17-
(** [attach_audio_mixed_processor processor] Attach audio stream processor to the entire audio pipeline, receives the samples as 'float'*)
20+
(** [attach_audio_mixed_processor processor] Attach audio stream processor to
21+
the entire audio pipeline, receives the samples as 'float'*)
1822

1923
val detach_audio_mixed_processor : audio_callback -> unit
20-
(** [detach_audio_mixed_processor processor] Detach audio stream processor from the entire audio pipeline*)
24+
(** [detach_audio_mixed_processor processor] Detach audio stream processor from
25+
the entire audio pipeline*)
2126

2227
(** File callbacks *)
2328

0 commit comments

Comments
 (0)