Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new variant: Source 2 WGSL #1511

Draft
wants to merge 26 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
674e250
add implementation for wgsl variant
Ziwen510 Dec 3, 2023
c0d7333
add testing for normal computation process in wgsl variant
Ziwen510 Dec 4, 2023
9ac36ff
add documentation for wgsl variant
Ziwen510 Dec 4, 2023
f4fa105
modify testing for wgsl variant
Ziwen510 Dec 5, 2023
95f3bdb
update snapshots
Ziwen510 Dec 5, 2023
42d7866
Merge branch 'master' into 1510-source-2-wgsl
RichDom2185 Jan 20, 2024
2cb1d28
Merge branch 'master' into 1510-source-2-wgsl
martin-henz Jan 30, 2024
3ca7ea7
Merge branch 'master' of https://github.com/source-academy/js-slang
Ziwen510 Mar 12, 2024
1dcf12e
Merge branch '1510-source-2-wgsl' of https://github.com/source-academ…
Ziwen510 Mar 12, 2024
a904704
update lockfile
Ziwen510 Mar 12, 2024
d18eada
fix error after merge
Ziwen510 Mar 12, 2024
7116f50
Merge branch 'master' into 1510-source-2-wgsl
martin-henz Mar 21, 2024
d8b9a8c
fixing yarn.lock
martin-henz Mar 24, 2024
e6e1cd2
fixing yarn.lock
martin-henz Mar 24, 2024
52305be
Merge branch 'master' of https://github.com/source-academy/js-slang i…
RichDom2185 Mar 24, 2024
0dce817
Revert lockfile recreation
RichDom2185 Mar 24, 2024
d338e81
Fix lockfile post-merge
RichDom2185 Mar 24, 2024
9b52a54
Merge branch 'master' into 1510-source-2-wgsl
martin-henz Mar 25, 2024
3a9a8d9
adapting to changes in modules
martin-henz Mar 26, 2024
bf3f1b9
adapting to changes in modules
martin-henz Mar 26, 2024
8708332
Merge branch 'master' into 1510-source-2-wgsl
martin-henz Mar 26, 2024
b1782c0
attempting to fix async
martin-henz Mar 27, 2024
48a2dd0
Merge branch '1510-source-2-wgsl' of github.com:source-academy/js-sla…
martin-henz Mar 27, 2024
a492de8
Merge branch 'master' into 1510-source-2-wgsl
martin-henz Mar 27, 2024
376e57f
Merge branch '1510-source-2-wgsl' of github.com:source-academy/js-sla…
martin-henz Mar 27, 2024
23a77ab
reverting to async version
martin-henz Mar 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 267 additions & 0 deletions docs/lib/sound_gpu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@

/**
* Makes a Sound with given wave function and duration.
* The wave function is a function: number -> number
* that takes in a non-negative input time and returns an amplitude
* between -1 and 1.
*
* @param wave wave function of the Sound
* @param duration duration of the Sound
* @return with wave as wave function and duration as duration
* @example const s = make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5);
*/
function make_sound(wave, duration) {}

/**
* Accesses the wave function of a given Sound.
*
* @param sound given Sound
* @return the wave function of the Sound
* @example get_wave(make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5)); // Returns t => Math_sin(2 * Math_PI * 440 * t)
*/
function get_wave(sound) {}

/**
* Accesses the duration of a given Sound.
*
* @param sound given Sound
* @return the duration of the Sound
* @example get_duration(make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5)); // Returns 5
*/
function get_duration(sound) {}

/**
* Checks if the argument is a Sound
*
* @param x input to be checked
* @return true if x is a Sound, false otherwise
* @example is_sound(make_sound(t => 0, 2)); // Returns true
*/
function is_sound(x) {}

/**
* Plays the given Wave using the computer’s sound device, for the duration
* given in seconds.
*
* @param wave the wave function to play, starting at 0
* @return the resulting Sound
* @example play_wave(t => math_sin(t * 3000), 5);
*/
function play_wave(wave, duration) {}

/**
* Plays the given Sound using the computer’s sound device
* on top of any Sounds that are currently playing.
*
* @param sound the Sound to play
* @return the given Sound
* @example play(sine_sound(440, 5));
*/
function play(sound) {}

/**
* Makes a noise Sound with given duration
*
* @param duration the duration of the noise sound
* @return resulting noise Sound
* @example noise_sound(5);
*/
function noise_sound(duration) {}

/**
* Makes a silence Sound with given duration
*
* @param duration the duration of the silence Sound
* @return resulting silence Sound
* @example silence_sound(5);
*/
function silence_sound(duration) {}

/**
* Makes a sine wave Sound with given frequency and duration
*
* @param freq the frequency of the sine wave Sound
* @param duration the duration of the sine wave Sound
* @return resulting sine wave Sound
* @example sine_sound(440, 5);
*/
function sine_sound(freq, duration) {}

/**
* Makes a square wave Sound with given frequency and duration
*
* @param freq the frequency of the square wave Sound
* @param duration the duration of the square wave Sound
* @return resulting square wave Sound
* @example square_sound(440, 5);
*/
function square_sound(freq, duration) {}

