{"id":13608564,"url":"https://github.com/atsushieno/compose-audio-controls","last_synced_at":"2025-04-21T20:32:39.849Z","repository":{"id":171967478,"uuid":"648495810","full_name":"atsushieno/compose-audio-controls","owner":"atsushieno","description":"audio controls for Jetpack Compose and Compose for Multiplatform ","archived":false,"fork":false,"pushed_at":"2024-09-07T10:41:22.000Z","size":3957,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-07T14:40:54.371Z","etag":null,"topics":["aap","android","audio","compose-multiplatform","jetpack-compose","keyboard","knob-control","midi","midi2"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/atsushieno.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-02T05:33:26.000Z","updated_at":"2024-09-07T06:09:24.000Z","dependencies_parsed_at":"2024-02-17T09:29:28.592Z","dependency_job_id":"f4ecbe40-557b-4a6e-8887-7d9f4a26ef71","html_url":"https://github.com/atsushieno/compose-audio-controls","commit_stats":null,"previous_names":["atsushieno/compose-audio-controls"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Fcompose-audio-controls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Fcompose-audio-controls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Fcompose-audio-controls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Fcompose-audio-controls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atsushieno","download_url":"https://codeload.github.com/atsushieno/compose-audio-controls/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223877434,"owners_count":17218574,"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":["aap","android","audio","compose-multiplatform","jetpack-compose","keyboard","knob-control","midi","midi2"],"created_at":"2024-08-01T19:01:28.307Z","updated_at":"2024-11-09T20:19:35.021Z","avatar_url":"https://github.com/atsushieno.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# Compose Audio Controls\n\n![demoapp sshot](docs/images/demoapp-sshot.png)\n\nIt is a repository for Jetpack Compose / Compose for Multiplatform widgets\nfor audio apps.\n\n## ImageStripKnob\n\n![ImageStripKnob demoapp](docs/images/ImageStripKnob.png)\n\n[`ImageStripKnob`](https://atsushieno.github.io/compose-audio-controls/compose-audio-controls/org.androidaudioplugin.composeaudiocontrols/-image-strip-knob.html) is a knob audio control based on an image strip.\n\n### KnobMan image strip\n\nIt makes use of [KnobMan](https://www.kvraudio.com/product/knobman-by-g200kg) image resource. If you are curious what this means, go to [Knob Gallery](https://www.g200kg.com/en/webknobman/gallery.php). You can use these knobs without coding anything. It is a cheap trick, but offers what people really need. It is used by wide range of people in audio app industry (such as [Kontakt](https://www.native-instruments.com/en/products/komplete/samplers/kontakt-7/) instrument, Web audio/music app developers who use [webaudio-controls](http://g200kg.github.io/webaudio-controls/docs/)). It gives you a lot of choices:\n\n![KnobGallery sshot](docs/images/KnobGallery-sshot.png)\n\n### Knob UI implementation\n\nIt respects \"Consider making touch targets at least 48x48dp\" principle in the [Android Accessibility Help](https://support.google.com/accessibility/android/answer/7101858?hl=en) guideline. You can override it at your own risk though.\n\nWe know what musicians actually want: it is a simple single-fingered vertically draggable knob. No pinching like real knobs required.\n\nSometimes we want fine-tuning. If you hold 1000 milliseconds (by default) it will enter \"fine mode\" where the value changes are multiplied by 0.1. It will happen at any time until you release your finger or mouse pointer.\n\nA value label tooltip will be shown when you drag over the knob. Your finger may be hiding it though; you can move the finger to left or right without changing value (to make it possible, we assign no horizontal control, at least for now). The tooltip is customizible - you can pass any `@Composable`.\n\nIt should be noted that `ImageStripKnob` is NOT a Material Design based component. You would be able to add some animation effects by your own (we also welcome contribution if it's optional and looking generally useful).\n\n### Usage example\n\n```kotlin\nvar paramValue by remember { mutableStateOf(0f) }\nText(\"Parameter $paramIndex: \")\nImageStripKnob(\n    drawableResId = R.drawable.knob_image,\n    value = paramValue,\n    onValueChange = {v -\u003e\n        paramValue = v\n        println(\"value at $paramIndex changed: $v\")\n        })\n```\n\nNoted that support for Android resource ID is specific to Android platform. If your project is Kotlin Multiplatform, use `ImageBitmap` instead.\n\n## DiatonicKeyboard\n\n![DiatonicKeyboard sshot](docs/images/DiatonicKeyboard.png)\n\n[`DiatonicKeyboard`](https://atsushieno.github.io/compose-audio-controls/compose-audio-controls/org.androidaudioplugin.composeaudiocontrols/-diatonic-keyboard.html) is a diatonic music keyboard control.\n\nIn addition, [`DiatonicKeyboardWithControllers`](https://atsushieno.github.io/compose-audio-controls/compose-audio-controls/org.androidaudioplugin.composeaudiocontrols/-diatonic-keyboard-with-controllers.html) adds some controllers for the parameters (explained below) to the keyboard. It takes extra space, but makes it more convenient.\n\nIts event handlers receive note number (and additional information in the next versions, unused argument so far).\n\nIt supports touch motions. There are two modes regarding how they are handled, up to \"moveAction\" \nparameter:\n\n- `NoteChange`: when it is dragged to another note region, a note off for current note and a new note on will be sent.\n- `NoteExpression`: when it is dragged, it will trigger `onNoteExpression` callback, for horizontal and vertical dragging, plus the pointer \"pressure\" if it is supported by device.\n\nTake it like, it works as an MPE (or MIDI 2.0) keyboard too.\nNote that note changes and note expressions are exclusive behaviors (we cannot do both).\nNote expression support works only if it is explicitly enabled.\n\nThe default note expression ranges on screen is 160.dp, 80dp on all directions (L \u003c-\u003e R, T \u003c-\u003e B).\nThe value sent to `onExpression` event handler ranges between `-1.0f..1.0f`.\nIt is up to you what kind of controls to assign, on X axis, Y axis, and pressure.\n\n### DiatonicKeyboard UI implementation\n\nIt is designed to be touchable on screen but not to become small as a musical keyboard.\nOne optimization made there is different pointer treat on touches and mouse/stylus.\nFor touches, the target note is calculated based on the nearest to the center of the keys.\nOn the other hand, if the input type is mouse or stylus, it expects exact insets.\n\n### Usage example\n\n```kotlin\nval noteOnStates = remember { List(128) { 0 }.toMutableStateList() }\nDiatonicKeyboard(noteOnStates.toList(),\n    // you will also insert actual musical operations within these lambdas\n    onNoteOn = { note, _ -\u003e\n        noteOnStates[note] = 1\n        println(\"note on: $note\")\n    },\n    onNoteOff = { note, _ -\u003e\n        noteOnStates[note] = 0\n        println(\"note off: $note\")\n    }\n)\n```\n\n## Using compose-audio-controls\n\nAdd the following `implementation` line to your dependencies list:\n\n```groovy\ndependencies {\n    implementation 'org.androidaudioplugin:compose-audio-controls:+' //replace `+` with your own\n}\n```\n\nThe API reference is published at https://atsushieno.github.io/compose-audio-controls/ (updated for every new release tagging)\n\n## Showcases\n\n[Resident MIDI Keyboard](https://github.com/atsushieno/resident-midi-keyboard) is a straightforward usage example of `DianoticKeyboardWithControllers`. (It used to be part of this project, but now has its own home.)\n\n[AAP (Audio Plugins For Android)](https://github.com/atsushieno/aap-core) makes use of the keyboard and knob as part of the default native (Compose) UI.\n\n## License\n\ncompose-audio-controls is released under the MIT license.\n\nThe sample app contains some public-domain images from KnobGallery.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatsushieno%2Fcompose-audio-controls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatsushieno%2Fcompose-audio-controls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatsushieno%2Fcompose-audio-controls/lists"}