Look at Bigarray module: http://caml.inria.fr/pub/docs/manual-ocaml/manual043.html http://pauillac.inria.fr/cdrom/www/caml/ocaml/htmlman/manual042.html http://jhenrikson.org/forklift/checkout/doc/higher_order.html From : http://webcvs.freedesktop.org/cairo/cairo-ocaml/test/basket.ml?revision=1.7&view=markup begin prerr_endline "Bigarray, PPM and PNG (ARGB32) " ; let arr = Bigarray.Array2.create Bigarray.int32 Bigarray.c_layout (int_of_float y_inches * 72) (int_of_float x_inches * 72) in Bigarray.Array2.fill arr 0xffffffl ; let s = Cairo_bigarray.of_bigarr_32 ~alpha:true arr in let c = Cairo.create s in draw c ; do_file_out "basket.ppm" (fun oc -> Cairo_bigarray.write_ppm_int32 oc arr) ; Cairo_png.surface_write_to_file s "basket.png" end =========================================================================== Actually many scientific OCaml libraries use the bigarray module. It is also the case of Lacaml (a binding to LAPACK) or FFTW (a binding to, hum, FFTW!). Now I do not understand why you could not have a function val read_array1 : t -> ('a,'b,'c) Bigarray.Array1.t -> int Sndfile.read_array1 f a read data from the file f into the supplied bigarray a and return the number of float values read. For multi-channel files, the array length must be an integer multiple of the number of channels. The idea is that the read function adapts the type of the bigarray passed (if possible; if not, raise an exception). One could also require that a Bigarray.Array2.t is used with one of its dimensions being the number of channels (if possible allowing easy slicing to extract a given channel). Same goes for a write function. BTW, the last part of the comment is a bit laconic: one wonders "or what ?". An exception is raised ? The array slots with higher indexes are never filled ? Garbage can be returned ? etc. > I was particularly interested if there was any utility to providing > functions for accessing shorts or ints. So far noone has come up > with a need for these. I did not follow thoroughly the discussion but there is an Int32 module and the C interface has "Int32_val(v)" and "Int64_val(v)". To create a caml Int32.t (resp. Int64.t), you must allocate a custom block containing an "int32" (resp. int64). See section 18 of the manual. =========================================================================== (* cairo_bigarray.mli *) (* open Bigarray val of_bigarr : ('a, 'b, c_layout) Array2.t -> Cairo.format -> width:int -> height:int -> stride:int -> Cairo.image_surface val of_bigarr_32 : alpha:bool -> (int32, int32_elt, c_layout) Array2.t -> Cairo.image_surface val of_bigarr_24 : (int, int_elt, c_layout) Array2.t -> Cairo.image_surface val of_bigarr_8 : (int, int8_unsigned_elt, c_layout) Array2.t -> Cairo.image_surface val write_ppm_int32 : out_channel -> (int32, int32_elt, c_layout) Array2.t -> unit val write_ppm_int : out_channel -> (int, int_elt, c_layout) Array2.t -> unit *) (* cairo_bigarray.ml *) (* open Bigarray external bigarray_kind_float : ('a, 'b, c_layout) Array2.t -> bool = "ml_bigarray_kind_float" external bigarray_byte_size : ('a, 'b, c_layout) Array2.t -> int = "ml_bigarray_byte_size" external image_surface_create : ('a, 'b, c_layout) Array2.t -> Cairo.format -> width:int -> height:int -> stride:int -> Cairo.image_surface = "ml_cairo_image_surface_create_for_data" let of_bigarr arr format ~width ~height ~stride = if bigarray_kind_float arr then invalid_arg "wrong Bigarray kind" ; if bigarray_byte_size arr < stride * height then invalid_arg "Bigarray too small" ; image_surface_create arr format width height stride let of_bigarr_32 ~alpha (arr : (int32, int32_elt, c_layout) Array2.t) = let h = Array2.dim1 arr in let w = Array2.dim2 arr in of_bigarr arr (if alpha then Cairo.FORMAT_ARGB32 else Cairo.FORMAT_RGB24) w h (4 * w) let of_bigarr_24 (arr : (int, int_elt, c_layout) Array2.t) = if Sys.word_size <> 32 then failwith "your ints have 63 bits" ; let h = Array2.dim1 arr in let w = Array2.dim2 arr in of_bigarr arr Cairo.FORMAT_RGB24 w h (4 * w) let of_bigarr_8 (arr : (int, int8_unsigned_elt, c_layout) Array2.t) = let h = Array2.dim1 arr in let w = Array2.dim2 arr in of_bigarr arr Cairo.FORMAT_A8 w h w let output_pixel oc p = let r = (p lsr 16) land 0xff in output_byte oc r ; let g = (p lsr 8) land 0xff in output_byte oc g ; let b = p land 0xff in output_byte oc b let write_ppm_int32 oc (arr : (int32, int32_elt, c_layout) Array2.t) = let h = Array2.dim1 arr in let w = Array2.dim2 arr in Printf.fprintf oc "P6 %d %d 255\n" w h ; for i=0 to pred h do for j=0 to pred w do output_pixel oc (Int32.to_int arr.{i, j}) done done ; flush oc let write_ppm_int oc (arr : (int, int_elt, c_layout) Array2.t) = let h = Array2.dim1 arr in let w = Array2.dim2 arr in Printf.fprintf oc "P6 %d %d 255\n" w h ; for i=0 to pred h do for j=0 to pred w do output_pixel oc arr.{i, j} done done ; flush oc *)