{"id":17238434,"url":"https://github.com/chaosprint/raveforce","last_synced_at":"2025-04-07T06:12:59.801Z","repository":{"id":57460169,"uuid":"170512152","full_name":"chaosprint/RaveForce","owner":"chaosprint","description":"RaveForce - An OpenAI Gym style toolkit for music generation experiments.","archived":false,"fork":false,"pushed_at":"2022-05-11T18:01:58.000Z","size":1469,"stargazers_count":246,"open_issues_count":3,"forks_count":12,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-31T05:05:06.437Z","etag":null,"topics":["deep-learning","deep-reinforcement-learning","music-generation","supercollider"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chaosprint.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-13T13:25:01.000Z","updated_at":"2025-03-19T13:19:08.000Z","dependencies_parsed_at":"2022-08-28T13:52:14.104Z","dependency_job_id":null,"html_url":"https://github.com/chaosprint/RaveForce","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaosprint%2FRaveForce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaosprint%2FRaveForce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaosprint%2FRaveForce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaosprint%2FRaveForce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chaosprint","download_url":"https://codeload.github.com/chaosprint/RaveForce/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247601449,"owners_count":20964864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","deep-reinforcement-learning","music-generation","supercollider"],"created_at":"2024-10-15T05:45:39.472Z","updated_at":"2025-04-07T06:12:59.785Z","avatar_url":"https://github.com/chaosprint.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RaveForce\nRaveForce is a Python package that allows you to define your musical task in Python with [Glicol](https://glicol.org) syntax, and train an agent to do the task with APIs similar to the [OpenAI Gym](https://gym.openai.com).\n\nHere is [an interactive example on the Google Colab](https://colab.research.google.com/drive/1mngiLHKrtCs4V2yfSfeILByCTtmdkPoJ?usp=sharing).\n\n![The result after 2000 iterations](https://raw.githubusercontent.com/chaosprint/RaveForce/main/demo_result.png)\n\n## Why RaveForce\n\nLet's consider a simple example: you want to train an agent to play the synth sequencer for you. The goal is to mimic a famous bass line. Therefore, in each `step`, the `agent` needs to make a decision on which note to play and what kind of timbre to make. The agent can have an `observation` of what has been synthesised, and the `reward` is calculated by comparing the similarity between the synthesised audio and the target at the moment.\n\nYet it can be very difficult and time-consuming to build a real-world environment (such as a music robot) to cover all the needs for electronic music. Another option is to use some built-in Python function to compose our `music tasks`, but still, for each task, you need to write some DSP function chains which will be unlikely for these codes to be used again in the real world. A better way is to find a commonplace between our simulation and real-world music practices. Live coding is exactly such a practice where the artist performs improvised algorithmic music by writing program code in real-time. What if we train a virtual agent to write (part of the) code to synthesis a loop for us?\n\nThe architecture looks like this:\n```mermaid\nflowchart TD\n    A[agent, i.e. a neural network] --\u003e B\n    B[input current states. output params of the live coding code] --\u003e C\n    C[live coding engine does the non-real-time synthesis] --\u003e D\n    D[get the reward, observation space, etc.] -- update --\u003e A\n```\n\nThis process should involve some deep neural network as the synthesised audio is much more difficult to process than the symbolic sequences.\n\nPreviously, SuperCollider is used for RaveForce. See paper:\n\u003e Lan, Qichao, Jim Tørresen, and Alexander Refsum Jensenius. \"RaveForce: A Deep Reinforcement Learning Environment for Music Generation.\" (2019).\n\nBut due to the speed limit of non-real-time synthesis on hard disk from SuperCollider, we switch to Glicol. \n\nGlicol is a new live coding language that can be accessed in the browsers:\n\nhttps://glicol.org\n\nThe syntax of Glicol is very similar to synth or sequencers, which perfectly fits our needs. Plus, Glicol is written in Rust and can be called in Python via WebAssembly (there are other methods but wasm is used since it shares the same format with Glicol js bindings).\n\n## How to use RaveForce\n\n### Install\nThis is quite straightforward:\n`pip install raveforce`\n\n### Be familiar with Glicol syntax.\n\nVisit Glicol website to get familiar with its syntax and concept:\n\nhttps://glicol.org\n\n### Python\nSince we are going to define our own musical task, we should make some changes to the `make` method.\n\nLet's consider the simplest example: just let the agent to play for 1 step, tweaking `attack`, `decay` and `freq` of a sine wave synth to simulate a kick drum.\n\n```python\nimport raveforce\nimport librosa\n\ntarget, sr = librosa.load(\"YOUR_KICK_DRUM_SAMPLE\", sr=None)\ndur = len(target) / sr\n\nenv = gym.make(\n    \"\"\"\n     ~env: imp 0.1 \u003e\u003e envperc {} {}\n    kick_drum: sin {} \u003e\u003e mul ~env\n    \"\"\",\n    total_step=1,\n    step_len=dur,\n    target = target,\n    action_space=[\n      (\"lin\", 0.0001, dur-0.0001), \n      (\"rel\", 0, lambda x: dur-0.0001-x), # related to para 0\n      (\"exp\", 10, 10000)\n    ]\n)\n```\n\nThen, use as a normal `Gym` env:\n```python\nobservation = env.reset()\naction = env.action_space.sample()\nprint(action)\n\nobservation, reward, done, info = env.step(action)\nplt.plot(observation) # make your own import matplotlib\nprint(reward, done, info)\n```\n\n## License\n\nGlicol branch (main):\n\n\u003e MIT License\n\nSuperCollider branch:\n\n\u003e GPL-3.0 License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaosprint%2Fraveforce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchaosprint%2Fraveforce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaosprint%2Fraveforce/lists"}