/**
* Makes a triangle wave Sound with given frequency and duration
*
* @param freq the frequency of the triangle wave Sound
* @param duration the duration of the triangle wave Sound
* @return resulting triangle wave Sound
* @example triangle_sound(440, 5);
*/
function triangle_sound(freq, duration) {}

/**
* Makes a sawtooth wave Sound with given frequency and duration
*
* @param freq the frequency of the sawtooth wave Sound
* @param duration the duration of the sawtooth wave Sound
* @return resulting sawtooth wave Sound
* @example sawtooth_sound(440, 5);
*/
function sawtooth_sound(freq, duration) {}

/**
* Makes a new Sound by combining the sounds in a given list
* where the second Sound is appended to the end of the first Sound,
* the third Sound is appended to the end of the second Sound, and
* so on. The effect is that the Sounds in the list are joined end-to-end
*
* @param list_of_sounds given list of Sounds
* @return the combined Sound
* @example consecutively(list(sine_sound(200, 2), sine_sound(400, 3)));
*/
function consecutively(list_of_sounds) {}

/**
* Makes a new Sound by combining the Sounds in a given list
* where all the Sounds are overlapped on top of each other.
*
* @param list_of_sounds given list of Sounds
* @return the combined Sound
* @example simultaneously(list(sine_sound(200, 2), sine_sound(400, 3)));
*/
function simultaneously(list_of_sounds) {}

/**
* Makes a Sound transformer that transforms a Sound by applying an ADSR
* envelope specified by four ratio parameters. All four ratios are between 0 and 1,
* and their sum is equal to 1.
*
* @param attack_ratio the ratio of the duration of the attack phase
* @param decay_ratio the ratio of the duration of the decay phase
* @param sustain_level the amplitude level of the sustain phase
* @param release_ratio the ratio of the duration of the release phase
* @return the resulting Sound transformer
* @example adsr(0.1, 0.2, 0.7, 0.1)(sine_sound(440, 5));
*/
function adsr(attack_ratio, decay_ratio, sustain_level, release_ratio) {}

/**
* Returns a Sound that results from applying a list of envelopes
* to a given wave form. The wave form is a Sound generator that
* takes a frequency and a duration as arguments and produces a
* Sound with the given frequency and duration. Each envelope is
* applied to a harmonic: the first harmonic has the given frequency,
* the second has twice the frequency, the third three times the
* frequency etc. The harmonics are then layered simultaneously to
* produce the resulting Sound.
* @param waveform function from pair(frequency, duration) to Sound
* @param base_frequency frequency of the first harmonic
* @param duration duration of the produced Sound, in seconds
* @param envelopes – list of envelopes, which are functions from Sound to Sound
* @return Sound resulting Sound
* @example stacking_adsr(sine_sound, 300, 5, list(adsr(0.1, 0.3, 0.2, 0.5), adsr(0.2, 0.5, 0.6, 0.1), adsr(0.3, 0.1, 0.7, 0.3)));
*/
function stacking_adsr(waveform, base_frequency, duration, envelopes) {}

/**
* Returns a Sound transformer which uses its argument
* to modulate the phase of a (carrier) sine wave
* of given frequency and duration with a given Sound.
* Modulating with a low frequency Sound results in a vibrato effect.
* Modulating with a Sound with frequencies comparable to
* the sine wave frequency results in more complex wave forms.
*
* @param freq the frequency of the sine wave to be modulated
* @param duration the duration of the output Sound
* @param amount the amount of modulation to apply to the carrier sine wave
* @return function which takes in a Sound and returns a Sound
* @example phase_mod(440, 5, 1)(sine_sound(220, 5));
*/
function phase_mod(freq, duration, amount) {}

/**
* Converts a letter name to its corresponding MIDI note.
* The letter name is represented in standard pitch notation.
* Examples are "A5", "Db3", "C#7".
*
* @param letter_name given letter name
* @return the corresponding midi note
* @example letter_name_to_midi_note("C4"); // Returns 60
*/
function letter_name_to_midi_note(note) {}

/**
* Converts a MIDI note to its corresponding frequency.
*
* @param note given MIDI note
* @return the frequency of the MIDI note
* @example midi_note_to_frequency(69); // Returns 440
*/
function midi_note_to_frequency(note) {}

/**
* Converts a letter name to its corresponding frequency.
*
* @param letter_name given letter name
* @return the corresponding frequency
* @example letter_name_to_frequency("A4"); // Returns 440
*/
function letter_name_to_frequency(note) {}

/**
* returns a Sound reminiscent of a bell, playing
* a given note for a given duration
* @param note MIDI note
* @param duration duration in seconds
* @return Sound resulting bell Sound with given pitch and duration
* @example bell(40, 1);
*/
function bell(note, duration) {}

/**
* returns a Sound reminiscent of a cello, playing
* a given note for a given duration
* @param note MIDI note
* @param duration duration in seconds
* @return Sound resulting cello Sound with given pitch and duration
* @example cello(36, 5);
*/
function cello(note, duration) {}

