diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..162db52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.pyc +*.egg +.eggs/ +.ipynb_checkpoints/ +*.swp +*.egg-info/ +.cache/ +build/ +*.DS_Store +.vscode +.idea/ diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 0000000..0f4d103 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,7 @@ +[settings] +line_length=1000 +force_single_line=True +force_sort_within_sections=True +default_section=THIRDPARTY +sections=FUTURE,STDLIB,LOCALFOLDER,THIRDPARTY +no_lines_before=THIRDPARTY diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..b223df6 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,453 @@ +# This Pylint rcfile contains a best-effort configuration to uphold the +# best-practices and style described in the Google Python style guide: +# https://google.github.io/styleguide/pyguide.html +# +# Its canonical open-source location is: +# https://google.github.io/styleguide/pylintrc + +[MASTER] + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=third_party + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Pickle collected data for later comparisons. +persistent=no + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Use multiple processes to speed up Pylint. +jobs=4 + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist= + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=abstract-method, + apply-builtin, + arguments-differ, + attribute-defined-outside-init, + backtick, + bad-option-value, + buffer-builtin, + c-extension-no-member, + consider-using-enumerate, + cmp-builtin, + cmp-method, + coerce-builtin, + coerce-method, + delslice-method, + div-method, + duplicate-code, + eq-without-hash, + execfile-builtin, + file-builtin, + filter-builtin-not-iterating, + fixme, + getslice-method, + global-statement, + hex-method, + idiv-method, + implicit-str-concat-in-sequence, + import-error, + import-self, + import-star-module-level, + inconsistent-return-statements, + input-builtin, + intern-builtin, + invalid-str-codec, + locally-disabled, + long-builtin, + long-suffix, + map-builtin-not-iterating, + misplaced-comparison-constant, + missing-function-docstring, + metaclass-assignment, + next-method-called, + next-method-defined, + no-absolute-import, + no-else-break, + no-else-continue, + no-else-raise, + no-else-return, + no-init, + no-member, + no-name-in-module, + no-self-use, + nonzero-method, + not-context-manager, # added + oct-method, + old-division, + old-ne-operator, + old-octal-literal, + old-raise-syntax, + parameter-unpacking, + print-statement, + raise-missing-from, + raising-string, + range-builtin-not-iterating, + raw_input-builtin, + rdiv-method, + reduce-builtin, + relative-import, + reload-builtin, + round-builtin, + setslice-method, + signature-differs, + standarderror-builtin, + super-with-arguments, + suppressed-message, + sys-max-int, + too-few-public-methods, + too-many-ancestors, + too-many-arguments, + too-many-boolean-expressions, + too-many-branches, + too-many-instance-attributes, + too-many-locals, + too-many-nested-blocks, + too-many-public-methods, + too-many-return-statements, + too-many-statements, + trailing-newlines, + unbalanced-tuple-unpacking, # added + unichr-builtin, + unicode-builtin, + unnecessary-pass, + unpacking-in-except, + unsubscriptable-object, # added + useless-else-on-loop, + useless-object-inheritance, + useless-suppression, + using-cmp-argument, + wrong-import-order, + xrange-builtin, + zip-builtin-not-iterating, + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". This option is deprecated +# and it will be removed in Pylint 2.0. +files-output=no + +# Tells whether to display a full report or only the messages +reports=no + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + + +[BASIC] + +# Good variable names which should always be accepted, separated by a comma +good-names=main,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl + +# Regular expression matching correct function names +function-rgx=^(?:(?PsetUp|tearDown|setUpModule|tearDownModule)|(?P_?[A-Z][a-zA-Z0-9]*)|(?P_?[a-z][a-z0-9_]*))$ + +# Regular expression matching correct variable names +variable-rgx=^[a-z][a-z0-9_]*$ + +# Regular expression matching correct constant names +const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ + +# Regular expression matching correct attribute names +attr-rgx=^_{0,2}[a-z][a-z0-9_]*$ + +# Regular expression matching correct argument names +argument-rgx=^[a-z][a-z0-9_]*$ + +# Regular expression matching correct class attribute names +class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ + +# Regular expression matching correct inline iteration names +inlinevar-rgx=^[a-z][a-z0-9_]*$ + +# Regular expression matching correct class names +class-rgx=^_?[A-Z][a-zA-Z0-9]*$ + +# Regular expression matching correct module names +module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$ + +# Regular expression matching correct method names +method-rgx=(?x)^(?:(?P_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P_{0,2}[a-z][a-z0-9_]*))$ + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$ + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=10 + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=80 + +# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt +# lines made too long by directives to pytype. + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=(?x)( + ^\s*(\#\ )??$| + ^\s*(from\s+\S+\s+)?import\s+.+$) + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=yes + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check= + +# Maximum number of lines in a module +max-module-lines=99999 + +# String used as indentation unit. The internal Google style guide mandates 2 +# spaces. Google's externaly-published style guide says 4, consistent with +# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google +# projects (like TensorFlow). +indent-string=' ' + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=TODO + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=yes + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_) + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_,_cb + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging, + absl.logging, + tensorflow.io.logging # added + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + + +[SPELLING] + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec, + sets + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant, absl + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls, + class_ + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=StandardError, + Exception, + BaseException diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..465a024 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,7 @@ +# This is the list of Magenta authors for copyright purposes. +# +# This does not necessarily list everyone who has contributed code, since in +# some cases, their employer may be the copyright holder. To see the full list +# of contributors, see the revision history in source control. +Google LLC +Szymon Sidor \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e3db600 --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright 2016 The Magenta Team. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2015, The TensorFlow Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/MarkovMusic-master/README.md b/MarkovMusic-master/README.md new file mode 100644 index 0000000..3fac956 --- /dev/null +++ b/MarkovMusic-master/README.md @@ -0,0 +1,15 @@ +# Markov Music + +A markov chain based VERY simplistic procedural music generator. +**Click link to watch [demo video](https://youtu.be/qjFFPDLDLEo)!** + +## Improvements + +- Python 3 compatible +- Auto generate adjacency list (Markov matrix) + +## Dependencies +- Python +- numpy +- pyknon https://github.com/kroger/pyknon +- pysynth https://github.com/mdoege/PySynth diff --git a/MarkovMusic-master/main.ipynb b/MarkovMusic-master/main.ipynb new file mode 100644 index 0000000..b0fe566 --- /dev/null +++ b/MarkovMusic-master/main.ipynb @@ -0,0 +1,259 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "##import pysynth as ps\n", + "from pyknon.genmidi import Midi\n", + "from pyknon.music import NoteSeq, Note, Rest\n", + "from src.MarkovMusic import MusicMatrix\n", + "from pprint import pprint" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "def make_midi(midi_path, notes, bpm=120):\n", + " note_names = 'c c# d d# e f f# g g# a a# b'.split()\n", + "\n", + " result = NoteSeq()\n", + " for n in notes:\n", + " duration = 1. / n[1]\n", + "\n", + " if n[0].lower() == 'r':\n", + " result.append(Rest(dur=duration))\n", + " else:\n", + " pitch = n[0][:-1]\n", + " octave = int(n[0][-1]) + 1\n", + " pitch_number = note_names.index(pitch.lower())\n", + " \n", + " result.append(Note(pitch_number, octave=octave, dur=duration))\n", + " \n", + " midi = Midi(number_tracks=1, tempo=bpm)\n", + " midi.seq_notes(result, track=0)\n", + " midi.write(midi_path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Row Row Row Your Boat" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "song = [['c4', 4], ['c4', 4], ['c4', 4], ['d4', 8], ['e4', 4], ['e4', 4], ['d4', 8], ['e4', 4], ['f4', 8], ['g4', 2], ['c4', 8], ['c4', 8], ['c4', 8], ['g4', 8], ['g4', 8], ['g4', 8], ['e4', 8], ['e4', 8], ['e4', 8], ['c4', 8], ['c4', 8], ['c4', 8], ['g4', 4], ['f4', 8], ['e4', 4], ['d4', 8], ['c4', 2]]\n", + "\n", + "#ps.make_wav(song, fn='examples/test.wav')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "matrix = MusicMatrix(song)\n", + "\n", + "start_note = ['c4', 4]\n", + "\n", + "random_song = []\n", + "for i in range(0, 100):\n", + " start_note = matrix.next_note(start_note)\n", + " random_song.append(start_note)\n", + "\n", + "# ps.make_wav(random_song, fn='examples/random.wav')\n", + "make_midi(midi_path='midi/random_rowboat.mid', notes=random_song)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Undertail" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "song = [('g#3', 16.0), ('e4', 16.0), ('d#4', 16.0), ('d4', 16.0), ('d#4', 16.0), ('r', 16.0), ('c#4', 16.0), ('b3', 16.0), ('a#3', 16.0), ('r', 16.0), ('g#3', 16.0), ('g3', 16.0), ('g#3', 16.0), ('r', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('d3', 16.0), ('d#3', 16.0), ('g3', 16.0), ('b3', 16.0), ('a#3', 16.0), ('g#3', 16.0), ('r', 16.0), ('g#3', 16.0), ('a#3', 16.0), ('b3', 16.0), ('r', 16.0), ('a#3', 16.0), ('b3', 16.0), ('c#4', 16.0), ('r', 16.0), ('b3', 16.0), ('a#3', 16.0), ('g3', 16.0), ('r', 16.0), ('g3', 16.0), ('a#3', 16.0), ('b3', 16.0), ('r', 16.0), ('a#3', 16.0), ('g#3', 16.0), ('d#3', 16.0), ('r', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('d3', 16.0), ('d#3', 16.0), ('g3', 16.0), ('b3', 16.0), ('a#3', 16.0), ('g#3', 16.0), ('r', 16.0), ('g#3', 16.0), ('g3', 16.0), ('g#3', 16.0), ('r', 16.0), ('g#4', 16.0)]\n", + "\n", + "# ps.make_wav(song, fn='examples/undertail.wav')\n", + "\n", + "matrix = MusicMatrix(song)\n", + "\n", + "start_note = ['d4', 16]\n", + "\n", + "random_song = []\n", + "for i in range(0, 100):\n", + " start_note = matrix.next_note(start_note)\n", + " random_song.append(start_note)\n", + "\n", + "# ps.make_wav(random_song, fn='examples/random_undertail.wav')\n", + "\n", + "make_midi(midi_path='midi/random_undertail.mid', notes=random_song)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Debussy - Reverie" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "song = [('g5', 2.0), ('d5', 1.3333333333333333), ('e5', 8.0), ('f5', 8.0), ('g5', 4.0), ('e5', 8.0), ('d5', 8.0), ('e5', 5.333333333333333), ('c5', 5.314878892780648), ('e5', 5.314878892710022), ('d5', 1.0), ('a#4', 4.0), ('d5', 4.0), ('e5', 4.0), ('f5', 4.0), ('c5', 1.0), ('g4', 2.0), ('a4', 0.4999999999999998), ('a5', 2.0), ('e5', 1.3333333333333333), ('c5', 8.0), ('e5', 8.0), ('d5', 4.0), ('a#4', 8.0), ('g4', 8.0), ('a5', 2.0), ('e5', 1.3333333333333333), ('c5', 8.0), ('e5', 8.0), ('d5', 4.0), ('a#4', 8.0), ('g4', 8.0), ('g5', 2.0), ('d5', 1.3333333333333333), ('a#4', 8.0), ('d5', 8.0), ('c5', 4.0), ('a4', 8.0), ('g4', 8.0), ('a4', 4.0), ('e4', 8.0), ('a4', 8.0), ('f4', 4.0), ('d4', 8.0), ('f4', 8.0), ('d4', 2.0), ('c4', 2.000000000000007), ('c6', 2.0), ('g5', 1.3333333333333333), ('a5', 8.0), ('a#5', 8.0), ('c6', 4.0), ('a5', 8.0), ('g5', 8.0), ('a5', 5.333333333333333), ('f5', 5.314878892498194), ('a5', 5.314878892498194), ('g5', 1.0), ('d#5', 4.0), ('g5', 4.0), ('a5', 4.0), ('a#5', 4.0), ('f5', 1.0), ('a5', 4.0), ('a#5', 4.0), ('c6', 4.0), ('d6', 4.0), ('a5', 1.0), ('a#5', 4.0), ('d6', 4.0), ('f6', 2.0), ('c#6', 2.0000000003000054), ('r', 8.084210527894808), ('d5', 8.0), ('e5', 8.0), ('r', 4.0), ('f5', 8.0), ('a5', 8.0), ('f6', 2.0), ('c#6', 2.0), ('r', 4.0), ('d5', 8.0), ('e5', 8.0), ('r', 4.0), ('f5', 8.0), ('a5', 8.0), ('f5', 4.0), ('d4', 8.0), ('e4', 8.0), ('f5', 0.3333333333333333), ('f4', 8.0), ('a4', 8.0), ('f4', 2.0), ('f4', 1.0), ('d4', 4.0), ('c4', 4.0), ('d4', 1.0), ('c5', 4.0), ('a#4', 8.0), ('a4', 8.0), ('g4', 1.3333333333333333), ('a4', 8.0), ('a#4', 8.0), ('c5', 4.0), ('c5', 8.0), ('d#5', 8.0), ('d5', 0.5), ('c5', 4.0), ('a#4', 8.0), ('a4', 8.0), ('g4', 1.3333333333333333), ('a4', 8.0), ('a#4', 8.0), ('c5', 8.0), ('d#5', 8.0), ('e5', 0.6666666666666666), ('d#5', 4.0), ('e5', 4.0), ('g5', 4.0), ('f5', 8.0), ('e5', 8.0), ('d5', 2.0), ('d5', 2.0), ('e5', 4.0), ('c5', 0.08888888888888886), ('f5', 4.0), ('e5', 8.0), ('d5', 8.0), ('c5', 1.0), ('d5', 4.0), ('f5', 0.5), ('e5', 4.0), ('d5', 8.0), ('c5', 8.0), ('a#4', 2.0), ('a#5', 2.0), ('a5', 4.0), ('g5', 4.0), ('e5', 0.4444444444444444), ('f5', 0.6666666666666666), ('f4', 4.0), ('f5', 0.23529411764705882), ('e4', 4.0), ('f4', 16.0), ('a4', 16.0), ('f4', 16.0), ('e4', 4.0), ('d4', 4.0), ('c4', 2.0), ('e4', 4.0), ('c#4', 4.0), ('c#4', 4.0), ('e4', 4.0), ('f#4', 4.0), ('g#4', 4.0), ('e4', 2.0), ('f#5', 4.0), ('g#5', 4.0), ('e5', 4.0), ('c#6', 4.0), ('f#5', 4.0), ('g#5', 16.0), ('f#5', 16.0), ('g#5', 16.0), ('e5', 4.0), ('b4', 4.0), ('g#4', 4.0), ('b4', 4.0), ('g#4', 4.0), ('e4', 4.0), ('f#4', 2.0), ('c#5', 2.0), ('f#5', 4.0), ('g#5', 4.0), ('e5', 4.0), ('c#6', 4.0), ('f#5', 4.0), ('g#5', 16.0), ('f#5', 16.0), ('g#5', 16.0), ('e5', 4.0), ('b5', 4.0), ('c#6', 4.0), ('e6', 4.0), ('d#6', 4.0), ('b5', 4.0), ('c#6', 4.0), ('e6', 4.0), ('f#6', 4.0), ('b5', 4.000000000000114), ('c#6', 4.0), ('e6', 4.0), ('d#6', 4.0), ('b5', 4.0), ('c#6', 4.0), ('e6', 4.0), ('f#6', 4.0), ('b5', 4.0), ('g6', 1.3333333333333333), ('a5', 4.0), ('g5', 2.6666666666666665), ('a4', 8.0), ('g4', 2.6666666666666665), ('a4', 8.0), ('d4', 4.0), ('e4', 4.0), ('c4', 4.0), ('a4', 4.0), ('d4', 4.0), ('e4', 16.0), ('d4', 16.0), ('e4', 16.0), ('c4', 2.0), ('d5', 4.0), ('e5', 16.0), ('d5', 16.0), ('e5', 16.0), ('c5', 2.0), ('g5', 2.0), ('d5', 1.3333333333333333), ('e5', 8.0), ('f5', 8.0), ('g5', 4.0), ('e5', 8.0), ('d5', 8.0), ('e5', 5.333333333333333), ('c5', 5.31487889037946), ('e5', 5.31487889037946), ('d5', 1.0), ('a#4', 4.0), ('d5', 4.0), ('e5', 4.0), ('f5', 4.0), ('c5', 1.0), ('g4', 2.0), ('a4', 0.5), ('a5', 2.0), ('e5', 1.3333333333333333), ('c5', 8.0), ('e5', 8.0), ('d5', 4.0), ('a#4', 8.0), ('g4', 8.0), ('a5', 2.0), ('e5', 1.3333333333333333), ('c5', 8.0), ('e5', 8.0), ('d5', 4.0), ('a#4', 8.0), ('g4', 8.0), ('g5', 2.0), ('d5', 1.3333333333333333), ('a#4', 8.0), ('d5', 8.0), ('c5', 4.0), ('a4', 8.0), ('f4', 8.0), ('g5', 2.0), ('d5', 1.3333333333333333), ('a#4', 8.0), ('d5', 8.0), ('c5', 4.0), ('d5', 4.0), ('a#4', 4.0), ('e4', 0.02580385041830461), ('a4', 4.0), ('a4', 2.0), ('a#4', 4.0), ('a4', 4.0), ('a4', 2.0), ('a#4', 4.0), ('a#4', 0.6666666666666666), ('a4', 4.0), ('a#4', 16.0), ('d5', 16.0), ('a#4', 16.0), ('a4', 4.0), ('g4', 4.0), ('f4', 2.0), ('a#5', 4.0), ('a4', 0.49983729252717796), ('a5', 4.0), ('a5', 2.0), ('a#5', 4.0), ('a#5', 2.0), ('a5', 2.0), ('a#5', 4.0), ('a5', 4.0), ('a#5', 16.0), ('d6', 16.0), ('a#5', 16.0), ('a5', 2.0), ('g5', 2.0), ('a5', 0.36355029584697357), ('a6', 1.0)]\n", + "\n", + "# ps.make_wav(song[:100], fn='examples/Debussy_Reverie.wav')\n", + "\n", + "matrix = MusicMatrix(song)\n", + "\n", + "start_note = ['g5', 2]\n", + "\n", + "random_song = []\n", + "for i in range(0, 100):\n", + " start_note = matrix.next_note(start_note)\n", + " random_song.append(start_note)\n", + "\n", + "# ps.make_wav(random_song, fn='examples/random_debussy.wav')\n", + "make_midi(midi_path='midi/random_debussy.mid', notes=random_song)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Synth Solo" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "song = [('d3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('d4', 16.0), ('r', 16.0), ('b3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('r', 5.333333333333333), ('f#3', 16.0), ('g3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 8.0), ('f#3', 16.0), ('r', 16.0), ('f#3', 16.0), ('g3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('b3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('d3', 16.0), ('r', 16.0), ('f#3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('e3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('d4', 16.0), ('r', 16.0), ('f#3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('f#3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('f#3', 16.0), ('r', 16.0), ('a3', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('f#4', 16.0), ('r', 16.0), ('g4', 16.0), ('r', 16.0), ('g3', 16.0), ('r', 16.0), ('b3', 16.0), ('r', 16.0), ('d4', 16.0)]\n", + "\n", + "# ps.make_wav(song[:100], fn='examples/synth_solo.wav')\n", + "\n", + "matrix = MusicMatrix(song)\n", + "\n", + "start_note = ['d4', 16]\n", + "\n", + "random_song = []\n", + "for i in range(0, 100):\n", + " start_note = matrix.next_note(start_note)\n", + " random_song.append(start_note)\n", + "\n", + "# ps.make_wav(random_song, fn='examples/random_synth_solo.wav')\n", + "make_midi(midi_path='midi/random_synth_solo.mid', notes=random_song)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Mix Songs" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 1],\n", + " [4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],\n", + " [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],\n", + " [0, 0, 0, 13, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 4, 0],\n", + " [0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 0, 2, 0, 1],\n", + " [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],\n", + " [0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 2, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 2, 0, 1, 0, 4, 0, 6, 2, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0],\n", + " [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 4],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1],\n", + " [0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 4, 0],\n", + " [2, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0]]\n", + "[[62, 0, 0, 0], [1, 0, 1, 2], [0, 0, 6, 10], [0, 4, 8, 22]]\n" + ] + } + ], + "source": [ + "song1 = [['c4', 4], ['c4', 4], ['c4', 4], ['d4', 8], ['e4', 4], ['e4', 4], ['d4', 8], ['e4', 4], ['f4', 8], ['g4', 2], ['c4', 8], ['c4', 8], ['c4', 8], ['g4', 8], ['g4', 8], ['g4', 8], ['e4', 8], ['e4', 8], ['e4', 8], ['c4', 8], ['c4', 8], ['c4', 8], ['g4', 4], ['f4', 8], ['e4', 4], ['d4', 8], ['c4', 2]]\n", + "\n", + "song2 = [('g#3', 16.0), ('e4', 16.0), ('d#4', 16.0), ('d4', 16.0), ('d#4', 16.0), ('r', 16.0), ('c#4', 16.0), ('b3', 16.0), ('a#3', 16.0), ('r', 16.0), ('g#3', 16.0), ('g3', 16.0), ('g#3', 16.0), ('r', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('d3', 16.0), ('d#3', 16.0), ('g3', 16.0), ('b3', 16.0), ('a#3', 16.0), ('g#3', 16.0), ('r', 16.0), ('g#3', 16.0), ('a#3', 16.0), ('b3', 16.0), ('r', 16.0), ('a#3', 16.0), ('b3', 16.0), ('c#4', 16.0), ('r', 16.0), ('b3', 16.0), ('a#3', 16.0), ('g3', 16.0), ('r', 16.0), ('g3', 16.0), ('a#3', 16.0), ('b3', 16.0), ('r', 16.0), ('a#3', 16.0), ('g#3', 16.0), ('d#3', 16.0), ('r', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('e3', 16.0), ('d#3', 16.0), ('d3', 16.0), ('d#3', 16.0), ('g3', 16.0), ('b3', 16.0), ('a#3', 16.0), ('g#3', 16.0), ('r', 16.0), ('g#3', 16.0), ('g3', 16.0), ('g#3', 16.0), ('r', 16.0), ('g#4', 16.0)]\n", + "\n", + "song = list(song1 * 2) + list(song2)\n", + "\n", + "matrix = MusicMatrix(song)\n", + "\n", + "pprint(matrix._markov._matrix)\n", + "pprint(matrix._timings._matrix)\n", + "\n", + "start_note = ['e3', 8]\n", + "\n", + "random_song = []\n", + "for i in range(0, 500):\n", + " start_note = matrix.next_note(start_note)\n", + " random_song.append(start_note)\n", + "\n", + "# ps.make_wav(random_song, fn='examples/random_mix.wav')\n", + "make_midi(midi_path='midi/random_mix.mid', notes=random_song)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.5.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/MarkovMusic-master/midi/Debussy_Reverie_945834_1.mid b/MarkovMusic-master/midi/Debussy_Reverie_945834_1.mid new file mode 100644 index 0000000..d32de64 Binary files /dev/null and b/MarkovMusic-master/midi/Debussy_Reverie_945834_1.mid differ diff --git a/MarkovMusic-master/midi/random_debussy.mid b/MarkovMusic-master/midi/random_debussy.mid new file mode 100644 index 0000000..22a4eae Binary files /dev/null and b/MarkovMusic-master/midi/random_debussy.mid differ diff --git a/MarkovMusic-master/midi/random_mix.mid b/MarkovMusic-master/midi/random_mix.mid new file mode 100644 index 0000000..215b5ae Binary files /dev/null and b/MarkovMusic-master/midi/random_mix.mid differ diff --git a/MarkovMusic-master/midi/random_mix_good.mid b/MarkovMusic-master/midi/random_mix_good.mid new file mode 100644 index 0000000..5bd758b Binary files /dev/null and b/MarkovMusic-master/midi/random_mix_good.mid differ diff --git a/MarkovMusic-master/midi/random_rowboat.mid b/MarkovMusic-master/midi/random_rowboat.mid new file mode 100644 index 0000000..80377d4 Binary files /dev/null and b/MarkovMusic-master/midi/random_rowboat.mid differ diff --git a/MarkovMusic-master/midi/random_synth_solo.mid b/MarkovMusic-master/midi/random_synth_solo.mid new file mode 100644 index 0000000..8946a60 Binary files /dev/null and b/MarkovMusic-master/midi/random_synth_solo.mid differ diff --git a/MarkovMusic-master/midi/random_undertail.mid b/MarkovMusic-master/midi/random_undertail.mid new file mode 100644 index 0000000..a4e410f Binary files /dev/null and b/MarkovMusic-master/midi/random_undertail.mid differ diff --git a/MarkovMusic-master/midi/synth_solo_73708.mid b/MarkovMusic-master/midi/synth_solo_73708.mid new file mode 100644 index 0000000..b04655c Binary files /dev/null and b/MarkovMusic-master/midi/synth_solo_73708.mid differ diff --git a/MarkovMusic-master/midi/undertail_155475.mid b/MarkovMusic-master/midi/undertail_155475.mid new file mode 100644 index 0000000..6b17843 Binary files /dev/null and b/MarkovMusic-master/midi/undertail_155475.mid differ diff --git a/MarkovMusic-master/readmidi.py b/MarkovMusic-master/readmidi.py new file mode 100644 index 0000000..988107a --- /dev/null +++ b/MarkovMusic-master/readmidi.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python + +# Read MIDI file track and synthesize with PySynth A + +# Usage: + +# python readmidi.py file.mid [tracknum] [file.wav] [--syn_b/--syn_c/--syn_d/--syn_e/--syn_p/--syn_s/--syn_samp] + +# Based on code from https://github.com/osakared/midifile.py +# which appears to be based on +# https://github.com/gasman/jasmid/blob/master/midifile.js + +# Original license: + +""" +Copyright (c) 2014, Thomas J. Webb +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +import struct + +class Note(object): + "Represents a single MIDI note" + + note_names = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'] + + def __init__(self, channel, pitch, velocity, start, duration = 0): + self.channel = channel + self.pitch = pitch + self.velocity = velocity + self.start = start + self.duration = duration + + def __str__(self): + s = Note.note_names[(self.pitch - 9) % 12] + s += str(self.pitch // 12 - 1) + s += " " + str(self.velocity) + s += " " + str(self.start) + " " + str(self.start + self.duration) + " " + return s + + def get_end(self): + return self.start + self.duration + +class MidiFile(object): + "Represents the notes in a MIDI file" + + def read_byte(self, file): + return struct.unpack('B', file.read(1))[0] + + def read_variable_length(self, file, counter): + counter -= 1 + num = self.read_byte(file) + + if num & 0x80: + num = num & 0x7F + while True: + counter -= 1 + c = self.read_byte(file) + num = (num << 7) + (c & 0x7F) + if not (c & 0x80): + break + + return (num, counter) + + def __init__(self, file_name): + self.tempo = 120 + try: + file = open(file_name, 'rb') + if file.read(4) != b'MThd': raise Exception('Not a MIDI file') + self.file_name = file_name + size = struct.unpack('>i', file.read(4))[0] + if size != 6: raise Exception('Unusual MIDI file with non-6 sized header') + self.format = struct.unpack('>h', file.read(2))[0] + self.track_count = struct.unpack('>h', file.read(2))[0] + self.time_division = struct.unpack('>h', file.read(2))[0] + + # Now to fill out the arrays with the notes + self.tracks = [] + for i in range(0, self.track_count): + self.tracks.append([]) + + for nn, track in enumerate(self.tracks): + abs_time = 0. + + if file.read(4) != b'MTrk': raise Exception('Not a valid track') + size = struct.unpack('>i', file.read(4))[0] + + # To keep track of running status + last_flag = None + while size > 0: + delta, size = self.read_variable_length(file, size) + delta /= float(self.time_division) + abs_time += delta + + size -= 1 + flag = self.read_byte(file) + # Sysex messages + if flag == 0xF0 or flag == 0xF7: + # print "Sysex" + while True: + size -= 1 + if self.read_byte(file) == 0xF7: break + # Meta messages + elif flag == 0xFF: + size -= 1 + type = self.read_byte(file) + if type == 0x2F: # end of track event + self.read_byte(file) + size -= 1 + break + print("Meta: " + str(type)) + length, size = self.read_variable_length(file, size) + message = file.read(length) + # if type not in [0x0, 0x7, 0x20, 0x2F, 0x51, 0x54, 0x58, 0x59, 0x7F]: + print(length, message) + if type == 0x51: # qpm/bpm + # http://www.recordingblogs.com/sa/Wiki?topic=MIDI+Set+Tempo+meta+message + self.tempo = 6e7 / struct.unpack('>i', b'\x00' + message)[0] + print("tempo =", self.tempo, "bpm") + # MIDI messages + else: + if flag & 0x80: + type_and_channel = flag + size -= 1 + param1 = self.read_byte(file) + last_flag = flag + else: + type_and_channel = last_flag + param1 = flag + type = ((type_and_channel & 0xF0) >> 4) + channel = type_and_channel & 0xF + if type == 0xC: # detect MIDI program change + print("program change, channel", channel, "=", param1) + continue + size -= 1 + param2 = self.read_byte(file) + + # detect MIDI ons and MIDI offs + if type == 0x9: + track.append(Note(channel, param1, param2, abs_time)) + elif type == 0x8: + for note in reversed(track): + if note.channel == channel and note.pitch == param1: + note.duration = abs_time - note.start + break + + except Exception as e: + print("Cannot parse MIDI file: " + str(e)) + finally: + file.close() + + def __str__(self): + s = "" + for i, track in enumerate(self.tracks): + s += "Track " + str(i+1) + "\n" + for note in track: + s += str(note) + "\n" + return s + +def getdur(a, b): + "Calculate note length for PySynth" + return 4 / (b - a) + +if __name__ == "__main__": + import sys + m = MidiFile(sys.argv[1]) + if len(sys.argv) > 2: + tracknum = int(sys.argv[2]) + else: + tracknum = 1 + if len(sys.argv) > 3: + filename = sys.argv[3] + else: + filename = "midi.wav" + print() + print("Track first notes") + for t, n in enumerate(m.tracks): + if len(n) > 0: + print(t, n[0], len(n)) + song = [] + notes = {} + + def getnote(q): + for x in q.keys(): + if q[x] >= 0: + return x + return None + + def gettotal(): + t = 0 + for x, y in song: + t += 4 / y + return t + + for n in m.tracks[tracknum]: + print(n) + nn = str(n).split() + start, stop = float(nn[2]), float(nn[3]) + + if start != stop: # note ends because of NOTE OFF event + if start - gettotal() > 0: + song.append(('r', getdur(gettotal(), start))) + print("r1") + song.append((nn[0].lower(), getdur(start, stop))) + elif float(nn[1]) == 0 and notes.get(nn[0].lower(), -1) >= 0: # note ends because of NOTE ON with velocity = 0 + if notes[nn[0].lower()] - gettotal() > 0: + song.append(('r', getdur(gettotal(), notes[nn[0].lower()]))) + print("r2") + song.append((nn[0].lower(), getdur(notes[nn[0].lower()], start))) + notes[nn[0].lower()] = -1 + elif float(nn[1]) > 0 and notes.get(nn[0].lower(), -1) == -1: # note ends because of new note + old = getnote(notes) + if old != None: + if notes[old] != start: + song.append((old, getdur(notes[old], start))) + notes[old] = -1 + elif start - gettotal() > 0: + song.append(('r', getdur(gettotal(), start))) + print("r3") + notes[nn[0].lower()] = start + print() + print("Song") + print(song) + # if "--syn_b" in sys.argv: + # import pysynth_b as pysynth + # elif "--syn_s" in sys.argv: + # import pysynth_s as pysynth + # elif "--syn_e" in sys.argv: + # import pysynth_e as pysynth + # elif "--syn_c" in sys.argv: + # import pysynth_c as pysynth + # elif "--syn_d" in sys.argv: + # import pysynth_d as pysynth + # elif "--syn_p" in sys.argv: + # import pysynth_p as pysynth + # elif "--syn_samp" in sys.argv: + # import pysynth_samp as pysynth + # else: + # import pysynth + # pysynth.make_wav(song, fn = filename, bpm = m.tempo) + diff --git a/MarkovMusic-master/src/MarkovBuilder.py b/MarkovMusic-master/src/MarkovBuilder.py new file mode 100644 index 0000000..f3d6ed2 --- /dev/null +++ b/MarkovMusic-master/src/MarkovBuilder.py @@ -0,0 +1,49 @@ +''' +Created on May 14, 2009 + +@author: darkxanthos +https://www.autoitscript.com/forum/topic/150415-generate-music-algorithmically/ + +''' +import random + +class MarkovBuilder: + def __init__(self, value_list): + self._values_added = 0 + self._reverse_value_lookup = value_list + self._value_lookup = {} + for i in range(0, len(value_list)): + self._value_lookup[value_list[i]] = i + #Initialize our adjacency matrix with the initial + #probabilities for note transitions. + self._matrix=[[0 for x in range(0,len(value_list))] for i in range(0,len(value_list))] + + def add(self, from_value, to_value): + """Add a path from a note to another note. Re-adding a path between notes will increase the associated weight.""" + value = self._value_lookup + self._matrix[value[from_value]][value[to_value]] += 1 + self._values_added = self._values_added + 1 + + def next_value(self, from_value): + value = self._value_lookup[from_value] + value_counts = self._matrix[value] + value_index = self.randomly_choose(value_counts) + if(value_index < 0): + raise RuntimeError("Non-existent value selected.") + else: + return self._reverse_value_lookup[value_index] + + def randomly_choose(self, choice_counts): + """Given an array of counts, returns the index that was randomly chosen""" + counted_sum = 0 + count_sum = sum(choice_counts) + + if count_sum == 0: + return random.randint(0, len(choice_counts)-1) + else: + selected_count = random.randrange(1, count_sum + 1) + for index in range(0, len(choice_counts)): + counted_sum += choice_counts[index] + if(counted_sum >= selected_count): + return index + raise RuntimeError("Impossible value selection made. BAD!") \ No newline at end of file diff --git a/MarkovMusic-master/src/MarkovMusic.py b/MarkovMusic-master/src/MarkovMusic.py new file mode 100644 index 0000000..82aa370 --- /dev/null +++ b/MarkovMusic-master/src/MarkovMusic.py @@ -0,0 +1,109 @@ +''' +Created on May 12, 2009 + +@author: Justin Bozonier +''' +#import pysynth +import numpy as np +from .MarkovBuilder import MarkovBuilder + +class MusicMatrix: + def __init__(self, song=None): + self._previous_note = None + + if song is not None: + notes = np.array(song, dtype=str)[:, 0] + durations = np.array(song, dtype=str)[:, 1] + + for i, d in enumerate(durations): + durations[i] = self.float2str(durations[i]) + + self._markov = MarkovBuilder(np.unique(notes).tolist()) + self._timings = MarkovBuilder(np.unique(durations).tolist()) + + for note in song: + self.add(note) + else: + self._markov = MarkovBuilder(["a", "a#", "b", "c", "c#", "d", "d#", "e", "f", "f#", "g", "g#"]) + self._timings = MarkovBuilder([1, 2, 4, 8, 16]) + + # print(self._markov._value_lookup) + # print(self._timings._value_lookup) + + def float2str(self, d): + if float(d) >= 1: + return '%d' % int(float(d)) + else: + return '%.2f' % float(d) + + def add(self, to_note): + """Add a path from a note to another note. Re-adding a path between notes will increase the associated weight.""" + + to_note = list(to_note) + to_note[1] = self.float2str(to_note[1]) + + if(self._previous_note is None): + self._previous_note = to_note + return + from_note = self._previous_note + self._markov.add(from_note[0], to_note[0]) + self._timings.add(from_note[1], to_note[1]) + self._previous_note = to_note + + def next_note(self, from_note): + from_note = list(from_note) + from_note[1] = self.float2str(from_note[1]) + + return [self._markov.next_value(from_note[0]), float(self._timings.next_value(from_note[1]))] + +if __name__ == "__main__": + # Playing it comes next :) + #test = [['c',4], ['e',4], ['g',4], ['c5',1]] + #pysynth.make_wav(test, fn = "test.wav") + + musicLearner = MusicMatrix() + + # Input the melody of Row, Row, Row Your Boat + # The MusicMatrix will automatically use this to + # model our own song after it. + musicLearner.add(["c", 4]) + musicLearner.add(["c", 4]) + musicLearner.add(["c", 4]) + musicLearner.add(["d", 8]) + musicLearner.add(["e", 4]) + musicLearner.add(["e", 4]) + musicLearner.add(["d", 8]) + musicLearner.add(["e", 4]) + musicLearner.add(["f", 8]) + musicLearner.add(["g", 2]) + + musicLearner.add(["c", 8]) + musicLearner.add(["c", 8]) + musicLearner.add(["c", 8]) + + musicLearner.add(["g", 8]) + musicLearner.add(["g", 8]) + musicLearner.add(["g", 8]) + + musicLearner.add(["e", 8]) + musicLearner.add(["e", 8]) + musicLearner.add(["e", 8]) + + musicLearner.add(["c", 8]) + musicLearner.add(["c", 8]) + musicLearner.add(["c", 8]) + + musicLearner.add(["g", 4]) + musicLearner.add(["f", 8]) + musicLearner.add(["e", 4]) + musicLearner.add(["d", 8]) + musicLearner.add(["c", 2]) + + random_score = [] + current_note = ["c", 4] + for i in range(0,100): + print(current_note[0] + ", " + str(current_note[1])) + current_note = musicLearner.next_note(current_note) + random_score.append(current_note) + + pysynth.make_wav(random_score, fn = "first_score.wav") \ No newline at end of file diff --git a/MarkovMusic-master/src/__pycache__/MarkovBuilder.cpython-35.pyc b/MarkovMusic-master/src/__pycache__/MarkovBuilder.cpython-35.pyc new file mode 100644 index 0000000..b3927b4 Binary files /dev/null and b/MarkovMusic-master/src/__pycache__/MarkovBuilder.cpython-35.pyc differ diff --git a/MarkovMusic-master/src/__pycache__/MarkovMusic.cpython-35.pyc b/MarkovMusic-master/src/__pycache__/MarkovMusic.cpython-35.pyc new file mode 100644 index 0000000..1950653 Binary files /dev/null and b/MarkovMusic-master/src/__pycache__/MarkovMusic.cpython-35.pyc differ diff --git a/README.md b/README.md index 79b391b..0821430 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,135 @@ -## AIrang 프로젝트
-![image](https://user-images.githubusercontent.com/52441697/100899294-03375a80-3505-11eb-898a-5dc2a67c9ecd.png) - -#### :pencil2: 프로젝트 소개 -모두를 위한 동요 창작 AI, AIRANG -인공지능을 통해 보다 많은 동요를 누구나 손쉽고 빠르게 작사 작곡 -#### :tv: AIrang 시연영상 링크 : https://www.youtube.com/watch?v=_yRwkHZCLmI -#### :space_invader: 팀원 기술블로그 주소 -* 김선우 - - 작곡 알고리즘, 프론트엔드 - - https://sunwoo-725.tistory.com/
-* 김채윤 - - 작곡 알고리즘, 백엔드 - - https://yunyuno3o.tistory.com/
-* 민은영 - - 작사 알고리즘, 프론트엔드 - - https://blog.naver.com/bear0369
-* 정혜민 - - 작사 알고리즘, 백엔드 - - https://codeinleonis.tistory.com/
-#### :book: 참고 -* 음성 데이터셋 -https://github.com/danbom/emotiontts_open_db -* 자연어 처리 -https://github.com/danbom/soynlp -* 키워드 추출을 위한 KRWordRank -https://github.com/lovit/KR-WordRank -* 마르코프 체인 작곡 -https://github.com/danbom/MarkovMusic -* 마젠타 작곡(RNN) -https://github.com/magenta/magenta -* 작사 알고리즘 참고 -https://github.com/danbom/hiphop - -### 2020 졸업프로젝트 진행 과정
-#### 📅 10.16 프로토타입 만들기 시작
-* Adobe XD 활용해 구현
- - 1018
https://xd.adobe.com/view/c1ddf3a1-8039-43de-966e-4c6cf48756b6-948e/ -#### 📅 10.22 작곡소프트웨어 발표
-* 작곡소프트웨어.pdf -#### 📅 10.23 1차 멘토링 및 사업계획서 작성, 프로토타입 장면 연결 시작
-#### 📅 10.24 프로토타입 1차 완성
-* Adobe XD 활용해 구현
- - 1024
https://xd.adobe.com/view/6d4ea879-0b66-4ed4-bbe9-1455d4917689-381d/?fullscreen&hints=off -#### 📅 10.30 사업계획서 제출 및 중간발표 자료(+ 창업경진대회 본선진출)
-#### 📅 11.03 중간발표
-* -#### 📅 11.06 창업 경진 대회 발표
-* 장려상 수상 -#### 📅 11.13 추가 데이터셋, 알고리즘 회의
-* 작사 데이터셋(은영,혜민) : https://docs.google.com/spreadsheets/d/1ot7RgS7kaz1GI-OhT3EXO5I805EZs1rsqfFV1MLsa60/edit?usp=sharing -* 작곡 데이터셋(선우,채윤) : https://docs.google.com/document/d/1D_6VYXj-haVLZm-3O4KSS6XG96-zDQht/edit -* 알고리즘 : https://docs.google.com/spreadsheets/d/1LDNTvfOhnJw_W6Rfeia6OdszMlUh3J3pT3UqdmKehQ0/edit?usp=sharing -#### 📅 11.20 작사, 작곡 회의
-* https://docs.google.com/spreadsheets/d/1LDNTvfOhnJw_W6Rfeia6OdszMlUh3J3pT3UqdmKehQ0/edit#gid=1287511031 -#### 📅 11.27 2차 멘토링
-#### 📅 12.03 AIrang 깃허브 리모델링
-#### 📅 12.08 AIrang 기말발표
+ + + +[![Build Status](https://github.com/magenta/magenta/workflows/build/badge.svg)](https://github.com/magenta/magenta/actions?query=workflow%3Abuild) + [![PyPI version](https://badge.fury.io/py/magenta.svg)](https://badge.fury.io/py/magenta) + +**Magenta** is a research project exploring the role of machine learning +in the process of creating art and music. Primarily this +involves developing new deep learning and reinforcement learning +algorithms for generating songs, images, drawings, and other materials. But it's also +an exploration in building smart tools and interfaces that allow +artists and musicians to extend (not replace!) their processes using +these models. Magenta was started by some researchers and engineers +from the [Google Brain team](https://research.google.com/teams/brain/), +but many others have contributed significantly to the project. We use +[TensorFlow](https://www.tensorflow.org) and release our models and +tools in open source on this GitHub. If you’d like to learn more +about Magenta, check out our [blog](https://magenta.tensorflow.org), +where we post technical details. You can also join our [discussion +group](https://groups.google.com/a/tensorflow.org/forum/#!forum/magenta-discuss). + +This is the home for our Python TensorFlow library. To use our models in the browser with [TensorFlow.js](https://js.tensorflow.org/), head to the [Magenta.js](https://github.com/tensorflow/magenta-js) repository. + +## Getting Started + +Take a look at our [colab notebooks](https://magenta.tensorflow.org/demos/colab/) for various models, including one on [getting started](https://colab.research.google.com/notebooks/magenta/hello_magenta/hello_magenta.ipynb). +[Magenta.js](https://github.com/tensorflow/magenta-js) is a also a good resource for models and [demos](https://magenta.tensorflow.org/demos/web/) that run in the browser. +This and more, including [blog posts](https://magenta.tensorflow.org/blog) and [Ableton Live plugins](https://magenta.tensorflow.org/demos/native/), can be found at [https://magenta.tensorflow.org](https://magenta.tensorflow.org). + +## Magenta Repo + +* [Installation](#installation) +* [Using Magenta](#using-magenta) +* [Development Environment (Advanced)](#development-environment) + +## Installation + +Magenta maintains a [pip package](https://pypi.python.org/pypi/magenta) for easy +installation. We recommend using Anaconda to install it, but it can work in any +standard Python environment. We support Python 3 (>= 3.5). These instructions +will assume you are using Anaconda. + +### Automated Install (w/ Anaconda) + +If you are running Mac OS X or Ubuntu, you can try using our automated +installation script. Just paste the following command into your terminal. + +```bash +curl https://raw.githubusercontent.com/tensorflow/magenta/master/magenta/tools/magenta-install.sh > /tmp/magenta-install.sh +bash /tmp/magenta-install.sh +``` + +After the script completes, open a new terminal window so the environment +variable changes take effect. + +The Magenta libraries are now available for use within Python programs and +Jupyter notebooks, and the Magenta scripts are installed in your path! + +Note that you will need to run `source activate magenta` to use Magenta every +time you open a new terminal window. + +### Manual Install (w/o Anaconda) + +If the automated script fails for any reason, or you'd prefer to install by +hand, do the following steps. + +Install the Magenta pip package: + +```bash +pip install magenta +``` + +**NOTE**: In order to install the `rtmidi` package that we depend on, you may need to install headers for some sound libraries. On Ubuntu Linux, this command should install the necessary packages: + +```bash +sudo apt-get install build-essential libasound2-dev libjack-dev portaudio19-dev +``` +On Fedora Linux, use +```bash +sudo dnf group install "C Development Tools and Libraries" +sudo dnf install SAASound-devel jack-audio-connection-kit-devel portaudio-devel +``` + + +The Magenta libraries are now available for use within Python programs and +Jupyter notebooks, and the Magenta scripts are installed in your path! + +## Using Magenta + +You can now train our various models and use them to generate music, audio, and images. You can +find instructions for each of the models by exploring the [models directory](magenta/models). + +## Development Environment +If you want to develop on Magenta, you'll need to set up the full Development Environment. + +First, clone this repository: + +```bash +git clone https://github.com/tensorflow/magenta.git +``` + +Next, install the dependencies by changing to the base directory and executing the setup command: + +```bash +pip install -e . +``` + +You can now edit the files and run scripts by calling Python as usual. For example, this is how you would run the `melody_rnn_generate` script from the base directory: + +```bash +python magenta/models/melody_rnn/melody_rnn_generate --config=... +``` + +You can also install the (potentially modified) package with: + +```bash +pip install . +``` + +Before creating a pull request, please also test your changes with: + +```bash +pip install pytest-pylint +pytest +``` + +## PIP Release + +To build a new version for pip, bump the version and then run: + +```bash +python setup.py test +python setup.py bdist_wheel --universal +twine upload dist/magenta-N.N.N-py2.py3-none-any.whl +``` diff --git a/magenta-logo-bg.png b/magenta-logo-bg.png new file mode 100644 index 0000000..f5557de Binary files /dev/null and b/magenta-logo-bg.png differ diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9af7e6f --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c00e65d --- /dev/null +++ b/setup.py @@ -0,0 +1,162 @@ +# Copyright 2020 The Magenta Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""A setuptools based setup module for magenta.""" + +from setuptools import find_packages +from setuptools import setup + +# Bit of a hack to parse the version string stored in version.py without +# executing __init__.py, which will end up requiring a bunch of dependencies to +# execute (e.g., tensorflow, pretty_midi, etc.). +# Makes the __version__ variable available. +with open('magenta/version.py') as in_file: + exec(in_file.read()) # pylint: disable=exec-used + +REQUIRED_PACKAGES = [ + 'absl-py', + 'dm-sonnet', + # tensor2tensor has a dependency on dopamine-rl, which we don't use. + # pin to a version that doesn't require pygame installation because that + # has too many external non-python dependencies. + 'dopamine-rl <= 3.0.1', + 'imageio', + 'librosa >= 0.6.2, < 0.8.0', + 'matplotlib >= 1.5.3', + 'mido == 1.2.6', + 'mir_eval >= 0.4', + 'note-seq', + 'numba < 0.50', # temporary fix for librosa import + 'numpy', + 'Pillow >= 3.4.2', + 'pretty_midi >= 0.2.6', + 'pygtrie >= 2.3', + 'python-rtmidi >= 1.1, < 1.2', # 1.2 breaks us + 'scikit-image', + 'scipy >= 0.18.1', + 'six >= 1.12.0', + 'sk-video', + 'sox >= 1.3.7', + 'tensor2tensor', + 'tensorflow', + 'tensorflow-datasets', + 'tensorflow-probability', + 'tf_slim', + 'wheel', +] + +EXTRAS_REQUIRE = { + 'beam': [ + 'apache-beam[gcp] >= 2.14.0', + ], + 'onsets_frames_realtime': [ + 'pyaudio', + 'colorama', + 'tflite', + ], + 'test': [ + 'pylint', + 'pytest', + ] +} + +# pylint:disable=line-too-long +CONSOLE_SCRIPTS = [ + 'magenta.interfaces.midi.magenta_midi', + 'magenta.interfaces.midi.midi_clock', + 'magenta.models.arbitrary_image_stylization.arbitrary_image_stylization_evaluate', + 'magenta.models.arbitrary_image_stylization.arbitrary_image_stylization_train', + 'magenta.models.arbitrary_image_stylization.arbitrary_image_stylization_with_weights', + 'magenta.models.arbitrary_image_stylization.arbitrary_image_stylization_distill_mobilenet', + 'magenta.models.drums_rnn.drums_rnn_create_dataset', + 'magenta.models.drums_rnn.drums_rnn_generate', + 'magenta.models.drums_rnn.drums_rnn_train', + 'magenta.models.image_stylization.image_stylization_create_dataset', + 'magenta.models.image_stylization.image_stylization_evaluate', + 'magenta.models.image_stylization.image_stylization_finetune', + 'magenta.models.image_stylization.image_stylization_train', + 'magenta.models.image_stylization.image_stylization_transform', + 'magenta.models.improv_rnn.improv_rnn_create_dataset', + 'magenta.models.improv_rnn.improv_rnn_generate', + 'magenta.models.improv_rnn.improv_rnn_train', + 'magenta.models.gansynth.gansynth_train', + 'magenta.models.gansynth.gansynth_generate', + 'magenta.models.melody_rnn.melody_rnn_create_dataset', + 'magenta.models.melody_rnn.melody_rnn_generate', + 'magenta.models.melody_rnn.melody_rnn_train', + 'magenta.models.music_vae.music_vae_generate', + 'magenta.models.music_vae.music_vae_train', + 'magenta.models.nsynth.wavenet.nsynth_generate', + 'magenta.models.nsynth.wavenet.nsynth_save_embeddings', + 'magenta.models.onsets_frames_transcription.onsets_frames_transcription_create_dataset', + 'magenta.models.onsets_frames_transcription.onsets_frames_transcription_create_dataset_maps', + 'magenta.models.onsets_frames_transcription.onsets_frames_transcription_create_tfrecords', + 'magenta.models.onsets_frames_transcription.onsets_frames_transcription_infer', + 'magenta.models.onsets_frames_transcription.onsets_frames_transcription_train', + 'magenta.models.onsets_frames_transcription.onsets_frames_transcription_transcribe', + 'magenta.models.onsets_frames_transcription.realtime.onsets_frames_transcription_realtime', + 'magenta.models.performance_rnn.performance_rnn_create_dataset', + 'magenta.models.performance_rnn.performance_rnn_generate', + 'magenta.models.performance_rnn.performance_rnn_train', + 'magenta.models.pianoroll_rnn_nade.pianoroll_rnn_nade_create_dataset', + 'magenta.models.pianoroll_rnn_nade.pianoroll_rnn_nade_generate', + 'magenta.models.pianoroll_rnn_nade.pianoroll_rnn_nade_train', + 'magenta.models.polyphony_rnn.polyphony_rnn_create_dataset', + 'magenta.models.polyphony_rnn.polyphony_rnn_generate', + 'magenta.models.polyphony_rnn.polyphony_rnn_train', + 'magenta.models.rl_tuner.rl_tuner_train', + 'magenta.models.sketch_rnn.sketch_rnn_train', + 'magenta.scripts.convert_dir_to_note_sequences', + 'magenta.tensor2tensor.t2t_datagen', + 'magenta.tensor2tensor.t2t_decoder', + 'magenta.tensor2tensor.t2t_trainer', +] +# pylint:enable=line-too-long + +setup( + name='magenta', + version=__version__, # pylint: disable=undefined-variable + description='Use machine learning to create art and music', + long_description='', + url='https://magenta.tensorflow.org/', + author='Google Inc.', + author_email='magenta-discuss@gmail.com', + license='Apache 2', + # PyPI package information. + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: Python :: 3', + 'Topic :: Scientific/Engineering :: Mathematics', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: Software Development :: Libraries', + ], + keywords='tensorflow machine learning magenta music art', + + packages=find_packages(), + install_requires=REQUIRED_PACKAGES, + extras_require=EXTRAS_REQUIRE, + entry_points={ + 'console_scripts': ['%s = %s:console_entry_point' % (n, p) for n, p in + ((s.split('.')[-1], s) for s in CONSOLE_SCRIPTS)], + }, + + include_package_data=True, + package_data={ + 'magenta': ['models/image_stylization/evaluation_images/*.jpg'], + }, +)