Deprecated: Creation of dynamic property wpdb::$categories is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$post2cat is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$link2cat is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Return type of WP_Theme::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 554

Deprecated: Return type of WP_Theme::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 595

Deprecated: Return type of WP_Theme::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 535

Deprecated: Return type of WP_Theme::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 544

Deprecated: Return type of WP_REST_Request::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 960

Deprecated: Return type of WP_REST_Request::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 980

Deprecated: Return type of WP_REST_Request::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 992

Deprecated: Return type of WP_REST_Request::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 1003

Deprecated: Return type of WP_Block_List::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 151

Deprecated: Return type of WP_Block_List::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 175

Deprecated: Return type of WP_Block_List::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 164

Deprecated: Return type of WP_Block_List::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 186

Deprecated: Return type of WP_Block_List::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 138

Deprecated: Return type of WP_Block_List::offsetExists($index) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 75

Deprecated: Return type of WP_Block_List::offsetGet($index) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 89

Deprecated: Return type of WP_Block_List::offsetSet($index, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 110

Deprecated: Return type of WP_Block_List::offsetUnset($index) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 127

Deprecated: Return type of WP_Block_List::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 199

Deprecated: Creation of dynamic property Automattic\Jetpack\Connection\Manager::$error_handler is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-connection/src/class-manager.php on line 91

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Instagram_Gallery::$is_wpcom is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-instagram-gallery.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Mailchimp::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-mailchimp.php on line 17

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 21

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$is_wpcom is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 22

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Gutenberg_Available_Extensions::$wpcom_is_site_specific_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/gutenberg-available-extensions.php on line 20

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_site_specific_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 24

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Subscribers::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/subscribers.php on line 15

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property WPCOM_Widget_Goodreads::$shelves is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/modules/widgets/goodreads.php on line 33

Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /var/www/twodee/blog/wp-includes/script-loader.php on line 348

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_classic_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 347

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 349

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block_side is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 350

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$panels_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 351

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$used_block_buttons is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 354

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 3030

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Warning: Cannot modify header information - headers already sent by (output started at /var/www/twodee/blog/wp-includes/class-wp-block-list.php:14) in /var/www/twodee/blog/wp-includes/feed-rss2.php on line 8
deltaphone – teaching machines https://twodee.org/blog Tue, 04 Oct 2022 01:09:31 +0000 en-US hourly 1 https://wordpress.org/?v=5.7.1 Terra’s Theme https://twodee.org/blog/17286 https://twodee.org/blog/17286#respond Sun, 06 Oct 2019 21:38:42 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/17286 [...]]]> I’m not exactly sure what Deltaphone is for, but this afternoon, it was for analyzing the structure of Terra’s Theme from Final Fantasy VI. (Thanks to 8-bit of 8-bit Music Theory, who did all the work.) The melodic line consists of a phrase repeated three times, and this phrase is expressed in the prefix function below. Did you know the A section and the B section simply swap the roots of these three iterations? The A section’s three iterations start at G#, G#, and B. The B section’s three iterations start at B, B, and G#.

Hit the Play button to hear. The editor is a little cramped in this blog; I suggest you scroll down and click Expand to open it in a new tab or window.

]]>
https://twodee.org/blog/17286/feed 0
VOICES 2019: Learning Music Theory through Code with Deltaphone https://twodee.org/blog/17218 https://twodee.org/blog/17218#respond Wed, 18 Sep 2019 00:45:53 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/17218 [...]]]> Follow is a draft of my talk for VOICES 2019, a virtual conference on the use of music in STEM learning. This is the first virtual conference I have attended. No flight, no badge, no bag of unwanted promotional materials. Just people talking about music and learning from the comfort of their homes and offices.

Introduction

Computer science education has had a good run of late. It’s been endorsed by presidents, athletes, musicians, and household names in technology. A number of states allow computer science to count toward math, science, or even foreign language requirements, and some require that it be offered in all high schools. There are many organizations aiming to provide access to computer science learning to underrepresented groups. A lot of funding is available for educators who can find effective ways to teach computer science.

Blikstein identifies four rationales behind the push to expand computer science education:

  • Labor market rationale: a competitive technology-based economy requires laborers with computer science skills
  • Equity of participation rationale: the most advantageous jobs and offices will go to those with computer science skills
  • Computational thinking rationale: computer science exposes learners to problem-solving strategies that they can apply to other disciplines
  • Computational literacy rationale: computer science engages learners in building representations of knowledge, both in their minds and in the programs they write

