diff --git a/content/docs/2023/mediaart-programming2/1/2023-media-art-programming2-1.pdf b/content/docs/2023/mediaart-programming2/1/2023-media-art-programming2-1.pdf new file mode 100644 index 0000000..91ba0d6 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/1/2023-media-art-programming2-1.pdf differ diff --git a/content/docs/2023/mediaart-programming2/1/_index.en.md b/content/docs/2023/mediaart-programming2/1/_index.en.md new file mode 100644 index 0000000..49416b7 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/1/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 1 +date: 2023-10-06 +weight: 1 +draft: false +params: + pdf_path: 2023-media-art-programming2-1.pdf +--- + +# 2023 Media Art Programming #1 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/1/_index.md b/content/docs/2023/mediaart-programming2/1/_index.md new file mode 100644 index 0000000..fd8a090 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/1/_index.md @@ -0,0 +1,14 @@ +--- +title: 第1週 +date: 2023-10-06 +weight: 1 +draft: false +params: + pdf_path: 2023-media-art-programming2-1.pdf +--- + +# 2023年 メディアアート・プログラミング 第1回 + +## スライド + +{{< embed_pdf >}} diff --git a/content/docs/2023/mediaart-programming2/2/2023-media-art-programming2-2.pdf b/content/docs/2023/mediaart-programming2/2/2023-media-art-programming2-2.pdf new file mode 100644 index 0000000..8438184 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/2/2023-media-art-programming2-2.pdf differ diff --git a/content/docs/2023/mediaart-programming2/2/_index.en.md b/content/docs/2023/mediaart-programming2/2/_index.en.md new file mode 100644 index 0000000..83d13c0 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/2/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 2 +date: 2023-10-13 +weight: 2 +draft: false +params: + pdf_path: 2023-media-art-programming2-2.pdf +--- + +# 2023 Media Art Programming #2 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/2/_index.md b/content/docs/2023/mediaart-programming2/2/_index.md new file mode 100644 index 0000000..61364aa --- /dev/null +++ b/content/docs/2023/mediaart-programming2/2/_index.md @@ -0,0 +1,14 @@ +--- +title: 第2週 +date: 2023-10-13 +weight: 2 +draft: false +params: + pdf_path: 2023-media-art-programming2-2.pdf +--- + +# 2023年 メディアアート・プログラミング 第2回 + +## スライド + +{{< embed_pdf >}} diff --git a/content/docs/2023/mediaart-programming2/3/_index.en.md b/content/docs/2023/mediaart-programming2/3/_index.en.md index 75b33fe..77a08cd 100644 --- a/content/docs/2023/mediaart-programming2/3/_index.en.md +++ b/content/docs/2023/mediaart-programming2/3/_index.en.md @@ -1,10 +1,10 @@ --- title: Week 3 -date: 2023-10-27T16:38:58+09:00 +date: 2023-10-20 weight: 3 params: pdf_path: 2023-media-art-programming2-3.pdf -draft: true +draft: false --- # 2023 メディアアート・プログラミング Week 3 diff --git a/content/docs/2023/mediaart-programming2/3/_index.md b/content/docs/2023/mediaart-programming2/3/_index.md index de8d073..a95431c 100644 --- a/content/docs/2023/mediaart-programming2/3/_index.md +++ b/content/docs/2023/mediaart-programming2/3/_index.md @@ -1,9 +1,9 @@ --- title: 第3週 -date: 2023-10-27T16:38:58+09:00 +date: 2023-10-20 weight: 3 -draft: true -params: +draft: false +params: pdf_path: 2023-media-art-programming2-3.pdf --- diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.001.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.001.jpeg new file mode 100644 index 0000000..4a05c85 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.001.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.002.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.002.jpeg new file mode 100644 index 0000000..96e42d4 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.002.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.003.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.003.jpeg new file mode 100644 index 0000000..d9f95e7 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.003.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.004.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.004.jpeg new file mode 100644 index 0000000..ad88b90 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.004.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.005.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.005.jpeg new file mode 100644 index 0000000..9d05625 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.005.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.006.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.006.jpeg new file mode 100644 index 0000000..4c40896 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.006.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.007.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.007.jpeg new file mode 100644 index 0000000..5e2c44f Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.007.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.008.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.008.jpeg new file mode 100644 index 0000000..3662147 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.008.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.009.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.009.jpeg new file mode 100644 index 0000000..28f3edc Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.009.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.010.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.010.jpeg new file mode 100644 index 0000000..3066b31 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.010.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.011.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.011.jpeg new file mode 100644 index 0000000..e9f2277 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.011.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.012.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.012.jpeg new file mode 100644 index 0000000..cbb7bfd Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.012.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.013.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.013.jpeg new file mode 100644 index 0000000..6b07172 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.013.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.014.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.014.jpeg new file mode 100644 index 0000000..94ac383 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.014.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.015.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.015.jpeg new file mode 100644 index 0000000..b04e519 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.015.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.016.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.016.jpeg new file mode 100644 index 0000000..608610a Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.016.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.017.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.017.jpeg new file mode 100644 index 0000000..ccfbcd2 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.017.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.018.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.018.jpeg new file mode 100644 index 0000000..b7b2d9f Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.018.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.019.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.019.jpeg new file mode 100644 index 0000000..1da4cc8 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.019.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.020.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.020.jpeg new file mode 100644 index 0000000..4d55d92 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.020.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.021.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.021.jpeg new file mode 100644 index 0000000..7ae0e6e Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.021.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.022.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.022.jpeg new file mode 100644 index 0000000..7806616 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.022.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.023.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.023.jpeg new file mode 100644 index 0000000..0232c64 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.023.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.024.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.024.jpeg new file mode 100644 index 0000000..ce59bac Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.024.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.025.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.025.jpeg new file mode 100644 index 0000000..9361595 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.025.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.026.jpeg b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.026.jpeg new file mode 100644 index 0000000..585a432 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/3/slides/2023-media-art-programming2-3.026.jpeg differ diff --git a/content/docs/2023/mediaart-programming2/3/slides/index.en.md b/content/docs/2023/mediaart-programming2/3/slides/index.en.md index 6876fea..afde317 100644 --- a/content/docs/2023/mediaart-programming2/3/slides/index.en.md +++ b/content/docs/2023/mediaart-programming2/3/slides/index.en.md @@ -1,6 +1,6 @@ --- -title: "Class Name 2023 Week 3 Slides" -date: 2023-10-27T16:38:58+09:00 +title: Media Art Programming 2023 Week 3 Slides +date: 2023-10-20 bookHidden: true --- diff --git a/content/docs/2023/mediaart-programming2/3/slides/index.md b/content/docs/2023/mediaart-programming2/3/slides/index.md index 9793fd7..14791cb 100644 --- a/content/docs/2023/mediaart-programming2/3/slides/index.md +++ b/content/docs/2023/mediaart-programming2/3/slides/index.md @@ -1,6 +1,6 @@ --- -title: "授業名 2023年 第3回 スライド" -date: 2023-10-27T16:38:58+09:00 +title: メディアアートプログラミング 2023年 第3回 スライド +date: 2023-10-20 bookHidden: true --- diff --git a/content/docs/2023/mediaart-programming2/4/_index.en.md b/content/docs/2023/mediaart-programming2/4/_index.en.md index 9b1baa0..7033d65 100644 --- a/content/docs/2023/mediaart-programming2/4/_index.en.md +++ b/content/docs/2023/mediaart-programming2/4/_index.en.md @@ -2,23 +2,23 @@ title: Week 4 date: 2023-10-27T16:40:01+09:00 weight: 4 -params: +params: pdf_path: "2023-media-art-programming2-4.pdf" --- -# 2023 Media Art Programming 2 Week 4 +# 2023 Media Art Programming 4th -## スライド +## Slides {{< embed_pdf >}} -{{< button href=.Page.Params.pdf_path >}}Slide(PDF){{< /button >}} +{{< button href=.Page.Params.pdf_path >}} slides (PDF) {{< /button >}} -{{< button href="slides">}}Slide(HTML){{< /button >}} +{{< button href="slides">}}slides (HTML){{< /button >}} -## Shell and pipe +## Shells and Pipes -Previously we have used basic commands like `ls` and `cd`, which take terminal text input and return text output to the terminal. +Previously we have used basic commands such as `ls` and `cd`, which take terminal text input and return text output to the terminal. On Unix-like operating systems, the input and output of commands with simple functions can be combined to perform complex operations using a feature called **pipes**. @@ -26,18 +26,17 @@ Take, for example, the command `say`, which can be used on macOS to read text al The following command will cause macOS to say "Hello" aloud. - ```sh say "Hello". ``` -Here, a program called say receives the text ``"hello"`` from standard input (stdin). +Here, a program called say receives the text `"hello"` from **standard input (stdin)**. So what happens if there is no input at all? ```sh say -```` +``` When executed without input, the say command enters a mode in which it waits for text input. Here, typing "hello" and then pressing the Enter key will cause the command to read out the text. When it finishes reading, it waits for text input again. @@ -49,13 +48,13 @@ A pipe can be used here to pass the result of another command to say as standard echo "hello" | say ``` -The ``echo`` command simply writes arbitrary text to standard output. say is executed without arguments as before, but instead of going into interactive mode, it reads the "hello" given by ``echo`` and exits. +The `echo`` command simply writes arbitrary text to standard output, while ``say`` is executed without arguments as before, but instead of going into interactive mode, it reads the "hello" given by ``echo` and exits. Instead of `echo`, you can use a command that writes a file to standard output, such as `cat hogehoge.txt`, to read an arbitrary text file. ## Files and Devices -By the way, files on storage are not the only things that `cat` can open; Unix-like operating systems can also take hardware information on the computer (e.g., CPU temperature, hard disk RPM, etc.) just as they can handle files. +By the way, files on storage are not the only things that `cat` can open; Unix-like operating systems can also take hardware information on your computer (e.g., CPU temperature, hard disk RPM, etc.) just as they can handle files. These devices reside in the `/dev` directory. This directory is not accessible from the Finder. @@ -63,7 +62,7 @@ These devices reside in the `/dev` directory. This directory is not accessible f ls /dev ``` -There are so many devices out there that it is difficult to guess their contents from their names, but devices connected via Bluetooth are a glimpse of what is possible. Let's try to use `urandom`, a hardware random number generator on a computer. +There are many devices out there, but it is difficult to guess their contents from their names. Let's try to use `urandom`, a hardware random number generator on your computer. On computers, random numbers are often treated as algorithmic sequences of numbers, which means that knowing the initial value of a random number can predict subsequent random number sequences, so security-critical random number generation is often based on time or hardware random number generators. @@ -73,7 +72,7 @@ Since opening with `cat` produces a tremendous number of random numbers and caus head /dev/urandom ``` -And although it is not available now, in the past Linux had a virtual device called `/dev/dsp` that could write waveform data directly to the audio driver when written via pipe. Currently in Linux, the command `aplay` can do the same thing. +And although not available today, in the past Linux had a virtual device called `/dev/dsp` that could write waveform data directly to the audio driver when written via pipe. Currently in Linux, the command `aplay` can do the same thing. There is an attempt to take advantage of this mechanism, called **Bytebeat**, to generate sound in as short and simple a program as possible. @@ -81,7 +80,7 @@ There is an attempt to take advantage of this mechanism, called **Bytebeat**, to {{< youtube tCRPUv8V22o>}} -Bytebeat was first published by viznut in 2011 in a video on Youtube and spread through commentary on his blog. +Bytebeat was first published by viznut in 2011 in a video on Youtube, which spread through commentary on his blog. [Algorithmic symphonies from one line of code -- how and why?(2011)](http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from- one-line-of.html) @@ -97,21 +96,21 @@ Let's try Bytebeat the old-fashioned (?) way of actually creating binary data. L Bytebeat was originally created with the following C program. ```c -main(t){for(;;t++)putchar(((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>19)))|t>>7);} +main(t){for(;;t++)putchar(((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>>19)))|t>>7);} ``` -This C code is compressed to the utmost limit, so if you write it a little more carefully, it will look like this. +This C code is compressed to the extreme, so if we write it a little more carefully, it looks like this ```c int main(int t){ for(;;t++){ - putchar(((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>19)))|t>>7); + putchar(((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>>19)))|t>>7); } } ``` -When a C program defines a function called `main`, it is the entry point for the program to execute. -In an infinite loop with `for`, `t` starts at 0 at the beginning of the program and is increased by 1 at each loop. So this is the virtual time. +C program defines a function called `main`, which is the entrance to be executed by the program. +In an infinite loop with `for`, `t` starts at 0 at the beginning of the program and is increased by 1 for each loop. So this is the virtual time. `putchar` is one of the most primitive functions in C, writing a single byte of data to the standard output. When this t is calculated with various operations, one byte of data (0~255) is output as the value of one sample waveform (≈voltage, air pressure). @@ -135,21 +134,21 @@ You can install `ffmpeg` with Homebrew. Please note that it takes a long time be brew install ffmpeg ``` -### ffmpegとffplayコマンド +### ffmpeg and ffplay commands -`ffmpeg`をインストールすると、`ffplay`というコマンドも同時に使えるようになります。 +When you install `ffmpeg`, you can use the command `ffplay` at the same time. -`ffplay`はffmpegの後段をファイル書き出しやストリーミングではなくシステム上で再生するようにした、いわば万能オーディオ/ビデオ再生ツールです。 +ffplay` is a universal audio/video playback tool that allows you to play the second part of ffmpeg on your system instead of exporting or streaming files. -例えば普通のオーディオファイルの再生は次のようなコマンドで可能です。 +For example, you can use the following commands to play a normal audio file. ```sh ffplay hoge.wav ``` -You can also listen to Internet radio. Open the following URL to receive NHK-FM (Tokyo). [^nhkurl] +You can also listen to Internet radio. You can receive NHK-FM (Tokyo) by opening the following URL. [^nhkurl] -[^nhkurl]: You can get a list of NHK web radio URLs here.http://www.nhk.or.jp/radio/config/config_web.xml +[^nhkurl]: You can get a list of URLs for NHK web radio here. http://www.nhk.or.jp/radio/config/config_web.xml ```sh ffplay https://radio-stream.nhk.jp/hls/live/2023507/nhkradiruakfm/master.m3u8 @@ -157,16 +156,16 @@ ffplay https://radio-stream.nhk.jp/hls/live/2023507/nhkradiruakfm/master.m3u8 During playback, the standard view of the frequency distribution is the spectrogram. -![Screenshot of playback while displaying the spectrogram in ffplay](radio1.png) +![Screenshot of playback while displaying the spectrogram in ffplay...](radio1.png) Pressing the w key with focus on this window allows you to switch between modes of waveform display. [^view] -[^view]: If you set the option `-showmode 0`, 0: video (hidden for audio files), 1: waveform, 2: spectrogram will be displayed. +[^view]: Optionally, `-showmode 0` will display 0: video (hidden for audio files), 1: waveform, 2: spectrogram. -![ffplayで音声波形を表示しながら再生している様子のスクリーンショット。](radio2.png) +![Screenshot of the audio waveform being played while it is displayed by ffplay]. (radio2.png) -### Listen to Audacity with ffmpeg +### Listening to Audacity with ffmpeg Last time, we did "Listen to Audacity with Audacity". If you do that again with ffplay, you will get the following command. @@ -174,14 +173,14 @@ Last time, we did "Listen to Audacity with Audacity". If you do that again with cat '/Applications/Audacity.app/Contents/MacOS/Audacity' | ffplay -f u8 -i pipe:0 -ar 44k -ac 1 ``` -This time, let's interpret the data as 1 byte per sample, a sample rate of 44100 (can be abbreviated as 44k), and the number of audio channels as mono. -Normally, ffplay will infer the format of the data from the file extension or file header, but this time, since we are reading the raw data directly, we need to specify the format as an option. This option corresponds directly to the "Import Raw Data" option we used in Audacity. +This time, let's interpret the data as 1 byte per sample, the sample rate as 44100 (can be abbreviated as 44k), and the number of audio channels as mono. +Normally, ffplay infers the format of the data from the file extension or file header, but this time, since it reads the raw data directly, we need to specify the format as an option. This option corresponds directly to the "Import Raw Data" option we used in Audacity. ![](slides/2023-media-art-programming2-4.011.jpeg) -## Manipulate bytes with Javascript! +## Manipulate byte strings with Javascript! -We've piped the raw byte data to ffplay and listened to it. Now it's time to create the code to generate the byte data. +We've piped the raw byte data into ffplay and listened to it. Now it's time to create the code to generate the byte data. Javascript inherently makes no distinction between numeric byte sizes, etc. (everything is handled in real numbers, 64-bit floating point format in many environments). @@ -196,16 +195,16 @@ const fs = require("fs"); const sample_rate = 8000; const seconds = 5; const byte_length = sample_rate*seconds; -const bytebeat = t => - (t*(1+(5&t>>10))*(3+(t>>17&1?(2^2&t>>14)/3:3&(t>>13)+1))>>(3&t>>9))&(t&4096?(t*(t^t%9)|t>>3)>>1:255); +const bytebeat = t => + (t*(1+(5&t>10))*(3+(t>>17&1?(2^2&t>14)/3:3&(t>>13)+1))>>(3&t>9))&(t&4096?(t*(t^t%9)|t>3)>>1:255); -const data = Uint8Array.from({ length: byte_length }, +const data = Uint8Array.from({ length: byte_length },. (v, t) => bytebeat(t) ); fs.writeFile("jsbytebeat.hex",data, err => {} ); ``` -Take a look around. +Let's look at them in turn. ```js const fs = require("fs"); @@ -218,44 +217,40 @@ const sample_rate = 8000; const seconds = 5; const byte_length = sample_rate*seconds; ``` - -The first two lines specify the sampling rate (how many samples per second of resolution to pack into the data) and the length of the audio waveform to be generated (in seconds). +The first two lines specify the sampling rate (how many samples per second of resolution to pack into the data) and the length of the audio waveform to be generated in seconds. Once these two values are determined, you know how many bytes of data should be generated in the end. That is the `length`. - -```js -const bytebeat = t => - (t*(1+(5&t>>10))*(3+(t>>17&1?(2^2&t>>14)/3:3&(t>>13)+1))>>(3&t>>9))&(t&4096?(t*(t^t%9)|t>>3)>>1:255); +``js +const bytebeat = t => + (t*(1+(5&t>10))*(3+(t>>17&1?(2^2&t>14)/3:3&(t>>13)+1))>>(3&t>>9))&(t&4096?(t*(t^t%9)|t>3)>>1:255); ``` -この行が最終的に波形を生成するBytebeatのプログラムです。この`=>`を使う書き方は関数定義の省略形です。 +This line is the Bytebeat program that will eventually generate the waveform. This writing style using `=>` is an abbreviation of the function definition. ```js -function bytebeat(t) { - return (t*(1+(5&t>>10))*(3+(t>>17&1?(2^2&t>>14)/3:3&(t>>13)+1))>>(3&t>>9))&(t&4096?(t*(t^t%9)|t>>3)>>1:255); +function bytebeat(t) { + return (t*(1+(5&t>10))*(3+(t>>17&1?(2^2&t>14)/3:3&(t>>13)+1))>>(3&t>>9))&(t&4096?(t*(t^t%9)|t>3)>>1:255); } ``` - -This definition is exactly the same. Note that the above is the only way to omit return, although it is your preference. (Even in the above, return is still required if the `=>` is followed by curly braces `{}`.) +This definition is exactly the same. The way it is written is a matter of taste, but note that return can only be omitted in the above way (even in the above way, return is still required if the `=>` is followed by curly braces `{}`). -```js -const data = Uint8Array.from({ length: byte_length }, +``js +const data = Uint8Array.from({ length: byte_length },. (v, t) => bytebeat(t) ); ``` +Now we create an array of unsigned 8-bit integers. There are many ways to do this, but in this case we will use the `from`` method with the ``length` and the initialization function. -We will now create an array of unsigned 8-bit integers. There are many ways to do this, but in this case we will use the `from` method to specify the `length` and initialization function. - -In `{length:byte_length}`, we specify that we want to create an array of 8000*5=400000 samples, which we calculated earlier. +In `{length:byte_length}` we specify that we want to create an array of 8000*5=400000 samples calculated earlier. `(v, t) => bytebeat(t)` is an initialization process that takes the index of an array called t, puts it into the bytebeat function, and stores the converted values in the array in order. -```js +```js. fs.writeFile("jsbytebeat.hex",data, err => {} ); ``` -At this point, finally, save the resulting byte sequence. The third argument, `err => {}`, indicates that no action is to be taken in error handling. The third argument, `err => {}`, refers to doing nothing in error handling. +Here we finally save the resulting byte sequence. The third argument, `err => {}`, indicates that no action is to be taken in error handling. The third argument, `err => {}`, refers to doing nothing in error handling. Now, let's run this as `bytebeat.js` in the terminal. At this time, remember that the `-ar` option in ffplay should match the sampling rate specified in the source code. @@ -263,32 +258,32 @@ At this time, remember that the `-ar` option in ffplay should match the sampling ```sh node bytebeat.js -cat jsbytebeat.hex | ffplay -f u8 -i pipe:0 -ar 8k -ac 1 +cat jsbytebeat.hex | ffplay -f u8 -i pipe:0 -ar 8k -ac 1 ``` -Hopefully, 5 seconds of audio should play and stop. +If all goes well, 5 seconds of audio should play and stop. -You can also output it again as a wav file with ffmpeg instead of ffplay.。 +You can also use ffmpeg instead of ffplay to output it again as a wav file. ```sh -cat jsbytebeat.hex | ffmpeg -f u8 -ar 8k -i pipe:0 -c:a pcm_u8 -ac 1 -y jsbytebeat.wav +cat jsbytebeat.hex | ffmpeg -f u8 -ar 8k -i pipe:0 -c:a pcm_u8 -ac 1 -y jsbytebeat.wav ``` -### Let's take a simple observation of the waveform +### Let's take a quick look at the waveforms. Let's try the bytebeat function as a function that just returns t as it is. ```js -const bytebeat = t => +const bytebeat = t => t ``` -At this time, the value of t itself keeps rising without limit up to several hundred thousand, but when it is finally written to `Uint8Array`, only the lower 8 bits of the integer portion are written. What this means is that after rising from 0 to 255, it returns to 0 again. +In this case, the value of t itself keeps rising without limit up to several hundred thousand and so on, but when it is finally written to `Uint8Array`, only the lower 8 bits of the integer portion are written. What this means is that after rising from 0 to 255, it returns to 0 again. If you open this `jsbytebeat.hex` with 0~255 written in it with VSCode's Hex Editor, it looks like the following. -![バイナリエディタで0~255までが連続するバイナリデータを表示したVisual Studio Codeのスクリーンショット。](binary.png) +![Visual Studio Code screenshot showing binary data with continuous 0~255 in the Binary Editor]. (binary.png) You can see that the numbers rise in sequence from 00 to FF (255) and back to 00 again. @@ -303,15 +298,15 @@ let file = fs.createWriteStream("graph.txt"); for (byte of data){ let txt = ""; for (i = 0; i < byte; i++) { - txt += "|"; + txt += "|"; } } - txt += "\n"; + txt += "\n"; } file.write(txt); } -file.end(); +file.end(); } ``` -The code above reads one byte of the `data` array, writes a character (|) for the numerical value of the data, breaks the line, reads the next byte again ......, and repeats to create a file called graph.txt. +The above code reads one byte of the `data` array, writes a character (|) for the numeric value of the data, breaks the line, reads the next byte again ......, and repeats to create a file called graph.txt. Now when you run `node bytebeat.js` again, it will create `graph.txt` in the directory. @@ -319,32 +314,164 @@ If you open this in VSCode, it should look like this. ![](graph.png) -Although the display varies depending on the character size and text wrapping settings, the sawtooth waveform is plotted by increasing the number of characters by one per line. +Although the display will vary depending on the size of the characters and the text wrapping settings, a sawtooth waveform is plotted by increasing the number of characters by one per line. -### Let's make it run continuously. +### Let's make it possible to run the program continuously. -WIP... +Writing the contents of a `Uint8Array` to standard output is relatively easy with `process.stdout.write(data)`, but it is surprisingly troublesome to make it continue to do so permanently. + +For now, let's change the code that just generated the array so that it can be written to standard output. + +```js + const data = Uint8Array.from({ length: length }, + (v, t) => bytebeat(t) + ); + process.stdout.write(data); +``` + +Let's call this file `bytebeat_stream.js`. +Now we can pipe the output of node directly and play it back for 5 seconds. + +```sh +node bytebeat_stream.js | ffplay -f u8 -i pipe:0 -ar 8k -ac 1 +``` + +Eventually I want to be able to do this continuously, so I'll create an infinite loop like this. + +```js +while(true){ + const data = Uint8Array.from({ length: length },. + (v, t) => bytebeat(t) + ); + process.stdout.write(data); +} +``` + +There are two problems with this code: first, t is an index created during array creation, so it resets to 0 every 5 seconds. Therefore, t should be defined as a global variable on the outside and updated. + +```js +let t = 0; +while(true){ + const data = Uint8Array.from({ length: length }, + (v, _t) => { + const res = bytebeat(t); + t++; + return res; + } + ); + process.stdout.write(data); +} +``` + +Declare `t` with `let` instead of `const` to declare it as a variable to be rewritten later. + +Also, the argument `(v,t)` used to generate the original array is no longer used, so change it to `_t` so that the name is not covered by the variable `t`. + +Another problem is that the speed at which the byte sequence is generated is by far faster than it is actually consumed by the audio driver. +(This is also the specification of the original C program, so you don't have to worry about it too much, but...) If unused data is generated endlessly and passed through a pipe, it can eat up a lot of memory. +There are several ways to achieve this, but a simple way is to use the `setInterval` function, which keeps executing a specific function at a fixed interval. + +First, the part of the code that writes to standard output for 5 seconds should be a function called `mainProcess`. + +```js +const mainProcess = ()=> { + const data = Uint8Array.from({ length: length }, + (v, _t) => { + const res = bytebeat(t); + t += 1; + return res + } + ); + process.stdout.write(data); +}; +``` +This is specified in `setInterval`. The second argument specifies the interval between executions, and the unit of the number at this time is milliseconds. So, divide the number of seconds specified in `seconds` by 1000. + +```js +setInterval(mainProcess,seconds / 1000.0); +``` + +In practice, the `mainProcess` should take some time to execute, so if you are generating exactly 5 seconds and waiting for 5 seconds, there may be cases where the audio driver fails because there is not enough data to write to the audio driver. In such cases, you may want to use `1010.0` instead of `1000.0` to speed up the execution. + +That's how the finished version of `bytebeat_stream.js` looks like this ```js -const { setTimeout } = require('timers/promises'); const sample_rate = 8000; -const seconds = 5; +const seconds = 1; const length = sample_rate * seconds; const bytebeat = t => - (((t >> 10 ^ t >> 11) % 5)* t>>16)* ((t >> 14 & 3 ^ t >> 15 & 1) + 1) * t % 99 + ((3 + (t >> 14 & 3) - (t >> 16 & 1)) / 3 * t % 99 & 64); + (((t >> 10 ^ t >> 11) % 5) * t >> 16) * ((t >> 14 & 3 ^ t >> 15 & 1) + 1) * t % 99 + ((3 + (t >> 14 & 3) - (t >> 16 & 1)) / 3 * t % 99 & 64); let t = 0; -(async () => { - while (true) { - const data = Uint8Array.from({ length: length }, - (v, _t) => { - const res = bytebeat(t); - t += 1; - return res - } - ); - process.stdout.write(data); - await setTimeout(seconds / 1000.0); - } -})() -``` \ No newline at end of file +const mainProcess = () =>{ + const data = Uint8Array.from({ length: length }, + (v, _t) => { + const res = bytebeat(t); + t += 1; + return res + } + ); + process.stdout.write(data); +}; + +setInterval(mainProcess,seconds / 1000.0); +``` + + + +## Supplemental (memorandum) + +### Handling of integer operations in Javascript + +It is actually not so obvious that the conversion of numeric types when finally packing integer values into a Uint8Array in JS is the same as in Bytebeat in C. + +For example, if you open a Node.js REPL and do some calculations, + +``` +> 1<<30 +1073741824 +> 1<<31 +-2147483648 +> 1<<32 +1 + +> (1<<31)+0.1 +-2147483647.9 +> 1.1<<31 +-2147483648 +> 0.9<<31 +0 + +> 2 ** 52 +4503599627370496 +> 2**52+1 +4503599627370497 +> 2 ** 53 +9007199254740992 +> 2 ** 53 +1 +9007199254740992 +``` + +and so on. From here, without looking up the specification, we can roughly do the following + +- The internal representation of numbers in JS is 64-bit floating point (`double` in C). +- The mantissa part (integer value when the exponent part is 0) is signed 53bit (if you take out the upper 32bit, it becomes C's `int`/`int32_t`). +- When performing bitwise operations, once truncate to an integer, and then calculate as an operation between signed 32 bits. +- When putting into `Uint8Array` and so on, the lower bits are cut out and casted, and the lower 32 bits are also used when casted from a 52-bit integer to a 32-bit integer. + +I checked later and it seems that this specification is generally correct. + +This behavior seems to eventually lead to the same result as the case where `t` is cast to type `char` when doing `putchar` using the first argument of the `main` function, that is, `int`, when doing Bytebeat in C language. + +It seems to be established on the balance of quite exquisite specification that the same sound can be easily made in C and Javascript. I'm not sure if they were anticipating that much or not... + +However, if you think about it, when you update the time in t++, it seems that in JavaScript, after being added up to 2^52, the increment will continue with a loss of precision instead of returning to 0. For example, how much does the accuracy start to drop for mono at a sample rate of 44.1 kHz? + +```sh +> (2**52 /44100)/(60*60*24*365) +3238.2813460788693 +``` + +It looks like we have nothing to worry about for 3238 years. + + diff --git a/content/docs/2023/mediaart-programming2/5/2023-media-art-programming2-5.pdf b/content/docs/2023/mediaart-programming2/5/2023-media-art-programming2-5.pdf new file mode 100644 index 0000000..6ca48d2 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/5/2023-media-art-programming2-5.pdf differ diff --git a/content/docs/2023/mediaart-programming2/5/_index.en.md b/content/docs/2023/mediaart-programming2/5/_index.en.md new file mode 100644 index 0000000..74cf6b5 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/5/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 5 +date: 2023-10-31 +weight: 5 +draft: false +params: + pdf_path: 2023-media-art-programming2-5.pdf +--- + +# 2023 Media Art Programming #5 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/5/_index.md b/content/docs/2023/mediaart-programming2/5/_index.md new file mode 100644 index 0000000..eaf8dae --- /dev/null +++ b/content/docs/2023/mediaart-programming2/5/_index.md @@ -0,0 +1,14 @@ +--- +title: 第5週 +date: 2023-10-31 +weight: 5 +draft: false +params: + pdf_path: 2023-media-art-programming2-5.pdf +--- + +# 2023年 メディアアート・プログラミング 第5回 + +## スライド + +{{< embed_pdf >}} diff --git a/content/docs/2023/mediaart-programming2/6/2023-media-art-programming2-6.pdf b/content/docs/2023/mediaart-programming2/6/2023-media-art-programming2-6.pdf new file mode 100644 index 0000000..1da92ae Binary files /dev/null and b/content/docs/2023/mediaart-programming2/6/2023-media-art-programming2-6.pdf differ diff --git a/content/docs/2023/mediaart-programming2/6/_index.en.md b/content/docs/2023/mediaart-programming2/6/_index.en.md new file mode 100644 index 0000000..a1b2660 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/6/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 6 +date: 2023-11-10 +weight: 6 +draft: false +params: + pdf_path: 2023-media-art-programming2-6.pdf +--- + +# 2023 Media Art Programming #6 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/6/_index.md b/content/docs/2023/mediaart-programming2/6/_index.md new file mode 100644 index 0000000..90d3047 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/6/_index.md @@ -0,0 +1,14 @@ +--- +title: 第6週 +date: 2023-11-10 +weight: 6 +draft: false +params: + pdf_path: 2023-media-art-programming2-6.pdf +--- + +# 2023年 メディアアート・プログラミング 第6回 + +## スライド + +{{< embed_pdf >}} diff --git a/content/docs/2023/mediaart-programming2/7/2023-media-art-programming2-7.pdf b/content/docs/2023/mediaart-programming2/7/2023-media-art-programming2-7.pdf new file mode 100644 index 0000000..aa8543f Binary files /dev/null and b/content/docs/2023/mediaart-programming2/7/2023-media-art-programming2-7.pdf differ diff --git a/content/docs/2023/mediaart-programming2/7/_index.en.md b/content/docs/2023/mediaart-programming2/7/_index.en.md new file mode 100644 index 0000000..235cfb2 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/7/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 7 +date: 2023-11-17 +weight: 7 +draft: false +params: + pdf_path: 2023-media-art-programming2-7.pdf +--- + +# 2023 Media Art Programming #8 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/7/_index.md b/content/docs/2023/mediaart-programming2/7/_index.md new file mode 100644 index 0000000..8b78cf1 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/7/_index.md @@ -0,0 +1,14 @@ +--- +title: 第7週 +date: 2023-11-17 +weight: 7 +draft: false +params: + pdf_path: 2023-media-art-programming2-7.pdf +--- + +# 2023年 メディアアート・プログラミング 第7回 + +## スライド + +{{< embed_pdf >}} diff --git a/content/docs/2023/mediaart-programming2/8/2023-media-art-programming2-8.pdf b/content/docs/2023/mediaart-programming2/8/2023-media-art-programming2-8.pdf new file mode 100644 index 0000000..73909d8 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/8/2023-media-art-programming2-8.pdf differ diff --git a/content/docs/2023/mediaart-programming2/8/_index.en.md b/content/docs/2023/mediaart-programming2/8/_index.en.md new file mode 100644 index 0000000..b95effc --- /dev/null +++ b/content/docs/2023/mediaart-programming2/8/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 8 +date: 2023-11-24 +weight: 8 +draft: false +params: + pdf_path: 2023-media-art-programming2-8.pdf +--- + +# 2023 Media Art Programming #8 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/8/_index.md b/content/docs/2023/mediaart-programming2/8/_index.md new file mode 100644 index 0000000..310c518 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/8/_index.md @@ -0,0 +1,14 @@ +--- +title: 第8週 +date: 2023-11-24 +weight: 8 +draft: false +params: + pdf_path: 2023-media-art-programming2-8.pdf +--- + +# 2023年 メディアアート・プログラミング 第8回 + +## スライド + +{{< embed_pdf >}} diff --git a/content/docs/2023/mediaart-programming2/9/2023-media-art-programming2-9.pdf b/content/docs/2023/mediaart-programming2/9/2023-media-art-programming2-9.pdf new file mode 100644 index 0000000..9dc78e0 Binary files /dev/null and b/content/docs/2023/mediaart-programming2/9/2023-media-art-programming2-9.pdf differ diff --git a/content/docs/2023/mediaart-programming2/9/_index.en.md b/content/docs/2023/mediaart-programming2/9/_index.en.md new file mode 100644 index 0000000..ffbc880 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/9/_index.en.md @@ -0,0 +1,15 @@ +--- +title: Week 9 +date: 2023-12-01 +weight: 9 +draft: false +params: + pdf_path: 2023-media-art-programming2-9.pdf +--- + +# 2023 Media Art Programming #9 + +## Slides + +{{< embed_pdf >}} + diff --git a/content/docs/2023/mediaart-programming2/9/_index.md b/content/docs/2023/mediaart-programming2/9/_index.md new file mode 100644 index 0000000..d8f2a32 --- /dev/null +++ b/content/docs/2023/mediaart-programming2/9/_index.md @@ -0,0 +1,14 @@ +--- +title: 第9週 +date: 2023-12-01 +weight: 9 +draft: false +params: + pdf_path: 2023-media-art-programming2-9.pdf +--- + +# 2023年 メディアアート・プログラミング 第9回 + +## スライド + +{{< embed_pdf >}}