{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "b7c95bcb", "metadata": {}, "outputs": [], "source": [ "from automuse.midi import Instrument, Player, play, change_instrument\n", "from time import sleep\n", "import automuse.chord as chord\n", "import automuse.modes as modes" ] }, { "cell_type": "markdown", "id": "bc16188e", "metadata": {}, "source": [ "# Playing Notes\n", "\n", "AutoMuse comes with a parallelised MIDI player, implemented in `omusic.midi`. The module exports very few components:\n", "\n", "* `change_instrument` changes the current instrument to one of `omusic.midi.Instrument`. Default is the Acoustic Grand Piano.\n", "\n", "* `.Player` creates a player. This player controls a MIDI port and acts as a context manager.\n", "\n", "* `.play` plays notes with a player.\n", "\n", "* `.port` returns the default MIDI port." ] }, { "cell_type": "markdown", "id": "d6cb6f29", "metadata": {}, "source": [ "## Playing Notes\n", "\n", "Let's begin with a quick example: play the $\\text{C}_5$. To make the note last, set its `duration` to 3 seconds." ] }, { "cell_type": "code", "execution_count": 2, "id": "c116c24a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "closing\n" ] } ], "source": [ "with Player() as player:\n", " play(player, \"C5\", duration=3)\n", " " ] }, { "cell_type": "markdown", "id": "2af4003d", "metadata": {}, "source": [ "Moving on to another example, let's try the $\\text{I}\\rightarrow\\text{IV}\\rightarrow\\text{V}\\rightarrow\\text{I}$ progression:" ] }, { "cell_type": "code", "execution_count": 3, "id": "cda21418", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "closing\n" ] } ], "source": [ "with Player() as player:\n", " for _ in range(1):\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=0))\n", " sleep(0.4)\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=3))\n", " sleep(0.4)\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=4))\n", " sleep(0.4)\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=0))\n", " sleep(0.4)" ] }, { "cell_type": "markdown", "id": "28a513a1", "metadata": {}, "source": [ "The `play` function has several parameters that \"humanise\" the output. These are:\n", "\n", "* arpeggio: Order of notes to play, can be `None` (do not reorder), `ascending`, or `descending`.\n", "* spacing: Melodic intervals between notes, if a list is given in `notes`.\n", "* touch: Variation in note velocity (touch pressure).\n", "\n", "The exact values, same as many things in music, are up to creative choices. Setting aside _reason_ for a moment, let's hear what different combinations sound like:" ] }, { "cell_type": "code", "execution_count": 4, "id": "336b1199", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "closing\n" ] } ], "source": [ "\n", "plan_1 = {\"arpeggio\": \"ascending\",\n", " \"spacing\": 0,\n", " \"touch\": 0,\n", " \"duration\": 1}\n", "\n", "plan_2 = {\"arpeggio\": \"descending\",\n", " \"spacing\": (0, 2),\n", " \"touch\": (-30, 30),\n", " \"duration\": 1}\n", "\n", "with Player() as player:\n", " for _ in range(1):\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=0), **plan_1)\n", " sleep(0.4)\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=3), **plan_1)\n", " sleep(0.4)\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=4), **plan_2)\n", " sleep(0.4)\n", " play(player, notes=chord.chord(\"C5\", modes.MAJOR, order=0), **plan_2)\n", " sleep(0.4)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.10" } }, "nbformat": 4, "nbformat_minor": 5 }