Each of these rationales has merit, but the first three are focused on secondary rewards like jobs, status, and transfer. The rationale that is dearest to my heart as an educator is computational literacy. Computational literacy is not about breeding a new generation of software developers. Advocates of this rationale view computer science as a medium for learning in all disciplines—just as literacy considers the written word to be a medium for all kinds of learning. By writing programs and reading them, we learn.

There’s one particular kind of learning for which I think computer science is well-suited: the learning of music theory.

Music Theory through Deltaphone

Programming is one of the primary activities of computer science. But learning to program is generally time-consuming and full of heartache. For programming not to distract from the learning process of another discipline, we need small languages tailored to the discipline. Sometimes these are called domain-specific languages or DSLs. I have been working on a DSL for music called Deltaphone. I will give a demonstration of its features as they relate to the learning of musical theory.

Sequence

Deltaphone supports sequencing, putting one note after another across time. Let’s write a program to render and play a scale. We’ll start with the chromatic scale. Instead of thinking of notes as absolute positions on the staff, learners can describe notes as changes or deltas from the previous note. In the chromatic scale, for example, each note is one halfstep or semitone higher than the previous note.

We can change the root of this scale, and the rest of the scale moves accordingly. In the Logo programming language, Seymour Papert called this turtle geometry. Instead of treating space as an absolute coordinate system, Logo programmers move around space by turning and moving relative to their current position and heading. You could say that Deltaphone supports turtle music.

The major scale follows a different offset pattern: +2 +2 +1 +2 +2 +2 +1.

The minor scale follows a rotated version of this offset pattern: +2 +1 +2 +2 +1 +2 +2.

Repetition

Musical actions can be repeated. Musicians acknowledge repetition with various repeat structures, but there is also considerable implicit repetition. Deltaphone supports both explicit repeat structures and more general purpose loops called ditto and for. Let’s walk up the staff in perfect fifths with ditto and do it again with repeat:

Data Abstraction

One particularly important cognitive activity that programming contributes to learning is abstraction, the generalization of specifics into patterns. In algebra, for instance, we think about operations in terms of variables instead of specific numbers. In Deltaphone, we can abstract data too. Consider this program that plays four quarter notes:

If I decide I want these to be half notes instead, I must make four changes. However, if I do little higher-order thinking, I can instead create a variable storing the duration. In this program I can make a single change to affect all four notes:

Variables make connections between separate instructions clear and make experimenting less costly.

Procedural Abstraction

In addition to abstracting data, we can also abstract procedures. If there’s a chunk of code that represents a high-level action, we can give that chunk an appropriate name. For example, in this program, we can create procedures for chords of the major scale:

Conclusion

My dream for Deltaphone is not to use it to teach kids how to program. Rather, I want to collaborate with music educators and develop a curriculum for learning music theory through programming. The learners will start with a just a handful of Deltaphone’s primitive commands and build up a whole library of musical structures, like repeats, chords, inversions, and so on. They will be computationally literate in music theory.

]]>
https://twodee.org/blog/17218/feed 0
Triadic Chords in Deltaphone https://twodee.org/blog/17160 https://twodee.org/blog/17160#comments Wed, 31 Jul 2019 02:15:08 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/17160 [...]]]> When non-pianists approach a piano, they will strike random keys—but often just one key at a time. If they play more than one, the sound is likely to be unpleasant. But that’s only because they don’t know which keys to strike at the same time. Let’s work out in Deltaphone a system of notes that do sound good together: the seven chords of the major scale.

The major scale is defined to be a list of notes that starts at some root note, jumps up 2 halfsteps, jumps up 2 more, jumps up 1, jumps up 2, jumps up 2, jumps up 2, and jumps up 1. All told, we travel 12 halfsteps up from the root, landing one octave above.

In this program, we generate the C major scale using these offsets, starting at C in the fourth octave and landing on C in the fifth octave:

The notes we visit are C, D, E, F, G, A, B, and C.

Now, consider this simple rule for finding notes in this scale that sound pleasing together:

  • Play any of the notes in the list.
  • Play also the note two positions farther along in the list.
  • Play also the note two more positions farther along in the list.

That set of three notes is called a triad. Let’s write a function that formalizes the algorithm:

