{"id":16508576,"url":"https://github.com/osteele/dart-tonic","last_synced_at":"2025-03-16T18:32:31.970Z","repository":{"id":14541097,"uuid":"17256053","full_name":"osteele/dart-tonic","owner":"osteele","description":"Music theory Dart package","archived":false,"fork":false,"pushed_at":"2024-01-24T03:36:55.000Z","size":131,"stargazers_count":52,"open_issues_count":3,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-15T22:56:14.139Z","etag":null,"topics":["music-theory"],"latest_commit_sha":null,"homepage":null,"language":"Dart","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/osteele.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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":"2014-02-27T16:44:09.000Z","updated_at":"2025-03-02T12:42:16.000Z","dependencies_parsed_at":"2023-11-26T00:19:12.286Z","dependency_job_id":"56aa927d-2bbf-4158-b1a1-ac974a339ccd","html_url":"https://github.com/osteele/dart-tonic","commit_stats":{"total_commits":68,"total_committers":7,"mean_commits":9.714285714285714,"dds":0.1029411764705882,"last_synced_commit":"0f30ec010246ea048423cf17f3c7ca2ad75ab758"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fdart-tonic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fdart-tonic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fdart-tonic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fdart-tonic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osteele","download_url":"https://codeload.github.com/osteele/dart-tonic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243826780,"owners_count":20354220,"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":["music-theory"],"created_at":"2024-10-11T15:46:18.235Z","updated_at":"2025-03-16T18:32:27.789Z","avatar_url":"https://github.com/osteele.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tonic\n\n[![Dart badge][dart-svg]][dart-url]\n[![pub package](https://img.shields.io/pub/v/tonic.svg)](https://pub.dartlang.org/packages/tonic)\n\nTonic is a [Flutter](https://flutter.io)-compatible\n[Dart](https://www.dartlang.org) package that models components of music theory.\n\n## Installation\n\n1\\. Add the following to your `pubspec.yaml`\n\n```yaml\ndependencies:\n  tonic: any\n```\n\n2\\. Run `pub get`\n\n## Usage\n\nSee the [API docs](https://pub.dartlang.org/documentation/tonic/latest/).\n\n### Examples\n\n```dart\nimport 'package:tonic/tonic.dart';\n\nmain() {\n  // Hemholtz and Scientific pitch notation\n  print(Pitch.parse('C4'));\n  print(Pitch.parse('C♯4'));\n  print(Pitch.parse('C♭4'));\n\n  // Unicode and ASCII sharps and flats\n  print(Pitch.parse('C#4') == Pitch.parse('C#4')); // =\u003e true\n  print(Pitch.parse('Cb4') == Pitch.parse('Cb4')); // =\u003e true\n\n  // Enharmonic equivalents\n  print(Pitch.parse('E♯4').midiNumber == Pitch.parse('F4').midiNumber); // =\u003e true\n  print(Pitch.parse('E4').midiNumber == Pitch.parse('F♭4').midiNumber); // =\u003e true\n  print(Pitch.parse('E♯4') == Pitch.parse('F4')); // =\u003e false\n  print(Pitch.parse('E4') == Pitch.parse('F♭4')); // =\u003e false\n\n  print(Pitch.parse('C4').octave); // =\u003e 5\n  print(Pitch.parse('C4').midiNumber); // =\u003e 60\n  print(new Pitch.fromMidiNumber(60)); // =\u003e C4\n  print(new Pitch.fromMidiNumber(60).helmholtzName); // =\u003e c'\n\n  // Intervals\n  print(Interval.M3);\n  print(Interval.parse('M3'));\n  print(Interval.m3.semitones); // =\u003e 3\n  print(Interval.M3.semitones); // =\u003e 4\n  print(Interval.A3.semitones); // =\u003e 5\n  print(Interval.d4.semitones); // =\u003e 4\n  print(Interval.P4.semitones); // =\u003e 5\n  print(Interval.A4.semitones); // =\u003e 6\n  print(Interval.M3.number); // =\u003e 3\n  print(Interval.M3.qualityName); // =\u003e \"M\"\n\n  // Interval arithmetic\n  print(Interval.M3 + Interval.m3); // =\u003e P5\n  print(Interval.m3 + Interval.M3); // =\u003e P5\n  print(Interval.m3 + Interval.m3); // =\u003e d5\n  print(Interval.M3 + Interval.M3); // =\u003e A5\n\n  print(Pitch.parse('C4') + Interval.M3); // =\u003e E4\n  print(Pitch.parse('C4') + Interval.A3); // =\u003e E♯4\n  print(Pitch.parse('C4') + Interval.d4); // =\u003e F♭4\n  print(Pitch.parse('C4') + Interval.P4); // =\u003e F4\n\n  print(Pitch.parse('C4') - Pitch.parse('C4'));   // =\u003e P1\n  print(Pitch.parse('D4') - Pitch.parse('C4'));   // =\u003e M2\n  print(Pitch.parse('E4') - Pitch.parse('C4'));   // =\u003e M3\n  print(Pitch.parse('E♯4') - Pitch.parse('C4')); // =\u003e A3\n  print(Pitch.parse('F♭4') - Pitch.parse('C4')); // =\u003e d4\n  print(Pitch.parse('F4') - Pitch.parse('C4'));  // =\u003e P4\n\n  // Chords\n  print(Chord.parse('E Major'));\n  print(ChordPattern.parse('Dominant 7th')); // =\u003e Dom 7th\n  print(ChordPattern.fromIntervals([Interval.P1, Interval.M3, Interval.P5])); // =\u003e Major\n  print(ChordPattern.fromIntervals([Interval.P1, Interval.m3, Interval.P5])); // =\u003e Minor\n  print(ChordPattern.fromIntervals([Interval.P1, Interval.m3, Interval.P5, Interval.m7])); // =\u003e Min 7th\n\n  // Scales\n  final scalePattern = ScalePattern.findByName('Diatonic Major');\n  print(scalePattern.intervals); // =\u003e [P1, M2, M3, P4, P5, M6, M7]\n  print(scalePattern.modes);\n  print(scalePattern.modes['Dorian'].intervals); // =\u003e [P1, M2, m3, P4, P5, M6, m7]\n\n  final scale = scalePattern.at(Pitch.parse('E4'));\n  print(scale.intervals); // =\u003e [P1, M2, M3, P4, P5, M6, M7]\n  print(scale.pitchClasses); // =\u003e [E4, F♯4, G♯4, A4, B4, C♯5, D♯5]\n\n  // Instruments and fret fingerings\n  final chord = Chord.parse('E Major');\n  final instrument = Instrument.Guitar;\n  print(bestFrettingFor(chord, instrument)); // =\u003e 022100\n}\n```\n\nMore examples can be found in the tests in `test/*_test.dart`.\n\n## Other Versions\n\n* **Dart 1.x**. [Version\n  0.1.1](https://github.com/osteele/dart-tonic/tree/v0.0.1) of this library is\n  compatible with Dart 1.x.\n* **TypeScript**. This (Dart) package is ported from\n  [tonic.ts](https://github.com/osteele/tonic.ts), for TypeScript.\n\n## License\n\nMIT\n\n[dart-url]: https://github.com/osteele/dart-tonic/actions?query=workflow%3A%22Build+Status%22\n[dart-svg]: https://github.com/osteele/dart-tonic/actions/workflows/dart.yml/badge.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosteele%2Fdart-tonic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosteele%2Fdart-tonic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosteele%2Fdart-tonic/lists"}