Skip to content

Commit

Permalink
Big changes and updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
SamueleGiraudo committed Aug 20, 2023
1 parent d945051 commit e374d1e
Show file tree
Hide file tree
Showing 152 changed files with 3,869 additions and 1,609 deletions.
10 changes: 5 additions & 5 deletions Examples/Example1.cal
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ scale time 0.25 in
{Global definitions.}

{Define the seven degrees D0, ..., D6 of the natural minor scale.}
let next = put ../Std/Pitch12/NaturalMinor in
let next = put ../Stdlib/Pitch12/NaturalMinor in
let D0 = %1 in
let D1 = D0[next] in
let D2 = D1[next] in
Expand All @@ -26,16 +26,16 @@ let D5 = D4[next] in
let D6 = D5[next] in

{A tool to repeat two times a sound.}
let r2 = put ../Std/Tool/Repeat3 in
let r2 = put ../Stdlib/Tool/Repeat3 in

{A tool to superimpose two phrases without distortion.}
let c2 = put ../Std/Tool/Chord2 in
let c2 = put ../Stdlib/Tool/Chord2 in

{A synthesizer.}
let synth = put ../Std/Synth/WetWood in
let synth = put ../Stdlib/Synth/WetWood in

{A delay effect.}
let eff = put ../Std/Effect/Delay500 in
let eff = put ../Stdlib/Effect/Delay500 in


{Definitions of phrases.}
Expand Down
Binary file removed Examples/Example1.png
Binary file not shown.
Binary file removed Examples/Example1.wav
Binary file not shown.
15 changes: 9 additions & 6 deletions Examples/Example2.cal
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ scale cycles 110 in
{Sets the unit of time to 0.35 s.}
scale time 0.35 in

{Reduces the general volume.}
scale vertical 0.3 in


{Global definitions.}

{Define the seven degrees D0, ..., D6 of the Phrygian scale.}
let next = put ../Std/Pitch12/Phrygian in
let next = put ../Stdlib/Pitch12/Phrygian in
let D0 = %1 in
let D1 = D0[next] in
let D2 = D1[next] in
Expand All @@ -23,20 +26,20 @@ let D5 = D4[next] in
let D6 = D5[next] in

{A tool to create silences.}
let s = put ../Std/Tool/Silence in
let s = put ../Stdlib/Tool/Silence in

{A tool to create an empty phrase. This is useful to alter a phrase by deleting some of its
notes by compositions.}
let e = put ../Std/Tool/Empty in
let e = put ../Stdlib/Tool/Empty in

{A tool to repeat two times a sound.}
let r2 = put ../Std/Tool/Repeat2 in
let r2 = put ../Stdlib/Tool/Repeat2 in

{A tool to superimpose two phrases without distortion.}
let c2 = put ../Std/Tool/Chord2 in
let c2 = put ../Stdlib/Tool/Chord2 in

{A synthesizer.}
let synth = put ../Std/Synth/EveningFlight in
let synth = put ../Stdlib/Synth/EveningFlight in


{Definitions of phrases.}
Expand Down
Binary file removed Examples/Example2.png
Binary file not shown.
Binary file removed Examples/Example2.wav
Binary file not shown.
4 changes: 4 additions & 0 deletions Help.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ lang: en
fontsize: 10 pt
---

WARNING: This page is completely out of date. A new updated version is planned in the
medium/long term (August 2023).


This page describes the way to build programs in the Calimba language. This is the official
documentation of the language.

Expand Down
17 changes: 11 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
# Author: Samuele Giraudo
# Creation: may 2022
# Modifications: may 2022, aug. 2022
# Modifications: may 2022, aug. 2022, nov. 2022, jul. 2023

CC = ocamlbuild
FLAGS = -r -cflags -w,A-4-70
LIBS = -libs str,unix -package extlib -tag thread -use-menhir
FLAGS = -r -cflags -w,A-4-70 -menhir "menhir --explain"
#-tag debug -tag "optimize(2)" -tag "optimization_rounds(4)"
LIBS =-package unix -package extlib -tag thread -use-menhir

NAME = calimba
EXEC = Main.native
SRC_DIR = Sources