That sounds pleasing, right? The best part is that the algorithm is versatile. It can be applied at any of the notes in the major scale. Let’s walk up the scale and apply it at each note:

All those triads should sound pleasing to your ears. But the code is awfully repetitive. Let’s walk up the whole scale with a loop instead:

Our algorithm for picking notes works across the whole scale!

There’s still one improvement we can make. Musicians give names to each of the triads using Roman numerals. When we pick the scale’s root as the triad’s root, we have a I chord. When we pick the second note of the scale as the triad’s root, we have a ii chord. When we pick the third note, a iii chord. The fourth note, a IV chord. The fifth note, a V chord. The sixth note, a vi chord. And the seventh note, a vii chord.

Let’s write some helper functions that abstract away the I, IV, V, and vi chords:

Now we have a language for compactly describing chords, and we can create chord progressions like I, V, vi, IV:

This progression and other orderings of the same four chords are quite common in popular music.

There’s one last trick we can apply to our triads, but let’s save inversions for next time.

]]>
https://twodee.org/blog/17160/feed 1
Interaction in Deltaphone https://twodee.org/blog/17039 https://twodee.org/blog/17039#respond Tue, 11 Jun 2019 19:10:30 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/17039 [...]]]> One of the many superpowers of a musician is the ability to hear intervals. This is not a superpower I possess. Can it be learned? While I’ve been working on Deltaphone, a friend mentioned that he coded an interval generator when he was a kid in order to help him train his ear. Last week I had the chance to visit a music theory club at an intermediate school, and they played a game in which a teacher played an interval on the piano and the students identified it.

Yesterday I set about adding support to Deltaphone for generating this kind of interactive game so that I too could acquire this superpower. But Deltaphone wasn’t exactly designed with interaction in mind. Previously, I interpreted the program completely before processing and rendering the score. But in a game, the interpreter might need to render the score more frequently to prompt the player or give feedback. Furthermore, the interpreter must occasionally wait for user input before proceeding. How would I stop the interpreter?

I feared I would need to rewrite the interpreter from scratch to support some form of continuations. But then I discovered Javascript’s async and await commands. Tagging a function with async makes it run asynchronously. An async function immediately returns a promise to its caller, at which point the caller normally continues on its merry way. To cause execution to block, however, one can await the resolution of a promise. Using these two commands, one can effectively suspend a function’s return without a busy loop.

Suppose I want to pause the interpreter until the user clicks a button. I added this wait-for-click statement, which only resolves its promise on the button’s click event:

class StatementWaitForClick() {
  async evaluate(env) {
    await new Promise(resolve => {
      button.onclick = () => resolve();
    });
  }
}

Very few of my structures need an explicit promise—only wait-for-click and multiple-choice-quiz. But I had to tag all my evaluate functions across my abstract syntax tree with async because I never know if a substructure might pause during its evaluation. This means that even those operations without an explicit promise must still await the asynchronous evaluation of their substructures, as we do in this add operation:

class ExpressionAdd(a, b) {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }

  async evaluate(env) {
    let valueA = await a.evaluate(env);
    let valueB = await b.evaluate(env);
    return valueA + valueB;
  }
}

With a pausable interpreter, Deltaphone programmers can now build interactive games. Like this one for recognizing intervals:

Just now I got 4 out of 5!

]]>
https://twodee.org/blog/17039/feed 0
University of Canterbury Seminar https://twodee.org/blog/17018 https://twodee.org/blog/17018#respond Fri, 24 May 2019 18:35:51 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/17018 [...]]]> Hi, I’m Chris and I teach people to teach machines. But I am a reluctant computer scientist. Sometimes I get concerned that the thing I know the most about is not directly linked to my survival. My father knew how to keep machines running. My wife grows vegetables. In a post-apocalyptic world, they would be valuable. I would not be.

A few weeks ago, my wife asked me if I thought our sons would study computer science. I told her that I hoped to teach them enough of it at home that they’d be freed up to study something else.

I really do like my discipline, but I love more the things that my children, my students, and I can make with it. The past few years, I have been searching for ways to make computer science less virtual and more physical, more integrated in the world around us. Our agenda for today is to demonstrate three projects that support my mission of making computer science less virtual.

Computational Making

Schools left and right, politically and geographically, are establishing makerspaces, buying up 3D printers and laser cutters, and getting their students designing and building real things. The students are making. This sounds great. However, if you talk to the teachers and librarians who are staffing these makerspaces, you will hear about the many kids who are just downloading other people’s 3D models and design files from Thingiverse and fabricating those.