/**
* returns a Sound reminiscent of a piano, playing
* a given note for a given duration
* @param note MIDI note
* @param duration duration in seconds
* @return Sound resulting piano Sound with given pitch and duration
* @example piano(48, 5);
*/
function piano(note, duration) {}

/**
* returns a Sound reminiscent of a trombone, playing
* a given note for a given duration
* @param note MIDI note
* @param duration duration in seconds
* @return Sound resulting trombone Sound with given pitch and duration
* @example trombone(60, 2);
*/
function trombone(note, duration) {}

/**
* returns a Sound reminiscent of a violin, playing
* a given note for a given duration
* @param note MIDI note
* @param duration duration in seconds
* @return Sound resulting violin Sound with given pitch and duration
* @example violin(53, 4);
*/
function violin(note, duration) {}
52 changes: 52 additions & 0 deletions docs/md/README_2_WGSL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Source §2 WGSL is a small programming language, designed for the second chapter
of the textbook
<a href="https://sourceacademy.org/sicpjs">Structure and Interpretation
of Computer Programs, JavaScript Adaptation</a> (SICP JS).

## What names are predeclared in Source §2 WGSL?

On the right, you see all predeclared names of Source §2 WGSL, in alphabetical
order. Click on a name to see how it is defined and used. They come in
these groups:
<ul>
<li>
<a href="../AUXILIARY/">AUXILIARY</a>: Auxiliary constants and functions
</li>
<li>
<a href="../MISC/">MISC</a>: Miscellaneous constants and functions
</li>
<li>
<a href="../MATH/">MATH</a>: Mathematical constants and functions
</li>
<li>
<a href="../LISTS/">LISTS</a>: Support for lists
</li>
<li>
<a href="../SOUNDS_GPU/">SOUNDS_GPU</a>: Support for sound module (GPU version)
</li>
</ul>

## What is WGSL?

WGSL stands for WebGPU Shading Language. It is the language used for writing programs that run on the GPU for web applications using the WebGPU API. It is designed to be safe, easy to use, and works across different web browsers and devices. WGSL thus allows us to write code that accelerates computations and graphics processing for web applications.

## What can you do in Source §2 WGSL?

You can use all features of
<a href="../source_2/">Source §2</a>, but with the enhanced performance of functions in the <a href="https://source-academy.github.io/modules/documentation/modules/sound.html">sound module</a>.
These functions are readily available for use without the need for explicit imports.
However, please note that the functions 'init_record', 'play_in_tab', 'record', 'record for', 'stop' are not available in this context. For a list of supported module functions, consult the <a href="../SOUNDS_GPU">SOUNDS_GPU documentation</a>.
In the event that your code encounters issues when running on the GPU, the program will automatically switch to running on the CPU. A prompt will be displayed to inform you of this change.

## Which browser should you use?

For the best experience with WebGPU, use the most recent versions of Chrome, Edge, or Opera, with Chrome being the preferred option. Please be aware that Safari and Firefox currently do not support WebGPU.

## You want the definitive specs?

For our development team, we are maintaining a definitive description
of the language, called the
<a href="../source_2_wgsl.pdf">Specification of Source §2 WGSL</a>. Feel free to
take a peek!


62 changes: 62 additions & 0 deletions docs/md/README_SOUNDS_GPU.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
To describe a Sound, you need a wave function, and the duration of the Sound in seconds.
The wave function takes a nonnegative time *t* (in seconds) as argument and returns the amplitude
of the wave
(a number between -1 and 1) at time *t*. In this library, we assume that as duration of a sound
a nonnegative number is given. An example wave function `my_wave` has this type:

`my_wave` : Number → Number

The following constructor and accessor functions are given:

```
function make_sound(wave, duration) {
return pair(wave, duration);
}

function get_wave(sound) {
return head(sound);
}

function get_duration(sound) {
return tail(sound);
}
```

As usual, make sure you do not break the data abstraction of a Sound and always use these
functions to make and access Sounds.

To try things out, you are given a function

`noise_sound` : Number → Sound

where the given Number is the duration of the noisy Sound to be created, in seconds.

The `play` function has the type:

`play` : Sound → Sound

because it returns the given Sound, in addition to playing it using your computer's audio system.

**Warning: In the following, we produce Sounds that might be very loud! Turn down the volume of
your speakers before you attempt to play Sounds, especially in a public place or if you are wearing
headphones.**

You can test and play the following:

```
play(noise_sound(0.5));
```

after which you should hear half a second of noise. (If you don't, your browser does not support sound; use a different one or ask your Avenger for advice).

### Sound Property

The `make_sound` constructor ensures that all Sounds have the following property:
```
(get_wave(sound))(get_duration(sound) + t) === 0
```
for any number `t` ≥ 0, regardless what the original wave of the Sound returns for `t`.
The wave will simply return 0 when the duration is up.
This Sound property removes the need to explicitly change the wave function when
the duration of a Sound changes.

Loading
Loading