NAME = calimba
EXEC = Calimba.native

.PHONY: all
all:
all: $(NAME)

.PHONY: $(NAME)
$(NAME):
$(CC) $(FLAGS) $(LIBS) $(SRC_DIR)/$(EXEC)
mv -f $(EXEC) $(NAME)

Expand Down
60 changes: 25 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Calimba
`<</^\|_`
`<</\|_`

A programming language to create music based on the theory of operads and clones.

Copyright (C) 2020--2022 [Samuele Giraudo](https://igm.univ-mlv.fr/~giraudo/) -
`samuele.giraudo@univ-eiffel.fr` -
Copyright (C) 2020--2023 [Samuele Giraudo](https://igm.univ-mlv.fr/~giraudo/) -
`giraudo[email protected]` -


Here is a [Discord server](https://discord.gg/n6Du2Q4QFb) for discussions about this
Expand All @@ -26,13 +26,9 @@ the documentation of the language are [here](Help.md).
## First examples
Here are some simple and commentated examples illustrating some features of the language:

+ [A Calimba program](Examples/Example1.cal) playing a harmonic progression. Here is the
corresponding [WAV file](Examples/Example1.wav) to listen it, and the [PNG
file](Examples/Example1.png) of a picture of the wave of the sound.
+ [A Calimba program](Examples/Example1.cal) playing a harmonic progression.
+ [A Calimba program](Examples/Example2.cal) playing a pattern modified by the composition
operation (the fundamental operation of the language). Here is the corresponding [WAV
file](Examples/Example2.wav) to listen it, and the [PNG file](Examples/Example2.png) of a
picture of the wave of the sound.
operation (the fundamental operation of the language).


## Versions
Expand All @@ -48,7 +44,7 @@ The following programs or libraries are needed:

+ `pkg-config`
+ `make`
+ `ocaml` (Version `>= 4.13.1`. An inferior but not too old version may be suitable.)
+ `ocaml` (Version `>= 5.0.0`. An inferior but not too old version may be suitable.)
+ `opam`
+ `ocamlbuild` (Available by `opam install ocamlbuild`.)
+ `ocamlfind` (Available by `opam install ocamlfind`.)
Expand All @@ -72,37 +68,31 @@ This creates an executable `calimba`. The following sections explain how to use
## User guide
This [page](Help.md) contains the description of the Calimba language.

Calimba files have `.cal` as extension. Given such a file `Program.cal`, the command
Calimba program files must have `.cal` as extension. The main command is

+ `./calimba -f Program.cal -p` generates the sound specified by the program and starts
playing it once the ENTER key is pressed;
```
./calimba [--help] [--version] --file PATH [--verbose] [--bunch START LEN] [--text]
[--write] [--draw] [--play]
```

+ `./calimba -f Program.cal -w` creates the PCM file `Program_N.pcm` containing the sound
specified by the program. `N` is the smallest decimal value starting from `0` so that the
target file does not preexist. The default sampling rate is $48000$ Hz and the depth is
$4$ bytes (signed 32 bytes).
where

+ `./calimba -f Program.cal -d` creates a SVG file `Program_N.svg` containing the wave of
the sound specified by the program. `N` is the smallest decimal value starting from `0` so
that the target file does not preexist.

+ `./calimba -f Program.cal -e` creates a CAL file `Program_N.cal` containing the processed
version of the expression specified by the program. `N` is the smallest decimal value
starting from `0` so that the target file does not preexist.

These four commands can be followed by `-b START LENGTH` where START is the starting time
and LENGTH is the length of the desired bunch of the sound. These values are in seconds and
are optional. For instance,

+ `./calimba -f Program.cal -p -b 8 3.5` plays the sound specified by the program starting
from $8$ s and lasting $3.5$ s;
+ `./calimba -f Program.cal -w -b 10` creates the PCM file of the sound specified by the
program starting from $10$ s.
+ `--help` prints the short help.
+ `--version` prints the version and other information.
+ `--file PATH` sets `PATH` as the path to the Qlusster program to consider.
+ `--verbose` enables the verbose mode.
+ `--bunch START LEN` specifies the part of the generated signal to consider, with its
starting time `START` and length `LEN` in seconds.
+ `--text` creates the CAL file containing the processed expression specified the program.
+ `--write` creates the PCM file specified by the program.
+ `--draw` creates the SVG and PNG files specified by the program.
+ `--play` plays the signal specified by the program.


### Standard library
The [standard library](Std) contains definitions of synthesizers, effects, scales,
transformations (repetitions, chords, let ring constructions), and randomization tools.
The [standard library](Stdlib) contains definitions of synthesizers (trying to mimic some
existing ones), effects, scales, transformations (repetitions, chords, let ring
constructions), and randomization tools.


### Documentation of the standard library
Expand Down
84 changes: 84 additions & 0 deletions Sources/Arguments.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
(* Author: Samuele Giraudo
* Creation: (jul 2020), jul. 2023
* Modifications: jul. 2023
*)

(* Management of arguments.
*
* Here are some definitions:
*
* - An ARGUMENT is any word following the executable name when the executable is
* launched.
* For instance, if the executable name is x and the executable is launched with
* x -o v1 v2 --opt2 v3
* then -o, v1, v2 , --opt2, and v3 are the arguments.
*
* - A SHORT OPTION is any argument of the form -C where C is a character.
*
* - A LONG OPTION is any argument of the form --STR where STR is a string.
*
* - A VALUE of a (short or long) argument is a word following a (short or long) argument
* or following itself a value.
* For instance in
* -o v1 v2 --opt2 v3 v4 v5 --opt3
* v1 and v2 are values of -o, v3, v4, and v5 are values of --opt2, and --opt3 has no
* values.
*)

(* Tests if the string arg can be a short option name. *)
let is_short_option_name arg =
String.length arg >= 2 && String.get arg 0 = '-' && String.get arg 1 <> '-'

(* Tests if the string arg can be a long option name. *)
let is_long_option_name arg =
String.length arg >= 3 && String.get arg 0 = '-' && String.get arg 1 = '-'
&& String.get arg 2 <> '-'

(* Tests if the string arg can be a value name. *)
let is_value_name arg =
String.length arg >= 1 && String.get arg 0 <> '-'

(* Tests if the string arg can be an argument name. *)
let is_argument_name arg =
is_short_option_name arg || is_long_option_name arg || is_value_name arg

(* Returns the list of the arguments. *)
let arguments =
let len = Array.length Sys.argv in
let args = List.init (len - 1) (fun i -> Sys.argv.(i + 1)) in
args |> List.filter is_argument_name

(* Tests if the current execution environment admits the string arg as argument. *)
let exists arg =
assert (is_argument_name arg);
List.mem arg arguments

(* Returns the list of the arguments following the argument arg. The returned list is empty
* when arg does not appear as an argument. *)
let arguments_after arg =
assert (is_argument_name arg);
let rec search_suffix args =
match args with
|[] -> []
|x :: args' when x = arg -> args'
|_ :: args' -> search_suffix args'
in
search_suffix arguments

(* Returns the list of the values of the option opt. The empty list is returned when opt is
* not an option. *)
let option_values opt =
assert (is_short_option_name opt || is_long_option_name opt);
let rec longest_prefix_of_values args =
match args with
|x :: args' when is_value_name x -> x :: longest_prefix_of_values args'
|_ -> []
in
opt |> arguments_after |> longest_prefix_of_values

(* Tests if the option name opt is an option and admits the value name v as value. *)
let option_has_value opt v =
assert (is_short_option_name opt || is_long_option_name opt);
assert (is_value_name v);
List.mem v (option_values opt)

17 changes: 17 additions & 0 deletions Sources/Beats.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(* Author: Samuele Giraudo
* Creation: jul. 2023
* Modifications: jul. 2023
*)

(* A type for beats. *)
type beats = Beat of int

(* Returns the index of the beat b. *)
let index b =
let Beat index = b in
index

(* Returns a string representation of the beat b. *)
let to_string b =
Printf.sprintf "%%%d" (index b)

Loading

0 comments on commit e374d1e

Please sign in to comment.