This happens for a couple of reasons. First, its part of the maker ethos to share what one has made. Second, learning to model in 2D and 3D is time-consuming and doesn’t really fit well into an already crowded school curricula. I think computer science can fix this. Instead of just plain making, we need computational making.

We hear a lot these days about computational thinking. There’s little agreement about what skills and concepts make up computational thinking, and it has come to be used as a way to invoke the idea of computer science but subtract out or downplay programming. I needed a term to invoke the idea of creating but with programming added in. That is computational making, which I define as a creative process

  • guided by algorithms and data
  • carried out in a parametric design space
  • with a physical output.

Let’s now look at some tools I’ve been building to facilitate computational making.

Madeup

The first tool is Madeup, a programming language for making things up—literally. It is very much modeled after the drawing mechanics of Seymour Papert’s Logo from the 1980s, but extended to three dimensions. Madeup, like Logo, is meant to make learning geometry an interactive experience. Instead of imposing a grand coordinate system over all space, the programmer uses a coordinate system relative to the avatar on the screen. Logo’s avatar was a turtle, and Papert called this way of thinking about space turtle geometry. Let’s see it at work in an example. We’ll code a rupee from the Legend of Zelda games.

For those of you who have been spending your time elsewhere, rupees look like this:

We will program the cross section of one of these. Imagine that we cut one right down the middle. What shape would we see? An elongated hexagon. Let’s write Madeup code to trace out the top half of the hexagon, like so:

Next we revolve that cross section around the x-axis, sampling the surface or revolution just six times to produce the hexagonal structure:

And finally we stretch it a bit vertically:

What if want to make a sharper bevel? We must change the angle we turn. Instead of 45, let’s try 30:

Whoops. We’ll need to change the peak angle too. But to what? Some experimentation leads us to 120:

But we can do better than experiment. Why is it 120? Because all told, we are turning back the direction we came, which is 180 degrees. We burn 30 of those up on the first yaw and 30 on the third yaw. That leaves 120 left for the middle yaw. Now we can generalize this and turn the angle into a parameter:

Madeup is a fully-featured programming language. It supports conditionals, loops, variables, functions, and arrays. There are many ways to turn a path into a solid. We’ve seen revolve, but there’s also dowel. Let’s make a chain link:

Let’s see a few more examples.

This perimeter of this gear is extruded and a hole is subtracted from its center:

The Madeup editor also supports a blocks programming interface, and one can (mostly) switch back and forth between text and blocks.

How does Madeup make computer science less virtual? The model can be printed on a 3D printer or embedded in a game engine.

I spent the last year

Twoville

The second project I’d like to share you has one less than dimension than Madeup. Twoville’s purpose is to help programmers build 2D scalable vector graphics (SVG) files that can be fed into a laser or vinyl cutter.

Let’s make another jewel, a diamond. Since we’re in 2D, we’ll just create the profile of a diamond. We start with a square, but rotate it a bit:

Twoville tends to be a very declarative language, as we’re often just setting properties. To ease the syntactic burden of setting a sequence of properties, I added in the scoping function with:

We want to chop off the top, so we overlay another rectangle across it:

To remove the red rectangle, we create a cutout object that serves as a mask:

A similar approach can be used to make a phone:

Like Madeup, Twoville supports conditionals, loops, functions, and arrays. I used functions to abstract out the droplet shapes of this logo that I walked by everyday in Brisbane, Australia, during the first half of my sabbatical:

If you’ve done anything with 3D printing in schools, you will have encountered the slowness of the technology. Models take a long time to print, and the machines need minding. 3D printing doesn’t scale well to large groups of students. Vinyl and laser cutters are much faster, and I think Twoville will better accommodate the time-limited summer camps and workshops I’ve been putting on back home.

Deltaphone

The last project I’d like to share has a less touchable output. It also has one less dimension than Twoville. I’m losing dimensions as I get older. It must be a case of “dimentia.” Deltaphone is my exploration of applying the idea of turtle geometry to music. Instead of thinking about music as a sequence of absolute positions on the staff, we think of a song in Deltaphone as a sequence of changes or deltas between one note and the next.

Let’s compose a little song to see how it works.

Deltaphone supports variables, conditionals, loops, and functions. The output of Deltaphone is a score.

This project is only a few months old, and I don’t know if it has a future or not. I need to find a music teacher who doesn’t feel threatened by technology and who can help me shape it into a tool to explore music theory and composition.

Conclusion

These are three projects that I have been developing to make computer science less virtual, to fit it into the everyday worlds of objects and music.

Educational psychologists argue about whether its better to learn a subject in a contextualized or decontextualized manner. Contextualized learning situates concepts in a themed narrative, like robotics or game development. Decontextualized learning happens when there is no overarching narrative.

Neither approach is perfect. We often rely on the context to engage students. The danger of contextualized learning is that learners may not see that concepts transfer to other contexts. For example, someone who has written an algorithm to determine the winner from a collection of players may not see that a very similar algorithm can be used to find the largest file in a directory. The danger of decontextualized learning is that that learners may not see that concepts transfer anywhere.

While this debate is important for educators to consider, I’d like turn it around a bit. What if we embedded computer science in a context not to improve the learning of computer science, but to improve the learning of the context? If the folks using these tools become better makers, mathematicians, and musicians, then my goal will be met.

]]>
https://twodee.org/blog/17018/feed 0
Why 12? https://twodee.org/blog/16962 https://twodee.org/blog/16962#respond Mon, 15 Apr 2019 02:13:31 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/16962 [...]]]> We looked previously at how an octave—or doubling, as we called it—is partitioned non-linearly into intermediate tones. But we didn’t ultimately decide how many intermediate tones there should be. The pioneers of Western music converged on a 12-partition. But why not 8? Or 10? Or 11? Or 13?

Ultimately, we want our instruments to sound pleasing to our ears. Octaves are the prime way to achieve this consonance. The doublings in our instruments’ wires and passageways always sound good together. But we want other combinations to sound good together too.

What does it mean for two notes to sound good together? Physically, it means that the notes’ pressure waves oscillate in such a way that they coincide at regular intervals. In a doubling, for example, two oscillations of the faster wave coincide with one oscillation of the slower wave. The ratio of the frequencies is 2:1.

Of all the possible partitioning schemes, a 12-partition produces the largest proportion of simple ratios. See how nicely the waves for notes 0 and 7 coincide?

In the time that it takes note 0 in red to oscillate twice, note 7 in blue oscillates three times. Our ears will like that!

Meanwhile, as note 0 in red oscillates three times, note 5 in blue oscillates four times:

A whopping six of the intermediate tones can be expressed with simple ratios:

Note Ratio to Root Approximate Ratio
0 $2^\frac{0}{12}$ $1$
1 $2^\frac{1}{12}$ $-$
2 $2^\frac{2}{12}$ $-$
3 $2^\frac{3}{12}$ $\frac{6}{5}$
4 $2^\frac{4}{12}$ $\frac{5}{4}$
5 $2^\frac{5}{12}$ $\frac{4}{3}$
6 $2^\frac{6}{12}$ $-$
7 $2^\frac{7}{12}$ $\frac{3}{2}$
8 $2^\frac{8}{12}$ $\frac{8}{5}$
9 $2^\frac{9}{12}$ $\frac{5}{3}$
10 $2^\frac{10}{12}$ $-$
11 $2^\frac{11}{12}$ $-$
12 $2^\frac{12}{12}$ $2$

The ratios are not exact, it should be noted. For example, note 7 is $2^\frac{7}{12} \approx 1.498307 \neq \frac{3}{2}$. Our ears probably won’t notice this slight deviation.

Given its high probability of producing consonant notes, the 12-partition came to dominate our musical systems. The sequence of all 12 steps is called the chromatic scale, which can be programmed in Deltaphone:

It’s rare that we find all twelve notes in a piece of music. Instead we restrict ourselves to subsets of these notes to achieve an even greater likelihood of consonance.

]]>
https://twodee.org/blog/16962/feed 0
Twelve Steps https://twodee.org/blog/16950 https://twodee.org/blog/16950#respond Fri, 29 Mar 2019 08:20:38 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/16950 [...]]]>

Music theory is a daunting subject, built out of centuries of mathematical analysis and aristocratic pride. Sometimes I think I’d be better off reinventing it than trying to learn it at this late stage of its maturity. Here’s how I might get started.

One day I’d be absently fooling around with a bit of wire, which I’d stretch between two nails. I’d absently pluck the wire and hear it make an intriguing sound. I’d pluck it over and over again until I grew tired, and then I’d move on to something else.

Later on I’d recreate the experiment using another bit of wire, and I’d notice that the sound was similar to but different from my original wire. I’d observe that my second wire was of a different length than my first. Intrigued by this difference, I’d start to experiment. Soon I’d have a series of wires of different lengths that I could pluck. I’d pluck them individually in succession, but I’d also pluck them simultaneously. Some multi-plucks would bring discomfort to my ears, but others would please me.

I don’t have such an instrument to play for you, but I can simulate one. This one has ten wires, with the shortest having length 1 and the longest having length 2:

Much to my surprise, I would discover that a wire of a certain length would “cooperate” with a wire twice its length. I’d find the same to be true of a wire four times as long and half as long. All of them would fit together nicely, as shown in this simulation:

I’d name the region between cooperating wire lengths a doubling. I’d make a device out of several doublings that I would use to entertain friends and pass the time. I wouldn’t be able to have very many doublings, though, before the device became unwieldy and the sound too shrill. I’d want more qualities of sounds. The only way to do this, I’d reason, is to add back in wires with lengths in between each doubling. But I’d need to be careful to only play wires that sounded pleasing together.

Suppose I inserted just one extra wire. What length would I make this new wire? Probably I’m make it the average of the base wire and its double. All told, the wire lengths would be 1, 1.5, and 2. If I named the shortest wire wire 0 and the longest wire 2, I’d document my instrument using the following table of wire numbers and lengths:

Wire Length
0 1
1 1.5
2 2

I’d name this arrangement a 2-partition.

To create a 3-partition, I’d insert another wire, but redistribute the wires evenly, resulting in these lengths:

Wire Length
0 1
1 1.3
2 1.6
3 2

In a 4-partition, I’d have these lengths:

Wire Length
0 1
1 1.25
2 1.5
3 1.75
4 2

And so on and so forth. In general, if I placed n wires in each doubling to make an n-partition, I’d measure each wire according to this formula:

$$\textit{length of wire}_i = 1 + \frac{i}{n}$$

Suppose I settled on a making 12-partition instrument. Visually, a plot of my wire lengths would look like this, with the wires on the x-axis and their lengths on the y-axis:

Eventually, I would try adding more wires after the double: wire 13, wire 14, and so on. Following my length formula, my wires would have these lengths:

Wire Length
0 1
1 1.083
2 1.16
3 1.25
4 1.3
5 1.416
6 1.5
7 1.583
8 1.6
9 1.75
10 1.83
11 1.916
12 2
13 2.083
14 2.16
15 2.25
16 2.3
17 2.416
18 2.5
19 2.583
20 2.6
21 2.75
22 2.83
23 2.916
24 3

In scanning this table, I would eventually find a pernicious flaw in my design. I’d find that going from wire 0 of length 1 to wire 12 of length 2 would produce the doubling that I liked so much. But going up another 12 wires to wire 24 would produce a 3. “That’s not a doubling,” I’d say to myself. Nor is going another 12-partition from wire 1 to wire 13. In fact, there would only be the one doubling in my entire instrument. Given the pleasure I found in doublings and my instrument’s failure to provide them, I would throw my instrument down, smashing it into tiny pieces.

After taking some time cool off, I would vent about my failure with some trusted friends, and they would think through the problem with me. In particular, one might suggest trying a different partitioning scheme. Perhaps instead of dividing the doubling into equally-sized chunks, in which each neighboring pair of wires has the same additive difference, the friend would wonder what would happen if I made each pair of wires have the same multiplicative ratio.

I’d wonder what ratio I should use. A ratio of 1 would make every string have the same length. A ratio of 2 would make every string a doubling. I’d conclude that I needed a ratio x somewhere between 1 and 2. It would take me a while to figure out exactly what ratio to use. But in my notebook I’d mark down the following observations about the wire lengths and their relationships if their ratio was held constant. Each wire would be some fixed proportion x of the previous wire:

Wire Length
0 1
1 $\textrm{length}_0 \cdot x$
2 $\textrm{length}_1 \cdot x$
3 $\textrm{length}_2 \cdot x$
4 $\textrm{length}_3 \cdot x$
… …
i $\textrm{length}_{i – 1} \cdot x$

After considering this table, I’d find that I could simplify the lengths by substituting in the previous wires’ lengths:

Wire Length Simplified Length
0 1 1
1 $\textrm{length}_0 \cdot x$ $1 \cdot x = x$
2 $\textrm{length}_1 \cdot x$ $x \cdot x = x^2$
3 $\textrm{length}_2 \cdot x$ $x^2 \cdot x = x^3$
4 $\textrm{length}_3 \cdot x$ $x^3 \cdot x = x^4$
… … …
i $\textrm{length}_{i – 1} \cdot x$ $x^{i – 1} \cdot x = x^i$

From this table, I would know that wire 12 would have length $x^{12}$. But I would also excitedly recall that I wanted wire 12 to have length 2. With two measures of the same string, I would figure out what x should be:

$$\begin{array}{rcl}x^{12} &=& 2 \\\sqrt[12]{x^{12}} &=& \sqrt[12]{2} \\x &=& \sqrt[12]{2} = 2^\frac{1}{12}\end{array}$$

Plugging this magic value of x into my table, I’d find the following exact lengths of the wires:

Wire Length
0 $x^0 = (2^\frac{1}{12})^0 = 1$
1 $x^1 = (2^\frac{1}{12})^1 = 1.059463$
2 $x^2 = (2^\frac{1}{12})^2 = 1.122462$
3 $x^3 = (2^\frac{1}{12})^3 = 1.189207$
4 $x^4 = (2^\frac{1}{12})^4 = 1.259921$
… …
i $x^i = (2^\frac{1}{12})^i = 2^\frac{i}{12}$
… …
12 $x^{12} = (2^\frac{1}{12})^{12} = 2$
13 $x^{13} = (2^\frac{1}{12})^{13} = 2.118926$
… …
24 $x^{24} = (2^\frac{1}{12})^{24} = 4$
… …

To my delight, I would find doublings all over—in fact, every 12-wire jump would yield a doubling!

Visually, a plot of my wire lengths for a ratio-based 12-partition would look like the blue line, with the old scheme plotted in green:

This table and plot show the lengths for a 12-partition. For a more general n-partition under this new ratio-based partitioning scheme, I’d measure each wire i according to this formula:

$$\textit{length of wire}_i = 2^\frac{i}{n}$$

I would then rebuild my instrument to span several doublings, with each wire being $2^\frac{1}{12}$ times the length of the preceding wire:

I would still find combinations of wires that didn’t sound pleasing, but I’d also find a number of combinations that did sound pleasing. Furthermore, the combinations that sounded good together in one doubling would sound just as good if I shifted them to a different doubling. And I’d find doublings between each pair of 12 notes.

Thus would I become the father of music theory. But really, I’d just think of myself as a musician trying to please my own ears.

]]>
https://twodee.org/blog/16950/feed 0
Intervals in Deltaphone https://twodee.org/blog/16923 https://twodee.org/blog/16923#respond Wed, 27 Feb 2019 01:25:28 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/16923 [...]]]> For a few years now, schools and industry have been telling kids that they can code. They say the jobs are plentiful, and the salary is enviable—the workforce is waiting. The nobler agents of educational reform will also tell our kids that programming is a creative exercise that will make them better thinkers in other disciplines. However, programming is often taught as a context in and of itself. It’s hard to learn two things at a time, and it’s even harder to teach them.

The past year or so I’ve been taking piano lessons from a guy I met on the internet. The lessons expose me to ideas about music theory that I want to understand, but I’ve gotten to the point in life where I don’t feel like I understand anything unless I program it. So, I started working on Deltaphone not as a tool to teach computer science, but as a tool to teach myself music. I will be slowly writing up the things I learn about music by coding it.

Today our subject is intervals. Pick any two notes. The gap between their frequencies is their interval. Play the notes at the same time or in succession. If they sound pleasing together, we say that the interval is consonant, which derives from the Latin word for “to sound together.” If they don’t sound pleasing, they are dissonant.

On a rainy day it might be interesting to play all possible intervals and decide which ones we think are consonant. But there are so many possible intervals. We’d probably need a rainy week! However, we may not need a week for three reasons:

  • The musicians of past centuries have already affixed the labels consonant and dissonant to all the intervals that we could dream up.
  • We don’t typically play just any two notes. We tend to play notes that are in the same scale.
  • The labeling exercise is pointless. Just because an interval is dissonant, that doesn’t mean musicians don’t play it.

The standard intervals that our Western musical ancestors defined for us are as follows:

  • Unison: a note paired with itself.
  • Second: a note paired with the second note in the scale.
  • Third: a note paired with the third note in the scale.
  • Fourth: a note paired with the fourth note in the scale.
  • Fifth: a note paired with the fifth note in the scale.
  • Sixth: a note paired with the sixth note in the scale.
  • Seventh: a note paired with the seventh note in the scale.
  • Eighth: a note paired with itself in the next higher octave.

Let’s make this idea concrete by writing a Deltaphone program to play all of these intervals, and we can decide for ourselves about their consonance. We start by dragging out the play block that supports chords, and we combine C4 and the note 0 steps above it in the current key:

The other intervals can be formed in similar fashion. We need only change the delta:

While this works, it’s very repetitive. After the first intervals, the ideas stop being new. Let’s generalize this into a function. We’ll have the parameter be the interval’s number.

You may have noticed in the previous video that the second used a delta of +1. This is confusing. For our function, we’ll make it so that if the caller passes a 2, we’ll play the second. If the caller passes a 3, we’ll play the third. And so on. We’ll need to subtract 1 from the parameter to get the delta:

This feels pretty good, but let’s generalize interval so that it can play from any root note, and let’s also use a for loop to walk through our numbers:

That’s enough about intervals for now. In the next installment, we’ll see how these intervals change when the underlying scale changes.

]]>
https://twodee.org/blog/16923/feed 0
Stepping Up in Deltaphone https://twodee.org/blog/16892 https://twodee.org/blog/16892#respond Thu, 18 Oct 2018 23:15:15 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/16892 [...]]]> Recently I added chords to Deltaphone, which required me to rethink how I was structuring the blocks to play notes. Previously, the play block came in two forms. There was a form for an absolutely-specified note, like “play C natural in the fourth octave.” And there was a form for a relatively-specified note, like “play the note 2 halfsteps up from where I’m currently at on the staff.” They looked like this:

How do I add chords to this? My first attempt was to add a new chord statement that accepted a stack of play statements. Something like this:

But this structure has two problems. First, a chord generally should have all of its notes be of the same duration. (The MusicXML docs agree.) Each play block has its duration specified separately and is therefore vulnerable to getting out of sync with its siblings. Second, other statements can be nested inside the chord, like repeat blocks, which is nonsense.

I decided instead to generalize the play to a single block that could play absolute notes, relative notes, or chords. Polymorphism fixes everything, right? The new block looked like this in its different contexts:

But after using this new play block to compose some simple songs, it felt too heavyweight. I want to be able to take Deltaphone into an elementary school classroom, and I expected that the polymorphic solution would require too much explanation. But I still needed a way to play chords. So, I decided to keep all three forms of the play block.

See them at work as I program the stepping-up-and-stepping-down exercise:

The exercise ends with three chords: a I chord, a V7 chord, and a I chord. With chords, only the root note has any long-term effect on the “cursor” that marks our current position on the staff.

]]>
https://twodee.org/blog/16892/feed 0
Kookaburra in Deltaphone https://twodee.org/blog/16891 https://twodee.org/blog/16891#comments Thu, 18 Oct 2018 20:51:30 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
https://twodee.org/blog/16891 [...]]]> Though we have been in Australia for several months, we have hardly seen any of its unique wildlife. Fearing that we’d return home with no distinctly Australian experiences, we set out to find some animals. Given the number of news reports I’ve heard about kangaroos injuring humans, we decided to take it slow. We headed to the Daisy Hill Koala Centre.

The koalas slept precariously in their perches, and we looked at them. It was great—until a loud boom came from within the center. A large spinning wheel that was part of a display had come loose from its mount and had fallen on a child. It’s not just the kangaroos.

One thing we have seen (and heard) plenty of are Australian birds. Like the noisy miner, magpie, and the kookaburra. There’s a famous Australian song about a kookaburra sitting in an old gum tree, and I was inspired to program its first two lines in Deltaphone:

This song was a helpful exercise. In programming it, I discovered that the second line is not an exact transposition of the first. If I maintain the exact halfstep differences between notes, I end up landing on notes not in the key of C major. See:

This led me to add a unit specifier to the delta blocks. One can jump either in halfsteps or in keysteps. Keystep jumps move a number of positions within the scale of the current key signature. This version sounds much better:

]]>
https://twodee.org/blog/16891/feed 3