├── .gitignore ├── .gitmodules ├── INSTALL.txt ├── MANIFEST.in ├── README.md ├── RELEASE_NOTES.txt ├── apidocs ├── api-objects.txt ├── class-tree.html ├── crarr.png ├── echonest.remix-module.html ├── echonest.remix-pysrc.html ├── echonest.remix.action-module.html ├── echonest.remix.action-pysrc.html ├── echonest.remix.action.Blend-class.html ├── echonest.remix.action.Crossfade-class.html ├── echonest.remix.action.Crossmatch-class.html ├── echonest.remix.action.Edit-class.html ├── echonest.remix.action.Fadein-class.html ├── echonest.remix.action.Fadeout-class.html ├── echonest.remix.action.Jump-class.html ├── echonest.remix.action.Playback-class.html ├── echonest.remix.audio-module.html ├── echonest.remix.audio-pysrc.html ├── echonest.remix.audio.AmplitudeFactor-class.html ├── echonest.remix.audio.AudioAnalysis-class.html ├── echonest.remix.audio.AudioData-class.html ├── echonest.remix.audio.AudioData32-class.html ├── echonest.remix.audio.AudioEffect-class.html ├── echonest.remix.audio.AudioQuantum-class.html ├── echonest.remix.audio.AudioQuantumList-class.html ├── echonest.remix.audio.AudioRenderable-class.html ├── echonest.remix.audio.AudioSegment-class.html ├── echonest.remix.audio.EchoNestRemixError-class.html ├── echonest.remix.audio.FileTypeError-class.html ├── echonest.remix.audio.LevelDB-class.html ├── echonest.remix.audio.LocalAnalysis-class.html ├── echonest.remix.audio.LocalAudioFile-class.html ├── echonest.remix.audio.ModifiedRenderable-class.html ├── echonest.remix.audio.Simultaneous-class.html ├── echonest.remix.audio.TimeTruncateFactor-class.html ├── echonest.remix.audio.TimeTruncateLength-class.html ├── echonest.remix.modify-module.html ├── echonest.remix.modify-pysrc.html ├── echonest.remix.modify.Modify-class.html ├── echonest.remix.support-module.html ├── echonest.remix.support-pysrc.html ├── echonest.remix.support.midi-module.html ├── echonest.remix.support.midi-pysrc.html ├── echonest.remix.support.midi.DataTypeConverters-module.html ├── echonest.remix.support.midi.DataTypeConverters-pysrc.html ├── echonest.remix.support.midi.EventDispatcher-module.html ├── echonest.remix.support.midi.EventDispatcher-pysrc.html ├── echonest.remix.support.midi.EventDispatcher.EventDispatcher-class.html ├── echonest.remix.support.midi.MidiFileParser-module.html ├── echonest.remix.support.midi.MidiFileParser-pysrc.html ├── echonest.remix.support.midi.MidiFileParser.MidiFileParser-class.html ├── echonest.remix.support.midi.MidiInFile-module.html ├── echonest.remix.support.midi.MidiInFile-pysrc.html ├── echonest.remix.support.midi.MidiInFile.MidiInFile-class.html ├── echonest.remix.support.midi.MidiInStream-module.html ├── echonest.remix.support.midi.MidiInStream-pysrc.html ├── echonest.remix.support.midi.MidiInStream.MidiInStream-class.html ├── echonest.remix.support.midi.MidiOutFile-module.html ├── echonest.remix.support.midi.MidiOutFile-pysrc.html ├── echonest.remix.support.midi.MidiOutFile.MidiOutFile-class.html ├── echonest.remix.support.midi.MidiOutStream-module.html ├── echonest.remix.support.midi.MidiOutStream-pysrc.html ├── echonest.remix.support.midi.MidiOutStream.MidiOutStream-class.html ├── echonest.remix.support.midi.MidiToText-module.html ├── echonest.remix.support.midi.MidiToText-pysrc.html ├── echonest.remix.support.midi.MidiToText.MidiToText-class.html ├── echonest.remix.support.midi.RawInstreamFile-module.html ├── echonest.remix.support.midi.RawInstreamFile-pysrc.html ├── echonest.remix.support.midi.RawInstreamFile.RawInstreamFile-class.html ├── echonest.remix.support.midi.RawOutstreamFile-module.html ├── echonest.remix.support.midi.RawOutstreamFile-pysrc.html ├── echonest.remix.support.midi.RawOutstreamFile.RawOutstreamFile-class.html ├── echonest.remix.support.midi.constants-module.html ├── echonest.remix.support.midi.constants-pysrc.html ├── echonest.remix.support.midi.example_mimimal_type0-module.html ├── echonest.remix.support.midi.example_mimimal_type0-pysrc.html ├── echonest.remix.support.midi.example_print_channel_0-module.html ├── echonest.remix.support.midi.example_print_channel_0-pysrc.html ├── echonest.remix.support.midi.example_print_channel_0.Transposer-class.html ├── echonest.remix.support.midi.example_print_events-module.html ├── echonest.remix.support.midi.example_print_events-pysrc.html ├── echonest.remix.support.midi.example_print_file-module.html ├── echonest.remix.support.midi.example_print_file-pysrc.html ├── echonest.remix.support.midi.example_transpose_octave-module.html ├── echonest.remix.support.midi.example_transpose_octave-pysrc.html ├── echonest.remix.support.midi.example_transpose_octave.Transposer-class.html ├── echonest.remix.video-module.html ├── echonest.remix.video-pysrc.html ├── echonest.remix.video.EditableFrames-class.html ├── echonest.remix.video.ImageSequence-class.html ├── echonest.remix.video.SynchronizedAV-class.html ├── echonest.remix.video.VideoSettings-class.html ├── epydoc.css ├── epydoc.js ├── frames.html ├── help.html ├── identifier-index.html ├── index.html ├── module-tree.html ├── pyechonest-module.html ├── pyechonest-pysrc.html ├── pyechonest.artist-module.html ├── pyechonest.artist-pysrc.html ├── pyechonest.artist.Artist-class.html ├── pyechonest.catalog-module.html ├── pyechonest.catalog-pysrc.html ├── pyechonest.catalog.Catalog-class.html ├── pyechonest.config-module.html ├── pyechonest.config-pysrc.html ├── pyechonest.playlist-module.html ├── pyechonest.playlist-pysrc.html ├── pyechonest.playlist.BetaPlaylist-class.html ├── pyechonest.playlist.Playlist-class.html ├── pyechonest.proxies-module.html ├── pyechonest.proxies-pysrc.html ├── pyechonest.proxies.ArtistProxy-class.html ├── pyechonest.proxies.BetaPlaylistProxy-class.html ├── pyechonest.proxies.CatalogProxy-class.html ├── pyechonest.proxies.GenericProxy-class.html ├── pyechonest.proxies.PlaylistProxy-class.html ├── pyechonest.proxies.ResultList-class.html ├── pyechonest.proxies.SongProxy-class.html ├── pyechonest.proxies.TrackProxy-class.html ├── pyechonest.results-module.html ├── pyechonest.results-pysrc.html ├── pyechonest.results.Result-class.html ├── pyechonest.sandbox-module.html ├── pyechonest.sandbox-pysrc.html ├── pyechonest.song-module.html ├── pyechonest.song-pysrc.html ├── pyechonest.song.Song-class.html ├── pyechonest.track-module.html ├── pyechonest.track-pysrc.html ├── pyechonest.track.Track-class.html ├── pyechonest.util-module.html ├── pyechonest.util-pysrc.html ├── pyechonest.util.EchoNestAPIError-class.html ├── pyechonest.util.EchoNestException-class.html ├── pyechonest.util.EchoNestIOError-class.html ├── pyechonest.util.MyBaseHandler-class.html ├── pyechonest.util.MyErrorProcessor-class.html ├── redirect.html ├── toc-echonest.remix-module.html ├── toc-echonest.remix.action-module.html ├── toc-echonest.remix.audio-module.html ├── toc-echonest.remix.modify-module.html ├── toc-echonest.remix.support-module.html ├── toc-echonest.remix.support.midi-module.html ├── toc-echonest.remix.support.midi.DataTypeConverters-module.html ├── toc-echonest.remix.support.midi.EventDispatcher-module.html ├── toc-echonest.remix.support.midi.MidiFileParser-module.html ├── toc-echonest.remix.support.midi.MidiInFile-module.html ├── toc-echonest.remix.support.midi.MidiInStream-module.html ├── toc-echonest.remix.support.midi.MidiOutFile-module.html ├── toc-echonest.remix.support.midi.MidiOutStream-module.html ├── toc-echonest.remix.support.midi.MidiToText-module.html ├── toc-echonest.remix.support.midi.RawInstreamFile-module.html ├── toc-echonest.remix.support.midi.RawOutstreamFile-module.html ├── toc-echonest.remix.support.midi.constants-module.html ├── toc-echonest.remix.support.midi.example_mimimal_type0-module.html ├── toc-echonest.remix.support.midi.example_print_channel_0-module.html ├── toc-echonest.remix.support.midi.example_print_events-module.html ├── toc-echonest.remix.support.midi.example_print_file-module.html ├── toc-echonest.remix.support.midi.example_transpose_octave-module.html ├── toc-echonest.remix.video-module.html ├── toc-everything.html ├── toc-pyechonest-module.html ├── toc-pyechonest.artist-module.html ├── toc-pyechonest.catalog-module.html ├── toc-pyechonest.config-module.html ├── toc-pyechonest.playlist-module.html ├── toc-pyechonest.proxies-module.html ├── toc-pyechonest.results-module.html ├── toc-pyechonest.sandbox-module.html ├── toc-pyechonest.song-module.html ├── toc-pyechonest.track-module.html ├── toc-pyechonest.util-module.html ├── toc.html ├── uml_class_diagram_for_echonest.gif ├── uml_class_diagram_for_echonest_10.gif ├── uml_class_diagram_for_echonest_11.gif ├── uml_class_diagram_for_echonest_12.gif ├── uml_class_diagram_for_echonest_13.gif ├── uml_class_diagram_for_echonest_14.gif ├── uml_class_diagram_for_echonest_15.gif ├── uml_class_diagram_for_echonest_16.gif ├── uml_class_diagram_for_echonest_17.gif ├── uml_class_diagram_for_echonest_18.gif ├── uml_class_diagram_for_echonest_19.gif ├── uml_class_diagram_for_echonest_2.gif ├── uml_class_diagram_for_echonest_20.gif ├── uml_class_diagram_for_echonest_21.gif ├── uml_class_diagram_for_echonest_22.gif ├── uml_class_diagram_for_echonest_23.gif ├── uml_class_diagram_for_echonest_24.gif ├── uml_class_diagram_for_echonest_25.gif ├── uml_class_diagram_for_echonest_26.gif ├── uml_class_diagram_for_echonest_27.gif ├── uml_class_diagram_for_echonest_28.gif ├── uml_class_diagram_for_echonest_29.gif ├── uml_class_diagram_for_echonest_3.gif ├── uml_class_diagram_for_echonest_30.gif ├── uml_class_diagram_for_echonest_31.gif ├── uml_class_diagram_for_echonest_32.gif ├── uml_class_diagram_for_echonest_33.gif ├── uml_class_diagram_for_echonest_34.gif ├── uml_class_diagram_for_echonest_4.gif ├── uml_class_diagram_for_echonest_5.gif ├── uml_class_diagram_for_echonest_6.gif ├── uml_class_diagram_for_echonest_7.gif ├── uml_class_diagram_for_echonest_8.gif ├── uml_class_diagram_for_echonest_9.gif ├── uml_class_diagram_for_pyechone.gif ├── uml_class_diagram_for_pyechone_10.gif ├── uml_class_diagram_for_pyechone_11.gif ├── uml_class_diagram_for_pyechone_12.gif ├── uml_class_diagram_for_pyechone_13.gif ├── uml_class_diagram_for_pyechone_14.gif ├── uml_class_diagram_for_pyechone_15.gif ├── uml_class_diagram_for_pyechone_16.gif ├── uml_class_diagram_for_pyechone_17.gif ├── uml_class_diagram_for_pyechone_18.gif ├── uml_class_diagram_for_pyechone_19.gif ├── uml_class_diagram_for_pyechone_2.gif ├── uml_class_diagram_for_pyechone_20.gif ├── uml_class_diagram_for_pyechone_3.gif ├── uml_class_diagram_for_pyechone_4.gif ├── uml_class_diagram_for_pyechone_5.gif ├── uml_class_diagram_for_pyechone_6.gif ├── uml_class_diagram_for_pyechone_7.gif ├── uml_class_diagram_for_pyechone_8.gif └── uml_class_diagram_for_pyechone_9.gif ├── epydoc.cfg ├── examples ├── .DS_Store ├── afromb │ └── afromb.py ├── cowbell │ ├── cowbell.py │ └── sounds │ │ ├── cowbell0.wav │ │ ├── cowbell1.wav │ │ ├── cowbell2.wav │ │ ├── cowbell3.wav │ │ ├── cowbell4.wav │ │ ├── trill.wav │ │ ├── walken0.wav │ │ ├── walken1.wav │ │ ├── walken10.wav │ │ ├── walken11.wav │ │ ├── walken12.wav │ │ ├── walken13.wav │ │ ├── walken14.wav │ │ ├── walken15.wav │ │ ├── walken2.wav │ │ ├── walken3.wav │ │ ├── walken4.wav │ │ ├── walken5.wav │ │ ├── walken6.wav │ │ ├── walken7.wav │ │ ├── walken8.wav │ │ └── walken9.wav ├── earworm │ ├── README.txt │ ├── earworm.py │ ├── earworm_support.py │ └── utils.py ├── filter │ └── filter.py ├── limp │ └── lopside.py ├── music │ ├── .DS_Store │ ├── Hiiragi_Fukuda-Open_Fields_Blues.mp3 │ ├── Karl_Blau-Gnos_Levohs.mp3 │ ├── Raleigh_Moncrief-Guppies.mp3 │ ├── Tracky_Birthday-Newish_Disco.mp3 │ └── attribution.txt ├── one │ └── one.py ├── quanta │ └── quanta.py ├── reverse │ └── reverse.py ├── save │ └── save.py ├── selection │ └── tonic.py ├── sorting │ ├── sorting.py │ ├── sorting_pitch.py │ └── sorting_timbre.py ├── step │ ├── step-by-pitch.py │ ├── step-by-section.py │ └── step.py ├── stretch │ ├── beatshift.py │ ├── cycle_dirac.py │ ├── cycle_soundtouch.py │ └── simple_stretch.py ├── swinger │ └── swinger.py ├── videx │ ├── vafroma.py │ ├── vafroma2.py │ ├── vafroma3.py │ ├── vafromb.py │ ├── vdissoc.py │ ├── vone.py │ └── vreverse.py └── waltzify │ └── waltzify.py ├── external ├── cAction │ ├── actionmodule.cpp │ └── setup.py ├── en-ffmpeg │ ├── mac │ │ └── en-ffmpeg │ └── win │ │ └── en-ffmpeg.exe ├── pydirac225 │ ├── DIRAC LE License Agreement.txt │ ├── diracmodule.cpp │ ├── libs │ │ ├── Darwin │ │ │ └── libDirac.a │ │ ├── Linux │ │ │ ├── libDirac.a │ │ │ └── libDirac64.a │ │ └── Windows │ │ │ ├── Dirac.lib │ │ │ └── DiracLE.dll │ ├── setup.py │ ├── source │ │ ├── Dirac.h │ │ ├── Dirac_LE.cpp │ │ └── Dirac_LE.h │ └── test_dirac.py ├── pysoundtouch14 │ ├── build │ │ ├── lib.linux-i686-2.5 │ │ │ └── soundtouch.so │ │ ├── lib.macosx-10.5-i386-2.5 │ │ │ └── soundtouch.so │ │ └── lib.win32-2.6 │ │ │ └── soundtouch.pyd │ ├── libsoundtouch │ │ ├── 3dnow_win.cpp │ │ ├── AAFilter.cpp │ │ ├── AAFilter.h │ │ ├── BPMDetect.cpp │ │ ├── BPMDetect.h │ │ ├── FIFOSampleBuffer.cpp │ │ ├── FIFOSampleBuffer.h │ │ ├── FIFOSamplePipe.h │ │ ├── FIRFilter.cpp │ │ ├── FIRFilter.h │ │ ├── PeakFinder.cpp │ │ ├── PeakFinder.h │ │ ├── RateTransposer.cpp │ │ ├── RateTransposer.h │ │ ├── STTypes.h │ │ ├── SoundTouch.cpp │ │ ├── SoundTouch.h │ │ ├── TDStretch.cpp │ │ ├── TDStretch.h │ │ ├── cpu_detect.h │ │ ├── cpu_detect_x86_gcc.cpp │ │ ├── cpu_detect_x86_win.cpp │ │ ├── mmx_optimized.cpp │ │ └── sse_optimized.cpp │ ├── setup.py │ └── soundtouchmodule.cpp └── youtube-dl │ └── youtube-dl ├── fix_develop_install.py ├── setup.py ├── src └── echonest │ ├── __init__.py │ └── remix │ ├── __init__.py │ ├── action.py │ ├── audio.py │ ├── local_db.py │ ├── modify.py │ ├── support │ ├── __init__.py │ ├── exceptionthread.py │ ├── ffmpeg.py │ └── midi │ │ ├── DataTypeConverters.py │ │ ├── EventDispatcher.py │ │ ├── MidiFileParser.py │ │ ├── MidiInFile.py │ │ ├── MidiInStream.py │ │ ├── MidiOutFile.py │ │ ├── MidiOutStream.py │ │ ├── MidiToText.py │ │ ├── RawInstreamFile.py │ │ ├── RawOutstreamFile.py │ │ ├── __init__.py │ │ ├── changes.txt │ │ ├── constants.py │ │ ├── example_mimimal_type0.py │ │ ├── example_print_channel_0.py │ │ ├── example_print_events.py │ │ ├── example_print_file.py │ │ ├── example_transpose_octave.py │ │ ├── experimental │ │ ├── EventDispatcherBase.py │ │ ├── MidiOutPassThrough.py │ │ ├── MidiOutStreamBase.py │ │ └── readme.txt │ │ ├── midiout │ │ ├── minimal_type0.mid │ │ └── transposed.mid │ │ ├── readme.txt │ │ ├── test │ │ ├── midifiles │ │ │ ├── midiout.mid │ │ │ ├── minimal-cubase-type0.mid │ │ │ ├── minimal-cubase-type1.mid │ │ │ ├── minimal.mid │ │ │ ├── minimal.txt │ │ │ ├── minimal_analyse.txt │ │ │ └── readme.txt │ │ └── readme.txt │ │ └── version.txt │ └── video.py ├── tests ├── TESTING.txt ├── input_file.mp3 └── test_ffmpeg.py ├── tutorial ├── afromb │ └── afromb.py ├── cowbell │ ├── cowbell.py │ ├── cowbell │ │ ├── cowbell.py │ │ └── sounds │ │ │ ├── cowbell0.wav │ │ │ ├── cowbell1.wav │ │ │ ├── cowbell2.wav │ │ │ ├── cowbell3.wav │ │ │ ├── cowbell4.wav │ │ │ ├── trill.wav │ │ │ ├── walken0.wav │ │ │ ├── walken1.wav │ │ │ ├── walken10.wav │ │ │ ├── walken11.wav │ │ │ ├── walken12.wav │ │ │ ├── walken13.wav │ │ │ ├── walken14.wav │ │ │ ├── walken15.wav │ │ │ ├── walken2.wav │ │ │ ├── walken3.wav │ │ │ ├── walken4.wav │ │ │ ├── walken5.wav │ │ │ ├── walken6.wav │ │ │ ├── walken7.wav │ │ │ ├── walken8.wav │ │ │ └── walken9.wav │ └── sounds │ │ ├── cowbell0.wav │ │ ├── cowbell1.wav │ │ ├── cowbell2.wav │ │ ├── cowbell3.wav │ │ ├── cowbell4.wav │ │ ├── trill.wav │ │ ├── walken0.wav │ │ ├── walken1.wav │ │ ├── walken10.wav │ │ ├── walken11.wav │ │ ├── walken12.wav │ │ ├── walken13.wav │ │ ├── walken14.wav │ │ ├── walken15.wav │ │ ├── walken2.wav │ │ ├── walken3.wav │ │ ├── walken4.wav │ │ ├── walken5.wav │ │ ├── walken6.wav │ │ ├── walken7.wav │ │ ├── walken8.wav │ │ └── walken9.wav ├── drums │ ├── breaks │ │ ├── AmenBrother.mp3 │ │ ├── GiveituporTurnitLoose.mp3 │ │ └── assemblyline.mp3 │ └── drums.py ├── limp │ └── lopside.py ├── one │ └── one.py ├── reverse │ └── reverse.py ├── selection │ └── tonic.py ├── stretch │ ├── beatshift.py │ ├── cycle_dirac.py │ └── cycle_soundtouch.py ├── swinger │ └── swinger.py ├── tutorial.txt └── waltzify │ └── waltzify.py └── welcome.rtf /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build/ 3 | dist/ 4 | js/ 5 | remix.egg-info 6 | *.so 7 | *.pyc 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "pyechonest"] 2 | path = pyechonest 3 | url = git://github.com/echonest/pyechonest.git 4 | -------------------------------------------------------------------------------- /INSTALL.txt: -------------------------------------------------------------------------------- 1 | Echo Nest Remix - Install From Source 2 | 3 | Introduction: 4 | 5 | Here is how you install Remix from source on Mac, Windows, or Linux. This method is either for Linux users, "experts" or developers, people that may have their own versions of Python already installed, or people want to contribute to Remix in some way. If you're not one of those people, you most likely want one of the install packages on the main page, not this stuff. 6 | 7 | Requirements: 8 | 9 | Installing Remix from source requires: 10 | -- python2.5-dev -- Python 2.5, 2.6, or 2.7 with the headers 11 | -- ffmpeg (only if you are on Linux) 12 | -- python-numpy 13 | -- A build environment, either XCode (mac), build-essential (gcc, Linux), Visual Studio Express or higher (Windows) 14 | 15 | Steps 16 | 17 | -- Install Numpy using the package manager of your choice, or from the web. 18 | -- Install python2.5-dev using the package manager of your choice 19 | -- Install build-essential using the package manager of your choice, get XCode, or get Visual Studio Express 20 | -- If you are on Linux, you need to get ffmpeg if you don't already have it. Our distribution has builds for Mac and Windows, but not Linux. The best place to get a good build of ffmpeg with all the good codecs in it is the Debian Multimedia Repository. All you need to do is add the correct lines to your /etc/apt/sources.list file and then apt-get install ffmpeg. After installing ffmpeg, you need to make a symbolic link to it so that Remix knows where to find it: 21 | sudo ln -s `which ffmpeg` /usr/local/bin/en-ffmpeg 22 | Note that the setup.py script also installs a version of ffmpeg on Mac and Windows called "en-ffmpeg" as well as the youtube-dl script. The pysoundtouch and pydirac libraries are also compiled and copied over. The version of ffmpeg we install is not modified in any way but includes various useful codecs and is confirmed to work well with Remix. If you have your own version of ffmpeg, feel free to use it but it needs to be symlinked to en-ffmpeg (we do this to not trample on existing versions of ffmpeg a user may have installed.) 23 | 24 | Test It: 25 | 26 | To test Python and Numpy, try the following: 27 | python 28 | import numpy 29 | To test ffmpeg, try: 30 | en-ffmpeg 31 | 32 | Install: 33 | 34 | If those give no errors, you're ready to get remix installed: 35 | 36 | -- Clone the source code from github: 37 | git clone https://github.com/echonest/remix.git 38 | -- Initialize and update the pyechonest submodule: 39 | git submodule update --init 40 | -- Install remix using setup.py: 41 | 42 | sudo python setup.py install 43 | 44 | Once that's done, you can visit http://echonest.github.com/remix/ to get an API key and run some examples! 45 | 46 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include * 2 | recursive-include examples * 3 | recursive-include external * 4 | prune flash 5 | prune tests 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Welcome to Echo Nest Remix 2 | 3 | ## Please check out [our approved local replacement for Remix, Amen](https://github.com/algorithmic-music-exploration/amen) 4 | 5 | ## The track/upload endpoint is no longer in service so many Remix based scripts will no longer work. 6 | 7 | Echo Nest Remix is **the Internet Synthesizer.** 8 | Make amazing things from music, automatically. Turn any music or video into Python, Flash, or Javascript code. 9 | 10 | Want more cowbell? [Remix can do it.](http://www.morecowbell.dj/ "") 11 | Want to make it swing? [Remix can do it.](http://swingify.cloudapp.net/ "") 12 | Want to turn any track into drum & bass? [Remix can do it.](http://the.wubmachine.com/ "") 13 | Want to make new music videos out of old ones? [Remix can do it.](http://www.youtube.com/watch?v=_bW7AkhgQpc/ "") 14 | 15 | ## Getting Started 16 | We've made a shiny new page for getting Remix installed: - if you have any problems, let us know! 17 | 18 | -![alt text](http://i.imgur.com/WWLYo.gif "Frustrated cat can't believe this is the 12th time he's clicked on an auto-linked README.md URL") 19 | -------------------------------------------------------------------------------- /apidocs/crarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/crarr.png -------------------------------------------------------------------------------- /apidocs/frames.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /apidocs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | remix 7 | 8 | 9 | 10 | 11 | 13 |

Module remix

14 |
15 |

Variables

16 |
17 | __package__
19 |
20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.action-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | action 7 | 8 | 9 | 10 | 11 | 13 |

Module action

14 |
15 |

Classes

16 | Blend
Crossfade
Crossmatch
Edit
Fadein
Fadeout
Jump
Playback

Functions

25 | display_actions
humanize_time
make_mono
make_stereo
render
rows

Variables

32 | __package__

34 | [hide private] 36 | 37 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.modify-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | modify 7 | 8 | 9 | 10 | 11 | 13 |

Module modify

14 |
15 |

Classes

16 | Modify

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | support 7 | 8 | 9 | 10 | 11 | 13 |

Module support

14 |
15 |

Variables

16 |
17 | __package__
19 |
20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | midi 7 | 8 | 9 | 10 | 11 | 13 |

Module midi

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.DataTypeConverters-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | DataTypeConverters 7 | 8 | 9 | 10 | 11 | 13 |

Module DataTypeConverters

14 |
15 |

Functions

16 | fromBytes
getNibbles
readBew
readVar
setNibbles
toBytes
to_n_bits
varLen
writeBew
writeVar

Variables

27 | __package__

29 | [hide private] 31 | 32 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.EventDispatcher-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | EventDispatcher 7 | 8 | 9 | 10 | 11 | 13 |

Module EventDispatcher

14 |
15 |

Classes

16 | EventDispatcher

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.MidiFileParser-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | MidiFileParser 7 | 8 | 9 | 10 | 11 | 13 |

Module MidiFileParser

14 |
15 |

Classes

16 | MidiFileParser

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.MidiInFile-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | MidiInFile 7 | 8 | 9 | 10 | 11 | 13 |

Module MidiInFile

14 |
15 |

Classes

16 | MidiInFile

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.MidiInStream-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | MidiInStream 7 | 8 | 9 | 10 | 11 | 13 |

Module MidiInStream

14 |
15 |

Classes

16 | MidiInStream

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.MidiOutFile-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | MidiOutFile 7 | 8 | 9 | 10 | 11 | 13 |

Module MidiOutFile

14 |
15 |

Classes

16 | MidiOutFile

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.MidiOutStream-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | MidiOutStream 7 | 8 | 9 | 10 | 11 | 13 |

Module MidiOutStream

14 |
15 |

Classes

16 | MidiOutStream

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.MidiToText-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | MidiToText 7 | 8 | 9 | 10 | 11 | 13 |

Module MidiToText

14 |
15 |

Classes

16 | MidiToText

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.RawInstreamFile-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | RawInstreamFile 7 | 8 | 9 | 10 | 11 | 13 |

Module RawInstreamFile

14 |
15 |

Classes

16 | RawInstreamFile

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.RawOutstreamFile-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | RawOutstreamFile 7 | 8 | 9 | 10 | 11 | 13 |

Module RawOutstreamFile

14 |
15 |

Classes

16 | RawOutstreamFile

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.example_mimimal_type0-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_mimimal_type0 7 | 8 | 9 | 10 | 11 | 13 |

Module example_mimimal_type0

14 |
15 |

Variables

16 | midi
out_file

19 | [hide private] 21 | 22 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.example_print_channel_0-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_print_channel_0 7 | 8 | 9 | 10 | 11 | 13 |

Module example_print_channel_0

14 |
15 |

Classes

16 | Transposer

Variables

18 | event_handler
in_file
midi_in

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.example_print_events-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_print_events 7 | 8 | 9 | 10 | 11 | 13 |

Module example_print_events

14 |
15 |

Variables

16 | __package__
midi

19 | [hide private] 21 | 22 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.example_print_file-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_print_file 7 | 8 | 9 | 10 | 11 | 13 |

Module example_print_file

14 |
15 |

Variables

16 | midiIn
test_file

19 | [hide private] 21 | 22 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /apidocs/toc-echonest.remix.support.midi.example_transpose_octave-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_transpose_octave 7 | 8 | 9 | 10 | 11 | 13 |

Module example_transpose_octave

14 |
15 |

Classes

16 | Transposer

Variables

18 | in_file
midi_in
midi_out
out_file

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | pyechonest 7 | 8 | 9 | 10 | 11 | 13 |

Module pyechonest

14 |
15 |

Variables

16 |
17 | __package__
19 |
20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.artist-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | artist 7 | 8 | 9 | 10 | 11 | 13 |

Module artist

14 |
15 |

Classes

16 | Artist

Functions

18 | extract
list_terms
search
similar
suggest
top_hottt
top_terms

Variables

26 | __package__

28 | [hide private] 30 | 31 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.catalog-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | catalog 7 | 8 | 9 | 10 | 11 | 13 |

Module catalog

14 |
15 |

Classes

16 | Catalog

Functions

18 | dthandler
list_catalogs

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.config-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | config 7 | 8 | 9 | 10 | 11 | 13 |

Module config

14 |
15 |

Variables

16 | API_HOST
API_SELECTOR
API_VERSION
CALL_TIMEOUT
CODEGEN_BINARY_OVERRIDE
ECHO_NEST_API_KEY
ECHO_NEST_CONSUMER_KEY
ECHO_NEST_SHARED_SECRET
HTTP_USER_AGENT
TRACE_API_CALLS
__package__
envkeys
key

30 | [hide private] 32 | 33 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.playlist-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | playlist 7 | 8 | 9 | 10 | 11 | 13 |

Module playlist

14 |
15 |

Classes

16 | BetaPlaylist
Playlist

Functions

19 | basic
static

Variables

22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.proxies-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | proxies 7 | 8 | 9 | 10 | 11 | 13 |

Module proxies

14 |
15 |

Classes

16 | ArtistProxy
BetaPlaylistProxy
CatalogProxy
GenericProxy
PlaylistProxy
ResultList
SongProxy
TrackProxy

Variables

25 | __package__

27 | [hide private] 29 | 30 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.results-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | results 7 | 8 | 9 | 10 | 11 | 13 |

Module results

14 |
15 |

Classes

16 | Result

Functions

18 | make_results

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.sandbox-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sandbox 7 | 8 | 9 | 10 | 11 | 13 |

Module sandbox

14 |
15 |

Functions

16 | access
list

Variables

19 | __package__

21 | [hide private] 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.song-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | song 7 | 8 | 9 | 10 | 11 | 13 |

Module song

14 |
15 |

Classes

16 | Song

Functions

18 | identify
profile
search

Variables

22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.track-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | track 7 | 8 | 9 | 10 | 11 | 13 |

Module track

14 |
15 |

Classes

16 | Track

Functions

18 |
19 | _analyze
21 |
22 | _profile
24 |
25 | _track_from_data
27 |
28 | _track_from_response
30 |
31 | _upload
33 |
34 | _wait_for_pending_track
36 | track_from_file
track_from_filename
track_from_id
track_from_md5
track_from_reanalyzing_id
track_from_reanalyzing_md5
track_from_url

Variables

44 | DEFAULT_ASYNC_TIMEOUT
__package__

47 | [hide private] 49 | 50 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /apidocs/toc-pyechonest.util-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | util 7 | 8 | 9 | 10 | 11 | 13 |

Module util

14 |
15 |

Classes

16 | EchoNestAPIError
EchoNestException
EchoNestIOError
MyBaseHandler
MyErrorProcessor

Functions

22 | callm
codegen
fix
get_successful_response
oauthgetm
postChunked
reallyUTF8
reallyunicode

Variables

31 | TYPENAMES
__package__
foreign_regex
headers
logger
long_regex
opener
short_regex

40 | [hide private] 42 | 43 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_10.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_11.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_12.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_13.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_14.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_15.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_16.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_17.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_18.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_19.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_2.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_20.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_21.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_22.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_23.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_24.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_25.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_26.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_27.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_28.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_29.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_3.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_30.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_31.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_32.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_33.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_34.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_4.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_5.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_6.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_7.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_8.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_echonest_9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_echonest_9.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_10.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_11.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_12.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_13.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_14.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_15.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_16.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_17.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_18.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_19.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_2.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_20.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_3.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_4.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_5.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_6.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_7.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_8.gif -------------------------------------------------------------------------------- /apidocs/uml_class_diagram_for_pyechone_9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/apidocs/uml_class_diagram_for_pyechone_9.gif -------------------------------------------------------------------------------- /epydoc.cfg: -------------------------------------------------------------------------------- 1 | [epydoc] 2 | 3 | modules: echonest.remix, pyechonest 4 | 5 | output: html 6 | 7 | target: apidocs 8 | 9 | docformat: restructuredtext 10 | 11 | # name: The Echo Nest Remix API 12 | 13 | url: https://github.com/echonest/remix/ 14 | 15 | css: grayscale 16 | 17 | # top: echonest.remix.audio 18 | 19 | graph: all 20 | 21 | -------------------------------------------------------------------------------- /examples/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/.DS_Store -------------------------------------------------------------------------------- /examples/cowbell/sounds/cowbell0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/cowbell0.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/cowbell1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/cowbell1.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/cowbell2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/cowbell2.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/cowbell3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/cowbell3.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/cowbell4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/cowbell4.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/trill.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/trill.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken0.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken1.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken10.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken10.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken11.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken11.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken12.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken12.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken13.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken13.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken14.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken14.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken15.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken15.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken2.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken3.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken4.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken5.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken6.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken7.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken7.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken8.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken8.wav -------------------------------------------------------------------------------- /examples/cowbell/sounds/walken9.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/cowbell/sounds/walken9.wav -------------------------------------------------------------------------------- /examples/earworm/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | utils.py 5 | 6 | Created by Jason Sundram, on 2010-04-05. 7 | """ 8 | 9 | def flatten(l): 10 | """ Converts a list of tuples to a flat list. 11 | e.g. flatten([(1,2), (3,4)]) => [1,2,3,4] 12 | """ 13 | return [item for pair in l for item in pair] 14 | 15 | def tuples(l, n=2): 16 | """ returns n-tuples from l. 17 | e.g. tuples(range(4), n=2) -> [(0, 1), (1, 2), (2, 3)] 18 | """ 19 | return zip(*[l[i:] for i in range(n)]) 20 | 21 | def rows(m): 22 | """returns the # of rows in a numpy matrix""" 23 | return m.shape[0] -------------------------------------------------------------------------------- /examples/filter/filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env/python 2 | #encoding: utf=8 3 | """ 4 | filter.py 5 | 6 | Filters lists of AudioQuanta (bars, beats, tatums, segments) 7 | by various proporties, and resynthesizes them 8 | 9 | 'pitch' takes an integer a finds chunks that have a pitch maximum in the given index 10 | 'pitches' takes a list of integers (be sure to quote them on the command line: "[0, 4, 7]") 11 | and finds chunks that have pitch maxima in those pitches - a simple chord-finder 12 | 'duration' takes a pair of integers (be sure to quote them on the command line: "[7, 14]") 13 | or floats and finds chunks that overlap / are within that range in time 14 | 'louder' and 'softer' take a float and finds chunks that are louder or softer than the number 15 | (in dBFS, so 0.0 is the loudest) 16 | 17 | By Thor Kell, 2012-11-14 18 | """ 19 | 20 | import echonest.remix.audio as audio 21 | 22 | usage = """ 23 | python filter.py 24 | 25 | """ 26 | def main(units, key, value, input_filename, output_filename): 27 | audiofile = audio.LocalAudioFile(input_filename) 28 | chunks = audiofile.analysis.__getattribute__(units) 29 | 30 | if key == 'pitch': 31 | value = int(value); 32 | if key == 'pitches': 33 | value = eval(value) 34 | if type(value) != list: 35 | print usage 36 | sys.exit(-1) 37 | if key == 'duration': 38 | value = eval(value) 39 | duration_start = value[0] 40 | duration_end = value[1] 41 | if key == 'louder' or key == 'softer': 42 | value = float(value) 43 | 44 | filtered_chunks = [] 45 | for chunk in chunks: 46 | if key == 'pitch': 47 | pitches = chunk.mean_pitches() 48 | if pitches.index(max(pitches)) == value: 49 | filtered_chunks.append(chunk) 50 | 51 | if key == 'pitches': 52 | max_indexes = [] 53 | pitches = chunk.mean_pitches() 54 | max_pitches = sorted(pitches, reverse=True) 55 | for pitch in max_pitches: 56 | max_indexes.append(pitches.index(pitch)) 57 | 58 | if set(value) == set(max_indexes[0:len(value)]): 59 | filtered_chunks.append(chunk) 60 | 61 | if key == 'duration': 62 | if chunk.start < duration_end and chunk.end > duration_start: 63 | filtered_chunks.append(chunk) 64 | elif chunk.start > duration_end: 65 | break 66 | 67 | if key == 'louder': 68 | if chunk.mean_loudness() > value: 69 | filtered_chunks.append(chunk) 70 | 71 | if key == 'softer': 72 | if chunk.mean_loudness() < value: 73 | filtered_chunks.append(chunk) 74 | 75 | out = audio.getpieces(audiofile, filtered_chunks) 76 | out.encode(output_filename) 77 | 78 | if __name__ == '__main__': 79 | import sys 80 | try: 81 | unit = sys.argv[1] 82 | key = sys.argv[2] 83 | value = sys.argv[3] 84 | input_filename = sys.argv[4] 85 | output_filename = sys.argv[5] 86 | 87 | except: 88 | print usage 89 | sys.exit(-1) 90 | main(unit, key, value, input_filename, output_filename) 91 | -------------------------------------------------------------------------------- /examples/limp/lopside.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | lopside.py 6 | 7 | Cut out the final beat or group of tatums in each bar. 8 | Demonstrates the beat hierarchy navigation in AudioQuantum 9 | 10 | Originally by Adam Lindsay, 2009-01-19. 11 | """ 12 | import echonest.remix.audio as audio 13 | import sys 14 | 15 | usage = """ 16 | Usage: 17 | python lopside.py [tatum|beat] 18 | Beat is selected by default. 19 | 20 | Example: 21 | python lopside.py beat aha.mp3 ahawaltz.mp3 22 | """ 23 | 24 | 25 | def main(units, inputFile, outputFile): 26 | audiofile = audio.LocalAudioFile(inputFile) 27 | collect = audio.AudioQuantumList() 28 | if not audiofile.analysis.bars: 29 | print "No bars found in this analysis!" 30 | print "No output." 31 | sys.exit(-1) 32 | for b in audiofile.analysis.bars[0:-1]: 33 | # all but the last beat 34 | collect.extend(b.children()[0:-1]) 35 | if units.startswith("tatum"): 36 | # all but the last half (round down) of the last beat 37 | half = - (len(b.children()[-1].children()) // 2) 38 | collect.extend(b.children()[-1].children()[0:half]) 39 | # endings were rough, so leave everything after the start 40 | # of the final bar intact: 41 | last = audio.AudioQuantum(audiofile.analysis.bars[-1].start, 42 | audiofile.analysis.duration - 43 | audiofile.analysis.bars[-1].start) 44 | collect.append(last) 45 | out = audio.getpieces(audiofile, collect) 46 | out.encode(outputFile) 47 | 48 | if __name__ == '__main__': 49 | try: 50 | units = sys.argv[-3] 51 | inputFilename = sys.argv[-2] 52 | outputFilename = sys.argv[-1] 53 | except: 54 | print usage 55 | sys.exit(-1) 56 | main(units, inputFilename, outputFilename) 57 | -------------------------------------------------------------------------------- /examples/music/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/music/.DS_Store -------------------------------------------------------------------------------- /examples/music/Hiiragi_Fukuda-Open_Fields_Blues.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/music/Hiiragi_Fukuda-Open_Fields_Blues.mp3 -------------------------------------------------------------------------------- /examples/music/Karl_Blau-Gnos_Levohs.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/music/Karl_Blau-Gnos_Levohs.mp3 -------------------------------------------------------------------------------- /examples/music/Raleigh_Moncrief-Guppies.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/music/Raleigh_Moncrief-Guppies.mp3 -------------------------------------------------------------------------------- /examples/music/Tracky_Birthday-Newish_Disco.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/examples/music/Tracky_Birthday-Newish_Disco.mp3 -------------------------------------------------------------------------------- /examples/music/attribution.txt: -------------------------------------------------------------------------------- 1 | Hiiragi Fukuda - "Open Fields Blues" 2 | http://freemusicarchive.org/music/hiiragi_fukuda/The_Stable_At_Dawn/01_01 3 | Licensed under a Attribution-NonCommercial-ShareAlike License. 4 | 5 | Karl Blau - "Gnos Levohs" 6 | http://freemusicarchive.org/music/Karl_Blau/Zebra/12_Gnos_Levohs 7 | Licensed under a Attribution-Noncommercial-Share Alike 3.0 United States License. 8 | 9 | Raleigh Moncrief - "Guppies" 10 | http://freemusicarchive.org/music/Raleigh_Moncrief/Vitamins_EP/Raleigh_Moncrief_-_Vitamins_EP_-_02_Guppies 11 | Licensed under a Attribution-NonCommercial License. 12 | 13 | Tracky_Birthday - "Newish_Disco" 14 | http://freemusicarchive.org/music/Tracky_Birthday/Animal_Audition/Newish_Disco 15 | Licensed under a Attribution-Noncommercial-Share Alike 3.0 United States License. 16 | -------------------------------------------------------------------------------- /examples/one/one.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | """ 4 | one.py 5 | 6 | Digest only the first beat of every bar. 7 | 8 | By Ben Lacker, 2009-02-18. 9 | """ 10 | import echonest.remix.audio as audio 11 | 12 | usage = """ 13 | Usage: 14 | python one.py 15 | 16 | Example: 17 | python one.py EverythingIsOnTheOne.mp3 EverythingIsReallyOnTheOne.mp3 18 | """ 19 | 20 | def main(input_filename, output_filename): 21 | audiofile = audio.LocalAudioFile(input_filename) 22 | bars = audiofile.analysis.bars 23 | collect = audio.AudioQuantumList() 24 | for bar in bars: 25 | collect.append(bar.children()[0]) 26 | out = audio.getpieces(audiofile, collect) 27 | out.encode(output_filename) 28 | 29 | if __name__ == '__main__': 30 | import sys 31 | try: 32 | input_filename = sys.argv[1] 33 | output_filename = sys.argv[2] 34 | except: 35 | print usage 36 | sys.exit(-1) 37 | main(input_filename, output_filename) 38 | -------------------------------------------------------------------------------- /examples/quanta/quanta.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | quanta.py 6 | 7 | Insert silences between a song's segments, tatums, beats, or sections. 8 | Demonstrates the Remix API's handling of audio quanta. 9 | 10 | By Ben Lacker 2009-3-4, updated by Thor Kell, 2012-9-26 11 | """ 12 | import sys 13 | 14 | import echonest.remix.audio as audio 15 | 16 | usage = """ 17 | Usage: 18 | python quanta.py [e] 19 | 20 | Example: 21 | python quanta.py beats SingleLadies.mp3 SingleLadiesBeats.mp3 22 | 23 | The 'e' flag, inserts a silence equal in duration to the preceding audio quantum. 24 | Otherwise, each silence is one second long. 25 | """ 26 | 27 | ACCEPTED_UNITS = ["segments", "tatums", "beats", "bars", "sections"] 28 | 29 | def main(input_filename, output_filename, units, equal_silence): 30 | audio_file = audio.LocalAudioFile(input_filename) 31 | chunks = audio_file.analysis.__getattribute__(units) 32 | num_channels = audio_file.numChannels 33 | sample_rate = audio_file.sampleRate 34 | if equal_silence: 35 | new_shape = ((audio_file.data.shape[0] * 2) + 100000, 36 | audio_file.data.shape[1]) 37 | else: 38 | new_shape = (audio_file.data.shape[0]+(len(chunks) * 44100) + 10000, 39 | audio_file.data.shape[1]) 40 | out = audio.AudioData(shape=new_shape, sampleRate=sample_rate, numChannels=num_channels) 41 | 42 | for chunk in chunks: 43 | chunk_data = audio_file[chunk] 44 | if equal_silence: 45 | silence_shape = chunk_data.data.shape 46 | else: 47 | silence_shape = (44100, audio_file.data.shape[1]) 48 | silence = audio.AudioData(shape=silence_shape, sampleRate=sample_rate, numChannels=num_channels) 49 | silence.endindex = silence.data.shape[0] 50 | 51 | out.append(chunk_data) 52 | out.append(silence) 53 | out.encode(output_filename) 54 | 55 | if __name__ == '__main__': 56 | try: 57 | units = sys.argv[1] 58 | input_filename = sys.argv[2] 59 | output_filename = sys.argv[3] 60 | if len(sys.argv) == 5: 61 | equal_silence = True 62 | else: 63 | equal_silence = False 64 | except: 65 | print usage 66 | sys.exit(-1) 67 | if not units in ACCEPTED_UNITS: 68 | print usage 69 | sys.exit(-1) 70 | main(input_filename, output_filename, units, equal_silence) 71 | -------------------------------------------------------------------------------- /examples/reverse/reverse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | reverse.py 6 | 7 | Reverse the beats or segments of a song. 8 | 9 | Originally created by Robert Ochshorn on 2008-06-11. Refactored by 10 | Joshua Lifton 2008-09-07. 11 | """ 12 | 13 | import echonest.remix.audio as audio 14 | 15 | usage = """ 16 | Usage: 17 | python reverse.py 18 | 19 | Example: 20 | python reverse.py beats YouCanCallMeAl.mp3 AlMeCallCanYou.mp3 21 | """ 22 | 23 | def main(toReverse, inputFilename, outputFilename): 24 | audioFile = audio.LocalAudioFile(inputFilename) 25 | if toReverse == 'beats' : 26 | chunks = audioFile.analysis.beats 27 | elif toReverse == 'segments' : 28 | chunks = audioFile.analysis.segments 29 | else : 30 | print usage 31 | return 32 | chunks.reverse() 33 | reversedAudio = audio.getpieces(audioFile, chunks) 34 | reversedAudio.encode(outputFilename) 35 | 36 | if __name__ == '__main__': 37 | import sys 38 | try : 39 | toReverse = sys.argv[1] 40 | inputFilename = sys.argv[2] 41 | outputFilename = sys.argv[3] 42 | except : 43 | print usage 44 | sys.exit(-1) 45 | if not toReverse in ["beats", "segments"]: 46 | print usage 47 | sys.exit(-1) 48 | main(toReverse, inputFilename, outputFilename) 49 | -------------------------------------------------------------------------------- /examples/save/save.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | """ 4 | save.py 5 | 6 | Save an Echo Nest analysis as a local file. You can save analysis by using .save() 7 | You can then load them by simply calling audio.LocalAudioFile('the_file.analysis.en') 8 | 9 | Note that save() saves to the same location as the initial file, and 10 | creates a corresponding .wav file. Moving the .wav file will break things! 11 | 12 | By Thor Kell, 10-2012 13 | """ 14 | 15 | usage = """ 16 | Usage: 17 | python save.py 18 | 19 | Example: 20 | python save.py SaveMe.mp3 21 | """ 22 | 23 | import echonest.remix.audio as audio 24 | 25 | def main(input_filename): 26 | audiofile = audio.LocalAudioFile(input_filename) 27 | audiofile.save() 28 | print "Saved anaylsis for %s" % input_filename 29 | 30 | 31 | if __name__ == '__main__': 32 | import sys 33 | try: 34 | input_filename = sys.argv[1] 35 | except: 36 | print usage 37 | sys.exit(-1) 38 | main(input_filename) 39 | 40 | -------------------------------------------------------------------------------- /examples/selection/tonic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | tonic.py 6 | 7 | Digest all beats, tatums, or bars that start in the key of the song. 8 | Demonstrates content-based selection filtering via AudioQuantumLists 9 | 10 | Originally by Adam Lindsay, 2008-09-15. 11 | Refactored by Thor Kell, 2012-11-01 12 | """ 13 | import echonest.remix.audio as audio 14 | 15 | usage = """ 16 | Usage: 17 | python tonic.py 18 | 19 | Example: 20 | python tonic.py beats HereComesTheSun.mp3 HereComesTheTonic.mp3 21 | """ 22 | 23 | ACCEPTED_UNITS = ["tatums", "beats", "bars"] 24 | 25 | def main(units, inputFile, outputFile): 26 | audiofile = audio.LocalAudioFile(inputFile) 27 | tonic = audiofile.analysis.key['value'] 28 | 29 | chunks = audiofile.analysis.__getattribute__(units) 30 | 31 | # Get the segments 32 | all_segments = audiofile.analysis.segments 33 | 34 | # Find tonic segments 35 | tonic_segments = audio.AudioQuantumList(kind="segment") 36 | for segment in all_segments: 37 | pitches = segment.pitches 38 | if pitches.index(max(pitches)) == tonic: 39 | tonic_segments.append(segment) 40 | 41 | # Find each chunk that matches each segment 42 | out_chunks = audio.AudioQuantumList(kind=units) 43 | for chunk in chunks: 44 | for segment in tonic_segments: 45 | if chunk.start >= segment.start and segment.end >= chunk.start: 46 | out_chunks.append(chunk) 47 | break 48 | 49 | out = audio.getpieces(audiofile, out_chunks) 50 | out.encode(outputFile) 51 | 52 | if __name__ == '__main__': 53 | import sys 54 | try: 55 | units = sys.argv[-3] 56 | inputFilename = sys.argv[-2] 57 | outputFilename = sys.argv[-1] 58 | except: 59 | print usage 60 | sys.exit(-1) 61 | if not units in ACCEPTED_UNITS: 62 | print usage 63 | sys.exit(-1) 64 | main(units, inputFilename, outputFilename) 65 | -------------------------------------------------------------------------------- /examples/sorting/sorting.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env/python 2 | #encoding: utf=8 3 | """ 4 | sorting.py 5 | 6 | Sorts AudioQuanta (bars, beats, tatums, segments) by various qualities, and resynthesizes them. 7 | 8 | By Thor Kell, 2012-11-02 9 | """ 10 | import echonest.remix.audio as audio 11 | usage = """ 12 | python sorting.py [reverse] 13 | 14 | """ 15 | def main(units, key, input_filename, output_filename): 16 | audiofile = audio.LocalAudioFile(input_filename) 17 | chunks = audiofile.analysis.__getattribute__(units) 18 | 19 | # Define the sorting function 20 | if key == 'duration': 21 | def sorting_function(chunk): 22 | return chunk.duration 23 | 24 | if key == 'confidence': 25 | def sorting_function(chunk): 26 | if units != 'segments': 27 | return chunk.confidence 28 | else: 29 | # Segments have no confidence, so we grab confidence from the tatum 30 | return chunk.tatum.confidence 31 | 32 | if key == 'loudness': 33 | def sorting_function(chunk): 34 | return chunk.mean_loudness() 35 | 36 | sorted_chunks = sorted(chunks, key=sorting_function, reverse=reverse) 37 | 38 | out = audio.getpieces(audiofile, sorted_chunks) 39 | out.encode(output_filename) 40 | 41 | if __name__ == '__main__': 42 | import sys 43 | try: 44 | unit = sys.argv[1] 45 | key = sys.argv[2] 46 | input_filename = sys.argv[3] 47 | output_filename = sys.argv[4] 48 | if len(sys.argv) == 6 and sys.argv[5] == 'reverse': 49 | reverse = True 50 | else: 51 | reverse = False 52 | except: 53 | print usage 54 | sys.exit(-1) 55 | main(unit, key, input_filename, output_filename) 56 | -------------------------------------------------------------------------------- /examples/sorting/sorting_pitch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env/python 2 | #encoding: utf=8 3 | """ 4 | sorting_pitch.py 5 | 6 | Sorts AudioQuanta (bars, beats, tatums, segments) by the maximum pitch. 7 | Results can be modded by 0-11 to sort relative to C, C#, D, D#, etc. 8 | 9 | By Thor Kell, 2012-11-02 10 | """ 11 | 12 | import echonest.remix.audio as audio 13 | usage = """ 14 | python sorting_pitch.py <0-11> [reverse] 15 | 16 | """ 17 | def main(units, key, input_filename, output_filename): 18 | audiofile = audio.LocalAudioFile(input_filename) 19 | chunks = audiofile.analysis.__getattribute__(units) 20 | key = int(key) 21 | 22 | def sorting_function(chunk): 23 | pitches = chunk.mean_pitches() 24 | return pitches.index(max(pitches)) - key % 12 25 | 26 | sorted_chunks = sorted(chunks, key=sorting_function, reverse=reverse) 27 | 28 | out = audio.getpieces(audiofile, sorted_chunks) 29 | out.encode(output_filename) 30 | 31 | if __name__ == '__main__': 32 | import sys 33 | try: 34 | unit = sys.argv[1] 35 | key = sys.argv[2] 36 | input_filename = sys.argv[3] 37 | output_filename = sys.argv[4] 38 | if len(sys.argv) == 6 and sys.argv[5] == 'reverse': 39 | reverse = True 40 | else: 41 | reverse = False 42 | 43 | except: 44 | print usage 45 | sys.exit(-1) 46 | main(unit, key, input_filename, output_filename) 47 | -------------------------------------------------------------------------------- /examples/sorting/sorting_timbre.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env/python 2 | #encoding: utf=8 3 | """ 4 | sorting_timbre.py 5 | 6 | Sorts AudioQuanta (bars, beats, tatums, segments) by timbral bin (0-11). 7 | By Thor Kell, 2012-11-14 8 | """ 9 | 10 | import echonest.remix.audio as audio 11 | usage = """ 12 | python sorting.py <0-11> [reverse] 13 | 14 | """ 15 | def main(units, timbre_bin, input_filename, output_filename): 16 | audiofile = audio.LocalAudioFile(input_filename) 17 | chunks = audiofile.analysis.__getattribute__(units) 18 | timbre_bin = int(timbre_bin) 19 | 20 | # For any chunk, return the timbre value of the given bin 21 | def sorting_function(chunk): 22 | timbre = chunk.mean_timbre() 23 | return timbre[timbre_bin] 24 | 25 | sorted_chunks = sorted(chunks, key=sorting_function, reverse=reverse) 26 | 27 | import pdb 28 | #pdb.set_trace() 29 | 30 | out = audio.getpieces(audiofile, sorted_chunks) 31 | out.encode(output_filename) 32 | 33 | if __name__ == '__main__': 34 | import sys 35 | try: 36 | unit = sys.argv[1] 37 | timbre_bin = sys.argv[2] 38 | input_filename = sys.argv[3] 39 | output_filename = sys.argv[4] 40 | if len(sys.argv) == 6 and sys.argv[5] == 'reverse': 41 | reverse = True 42 | else: 43 | reverse = False 44 | 45 | except: 46 | print usage 47 | sys.exit(-1) 48 | main(unit, timbre_bin, input_filename, output_filename) 49 | -------------------------------------------------------------------------------- /examples/step/step-by-pitch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | step.py 6 | 7 | For each bar, take one of the nearest (in timbre) beats 8 | to the last beat, chosen from all of the beats that fall 9 | on the one. Repeat for all the twos, etc. 10 | 11 | The variation parameter, (_v_) means there's a roughly 12 | one in _v_ chance that the actual next beat is chosen. The 13 | length is the length in bars you want it to go on. 14 | 15 | Originally by Adam Lindsay, 2009-03-10. 16 | Refactored by Thor Kell, 2012-12-12 17 | """ 18 | 19 | import random 20 | import numpy 21 | import echonest.remix.audio as audio 22 | 23 | usage = """ 24 | Usage: 25 | python step.py inputFilename outputFilename [variation [length]] 26 | 27 | variation is the number of near candidates chosen from. [default=4] 28 | length is the number of bars in the final product. [default=40] 29 | 30 | Example: 31 | python step.py Discipline.mp3 Undisciplined.mp3 4 100 32 | """ 33 | 34 | def main(infile, outfile, choices=4, bars=40): 35 | audiofile = audio.LocalAudioFile(infile) 36 | meter = audiofile.analysis.time_signature['value'] 37 | fade_in = audiofile.analysis.end_of_fade_in 38 | fade_out = audiofile.analysis.start_of_fade_out 39 | 40 | beats = [] 41 | for b in audiofile.analysis.beats: 42 | if b.start > fade_in or b.end < fade_out: 43 | beats.append(b) 44 | output = audio.AudioQuantumList() 45 | 46 | beat_array = [] 47 | for m in range(meter): 48 | metered_beats = [] 49 | for b in beats: 50 | if beats.index(b) % meter == m: 51 | metered_beats.append(b) 52 | beat_array.append(metered_beats) 53 | 54 | # Always start with the first beat 55 | output.append(beat_array[0][0]); 56 | for x in range(1, bars * meter): 57 | meter_index = x % meter 58 | next_candidates = beat_array[meter_index] 59 | 60 | def sorting_function(chunk, target_chunk=output[-1]): 61 | timbre = chunk.mean_pitches() 62 | target_timbre = target_chunk.mean_pitches() 63 | timbre_distance = numpy.linalg.norm(numpy.array(timbre) - numpy.array(target_timbre)) 64 | return timbre_distance 65 | 66 | next_candidates = sorted(next_candidates, key=sorting_function) 67 | next_index = random.randint(0, min(choices, len(next_candidates) -1 )) 68 | output.append(next_candidates[next_index]) 69 | 70 | out = audio.getpieces(audiofile, output) 71 | out.encode(outfile) 72 | 73 | 74 | if __name__ == '__main__': 75 | import sys 76 | try: 77 | inputFilename = sys.argv[1] 78 | outputFilename = sys.argv[2] 79 | if len(sys.argv) > 3: 80 | variation = int(sys.argv[3]) 81 | else: 82 | variation = 4 83 | if len(sys.argv) > 4: 84 | length = int(sys.argv[4]) 85 | else: 86 | length = 40 87 | except: 88 | print usage 89 | sys.exit(-1) 90 | main(inputFilename, outputFilename, variation, length) 91 | -------------------------------------------------------------------------------- /examples/step/step-by-section.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | step.py 6 | 7 | For each bar, take one of the nearest (in timbre) beats 8 | to the last beat, chosen from all of the beats that fall 9 | on the one in this section. Repeat for all the twos, etc. 10 | 11 | This version divides things by section, retaining the 12 | structure and approximate length of the original. The 13 | variation parameter, (_v_) means there's a roughly 14 | one in _v_ chance that the actual next beat is chosen. A 15 | musical M-x dissociated-press. 16 | 17 | Originally by Adam Lindsay, 2009-03-10. 18 | Refactored by Thor Kell, 2012-12-12 19 | """ 20 | 21 | import random 22 | import numpy 23 | import echonest.remix.audio as audio 24 | 25 | usage = """ 26 | Usage: 27 | python step.py inputFilename outputFilename [variation] 28 | 29 | variation is the number of near candidates chosen from. [default=4] 30 | 31 | Example: 32 | python step.py Discipline.mp3 Undisciplined.mp3 4 33 | """ 34 | 35 | def main(infile, outfile, choices=4): 36 | audiofile = audio.LocalAudioFile(infile) 37 | meter = audiofile.analysis.time_signature['value'] 38 | sections = audiofile.analysis.sections 39 | output = audio.AudioQuantumList() 40 | 41 | for section in sections: 42 | beats = [] 43 | bars = section.children() 44 | for bar in bars: 45 | beats.extend(bar.children()) 46 | 47 | beat_array = [] 48 | for m in range(meter): 49 | metered_beats = [] 50 | for b in beats: 51 | if beats.index(b) % meter == m: 52 | metered_beats.append(b) 53 | beat_array.append(metered_beats) 54 | 55 | # Always start with the first beat 56 | output.append(beat_array[0][0]); 57 | for x in range(1, len(bars) * meter): 58 | meter_index = x % meter 59 | next_candidates = beat_array[meter_index] 60 | 61 | def sorting_function(chunk, target_chunk=output[-1]): 62 | timbre = chunk.mean_timbre() 63 | target_timbre = target_chunk.mean_timbre() 64 | timbre_distance = numpy.linalg.norm(numpy.array(timbre) - numpy.array(target_timbre)) 65 | return timbre_distance 66 | 67 | next_candidates = sorted(next_candidates, key=sorting_function) 68 | next_index = random.randint(0, min(choices, len(next_candidates) - 1)) 69 | output.append(next_candidates[next_index]) 70 | 71 | out = audio.getpieces(audiofile, output) 72 | out.encode(outfile) 73 | 74 | 75 | if __name__ == '__main__': 76 | import sys 77 | try: 78 | inputFilename = sys.argv[1] 79 | outputFilename = sys.argv[2] 80 | if len(sys.argv) > 3: 81 | variation = int(sys.argv[3]) 82 | else: 83 | variation = 4 84 | except: 85 | print usage 86 | sys.exit(-1) 87 | main(inputFilename, outputFilename, variation) 88 | -------------------------------------------------------------------------------- /examples/step/step.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | step.py 6 | 7 | For each bar, take one of the nearest (in timbre) beats 8 | to the last beat, chosen from all of the beats that fall 9 | on the one. Repeat for all the twos, etc. 10 | 11 | The variation parameter, (_v_) means there's a roughly 12 | one in _v_ chance that the actual next beat is chosen. The 13 | length is the length in bars you want it to go on. 14 | 15 | Originally by Adam Lindsay, 2009-03-10. 16 | Refactored by Thor Kell, 2012-12-12 17 | """ 18 | 19 | import random 20 | import numpy 21 | import echonest.remix.audio as audio 22 | 23 | usage = """ 24 | Usage: 25 | python step.py inputFilename outputFilename [variation [length]] 26 | 27 | variation is the number of near candidates chosen from. [default=4] 28 | length is the number of bars in the final product. [default=40] 29 | 30 | Example: 31 | python step.py Discipline.mp3 Undisciplined.mp3 4 100 32 | """ 33 | 34 | def main(infile, outfile, choices=4, bars=40): 35 | audiofile = audio.LocalAudioFile(infile) 36 | meter = audiofile.analysis.time_signature['value'] 37 | fade_in = audiofile.analysis.end_of_fade_in 38 | fade_out = audiofile.analysis.start_of_fade_out 39 | 40 | beats = [] 41 | for b in audiofile.analysis.beats: 42 | if b.start > fade_in or b.end < fade_out: 43 | beats.append(b) 44 | output = audio.AudioQuantumList() 45 | 46 | beat_array = [] 47 | for m in range(meter): 48 | metered_beats = [] 49 | for b in beats: 50 | if beats.index(b) % meter == m: 51 | metered_beats.append(b) 52 | beat_array.append(metered_beats) 53 | 54 | # Always start with the first beat 55 | output.append(beat_array[0][0]); 56 | for x in range(1, bars * meter): 57 | meter_index = x % meter 58 | next_candidates = beat_array[meter_index] 59 | 60 | def sorting_function(chunk, target_chunk=output[-1]): 61 | timbre = chunk.mean_timbre() 62 | target_timbre = target_chunk.mean_timbre() 63 | timbre_distance = numpy.linalg.norm(numpy.array(timbre) - numpy.array(target_timbre)) 64 | return timbre_distance 65 | 66 | next_candidates = sorted(next_candidates, key=sorting_function) 67 | next_index = random.randint(0, min(choices, len(next_candidates) - 1)) 68 | output.append(next_candidates[next_index]) 69 | 70 | out = audio.getpieces(audiofile, output) 71 | out.encode(outfile) 72 | 73 | 74 | if __name__ == '__main__': 75 | import sys 76 | try: 77 | inputFilename = sys.argv[1] 78 | outputFilename = sys.argv[2] 79 | if len(sys.argv) > 3: 80 | variation = int(sys.argv[3]) 81 | else: 82 | variation = 4 83 | if len(sys.argv) > 4: 84 | length = int(sys.argv[4]) 85 | else: 86 | length = 40 87 | except: 88 | print usage 89 | sys.exit(-1) 90 | main(inputFilename, outputFilename, variation, length) 91 | -------------------------------------------------------------------------------- /examples/stretch/beatshift.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | beatshift.py 5 | 6 | Pitchshift each beat based on its position in the bar. 7 | Beat one is unchanged, beat two is shifted down one half step, 8 | beat three is shifted down two half steps, etc. 9 | 10 | Created by Ben Lacker on 2009-06-24. 11 | Refactored by Thor Kell on 2013-03-06. 12 | """ 13 | import numpy 14 | import os 15 | import random 16 | import sys 17 | import time 18 | 19 | from echonest.remix import audio, modify 20 | 21 | usage = """ 22 | Usage: 23 | python beatshift.py 24 | Exampel: 25 | python beatshift.py CryMeARiver.mp3 CryMeAShifty.mp3 26 | """ 27 | 28 | def main(input_filename, output_filename): 29 | soundtouch = modify.Modify() 30 | audiofile = audio.LocalAudioFile(input_filename) 31 | beats = audiofile.analysis.beats 32 | out_shape = (len(audiofile.data),) 33 | out_data = audio.AudioData(shape=out_shape, numChannels=1, sampleRate=44100) 34 | 35 | for i, beat in enumerate(beats): 36 | data = audiofile[beat].data 37 | number = beat.local_context()[0] % 12 38 | new_beat = soundtouch.shiftPitchSemiTones(audiofile[beat], number*-1) 39 | out_data.append(new_beat) 40 | 41 | out_data.encode(output_filename) 42 | 43 | if __name__ == '__main__': 44 | import sys 45 | try: 46 | input_filename = sys.argv[1] 47 | output_filename = sys.argv[2] 48 | except: 49 | print usage 50 | sys.exit(-1) 51 | main(input_filename, output_filename) 52 | -------------------------------------------------------------------------------- /examples/stretch/cycle_dirac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | cycle.py 5 | 6 | Periodically time-compress and time-stretch the beats in each measure. 7 | Each measure starts fast and ends slow. 8 | 9 | Created by Thor Kell on 2013-05-06, based on code by Ben Lacker. 10 | """ 11 | import math 12 | import os 13 | import sys 14 | import dirac 15 | from echonest.remix import audio 16 | 17 | usage = """ 18 | Usage: 19 | python cycle.py 20 | Exampel: 21 | python cycle.py CryMeARiver.mp3 CryCycle.mp3 22 | """ 23 | 24 | def main(input_filename, output_filename): 25 | audiofile = audio.LocalAudioFile(input_filename) 26 | bars = audiofile.analysis.bars 27 | collect = [] 28 | 29 | for bar in bars: 30 | bar_ratio = (bars.index(bar) % 4) / 2.0 31 | beats = bar.children() 32 | for beat in beats: 33 | beat_index = beat.local_context()[0] 34 | ratio = beat_index / 2.0 + 0.5 35 | ratio = ratio + bar_ratio # dirac can't compress by less than 0.5! 36 | beat_audio = beat.render() 37 | scaled_beat = dirac.timeScale(beat_audio.data, ratio) 38 | ts = audio.AudioData(ndarray=scaled_beat, shape=scaled_beat.shape, 39 | sampleRate=audiofile.sampleRate, numChannels=scaled_beat.shape[1]) 40 | collect.append(ts) 41 | 42 | out = audio.assemble(collect, numChannels=2) 43 | out.encode(output_filename) 44 | 45 | if __name__ == '__main__': 46 | import sys 47 | try: 48 | input_filename = sys.argv[1] 49 | output_filename = sys.argv[2] 50 | except: 51 | print usage 52 | sys.exit(-1) 53 | main(input_filename, output_filename) 54 | 55 | -------------------------------------------------------------------------------- /examples/stretch/cycle_soundtouch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | cycle.py 5 | 6 | Periodically time-compress and time-stretch the beats in each measure. 7 | Each measure starts fast and ends slow. 8 | 9 | Currently there is a bug with soundtouch. 10 | Please see cycle_dirac, and use dirac for time stretching. 11 | 12 | Created by Ben Lacker on 2009-06-16. 13 | Refactored by Thor Kell on 2013-03-06. 14 | """ 15 | import math 16 | import os 17 | import sys 18 | 19 | from echonest.remix import audio, modify 20 | 21 | usage = """ 22 | Usage: 23 | python cycle.py 24 | Exampel: 25 | python cycle.py CryMeARiver.mp3 CryCycle.mp3 26 | """ 27 | 28 | def main(input_filename, output_filename): 29 | 30 | audiofile = audio.LocalAudioFile(input_filename) 31 | soundtouch = modify.Modify() 32 | beats = audiofile.analysis.beats 33 | collect = [] 34 | 35 | for beat in beats: 36 | context = beat.local_context() 37 | ratio = (math.cos(math.pi * 2 * context[0]/float(context[1])) / 2) + 1 38 | new = soundtouch.shiftTempo(audiofile[beat], ratio) 39 | collect.append(new) 40 | 41 | out = audio.assemble(collect) 42 | out.encode(output_filename) 43 | 44 | if __name__ == '__main__': 45 | import sys 46 | try: 47 | input_filename = sys.argv[1] 48 | output_filename = sys.argv[2] 49 | except: 50 | print usage 51 | sys.exit(-1) 52 | main(input_filename, output_filename) 53 | -------------------------------------------------------------------------------- /examples/stretch/simple_stretch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | simple_stretch.py 5 | 6 | Compress or exapand the entire track, beat by beat. 7 | 8 | Created by Thor Kell on 2013-11-18 9 | """ 10 | import math 11 | import os 12 | import sys 13 | import dirac 14 | from echonest.remix import audio 15 | 16 | usage = """ 17 | Usage: 18 | python simple_stretch.py 19 | Example: 20 | python simple_stretch.py CryMeARiver.mp3 StrechMeARiver.mp3 21 | Notes: 22 | Ratio must be greater than 0.5 23 | """ 24 | 25 | def main(input_filename, output_filename, ratio): 26 | audiofile = audio.LocalAudioFile(input_filename) 27 | beats = audiofile.analysis.beats 28 | collect = [] 29 | 30 | for beat in beats: 31 | beat_audio = beat.render() 32 | scaled_beat = dirac.timeScale(beat_audio.data, ratio) 33 | ts = audio.AudioData(ndarray=scaled_beat, shape=scaled_beat.shape, 34 | sampleRate=audiofile.sampleRate, numChannels=scaled_beat.shape[1]) 35 | collect.append(ts) 36 | 37 | out = audio.assemble(collect, numChannels=2) 38 | out.encode(output_filename) 39 | 40 | if __name__ == '__main__': 41 | import sys 42 | try: 43 | input_filename = sys.argv[1] 44 | output_filename = sys.argv[2] 45 | ratio = float(sys.argv[3]) 46 | if ratio < 0.5: 47 | print "Error: Ratio must be greater than 0.5!" 48 | sys.exit(-1) 49 | except: 50 | print usage 51 | sys.exit(-1) 52 | main(input_filename, output_filename, ratio) 53 | -------------------------------------------------------------------------------- /examples/videx/vafroma.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | vafroma.py 6 | 7 | Re-synthesize video A using the segments of song A. 8 | 9 | By Ben Lacker, P. Lamere 10 | """ 11 | import numpy 12 | import sys 13 | import time 14 | import echonest.remix.audio as audio 15 | import echonest.remix.video as video 16 | import echonest.remix.modify as modify 17 | 18 | usage=""" 19 | Usage: 20 | python vafroma.py 21 | 22 | Example: 23 | python vafroma.py BillieJeanMusicVideo.mp4 24 | """ 25 | 26 | 27 | dur_weight = 1000 28 | #dur_weight = 100 29 | timbre_weight = .001 30 | pitch_weight = 10 31 | loudness_weight = 1 32 | 33 | class AfromA(object): 34 | def __init__(self, input_filename, output_filename): 35 | self.av = video.loadav(input_filename) 36 | self.segs = self.av.audio.analysis.segments 37 | self.output_filename = output_filename 38 | 39 | def get_distance_from(self, seg): 40 | distances = [] 41 | for a in self.segs: 42 | ddur = numpy.square(seg.duration - a.duration) 43 | dloud = numpy.square(seg.loudness_max - a.loudness_max) 44 | 45 | timbre_diff = numpy.subtract(seg.timbre, a.timbre) 46 | dtimbre = (numpy.sum(numpy.square(timbre_diff))) 47 | 48 | pitch_diff = numpy.subtract(seg.pitches, a.pitches) 49 | dpitch = (numpy.sum(numpy.square(pitch_diff))) 50 | 51 | #print dur_weight * ddur, timbre_weight * dtimbre, \ 52 | # pitch_weight * dpitch, loudness_weight * dloud 53 | distance = dur_weight * ddur \ 54 | + loudness_weight * dloud \ 55 | + timbre_weight * dtimbre \ 56 | + pitch_weight * dpitch; 57 | distances.append(distance) 58 | 59 | return distances 60 | 61 | 62 | def run(self): 63 | st = modify.Modify() 64 | collect = audio.AudioQuantumList() 65 | for a in self.segs: 66 | seg_index = a.absolute_context()[0] 67 | 68 | distances = self.get_distance_from(a) 69 | 70 | distances[seg_index] = sys.maxint 71 | 72 | match_index = distances.index(min(distances)) 73 | match = self.segs[match_index] 74 | print seg_index, match_index 75 | # make the length of the new seg match the length 76 | # of the old seg 77 | collect.append(match) 78 | out = video.getpieces(self.av, collect) 79 | out.save(self.output_filename) 80 | 81 | def main(): 82 | try: 83 | input_filename = sys.argv[1] 84 | if len(sys.argv) > 2: 85 | output_filename = sys.argv[2] 86 | else: 87 | output_filename = "aa_" + input_filename 88 | except: 89 | print usage 90 | sys.exit(-1) 91 | AfromA(input_filename, output_filename).run() 92 | 93 | 94 | if __name__=='__main__': 95 | tic = time.time() 96 | main() 97 | toc = time.time() 98 | print "Elapsed time: %.3f sec" % float(toc-tic) 99 | -------------------------------------------------------------------------------- /examples/videx/vafroma2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | vafroma2.py 6 | 7 | Re-synthesize video A using the segments of song A. 8 | Same as vafroma.py, but avoids re-using segments. 9 | 10 | By Ben Lacker, P. Lamere 11 | """ 12 | import numpy 13 | import sys 14 | import time 15 | import echonest.remix.audio as audio 16 | import echonest.remix.video as video 17 | import echonest.remix.modify as modify 18 | 19 | usage=""" 20 | Usage: 21 | python vafroma2.py 22 | 23 | Example: 24 | python vafroma2.py BillieJeanMusicVideo.mp4 25 | """ 26 | 27 | 28 | dur_weight = 1000 29 | #dur_weight = 100 30 | timbre_weight = .001 31 | pitch_weight = 10 32 | loudness_weight = 1 33 | 34 | class AfromA(object): 35 | def __init__(self, input_filename, output_filename): 36 | self.av = video.loadav(input_filename) 37 | self.segs = self.av.audio.analysis.segments 38 | self.output_filename = output_filename 39 | 40 | def get_distance_from(self, seg): 41 | distances = [] 42 | for a in self.segs: 43 | ddur = numpy.square(seg.duration - a.duration) 44 | dloud = numpy.square(seg.loudness_max - a.loudness_max) 45 | 46 | timbre_diff = numpy.subtract(seg.timbre, a.timbre) 47 | dtimbre = (numpy.sum(numpy.square(timbre_diff))) 48 | 49 | pitch_diff = numpy.subtract(seg.pitches, a.pitches) 50 | dpitch = (numpy.sum(numpy.square(pitch_diff))) 51 | 52 | #print dur_weight * ddur, timbre_weight * dtimbre, \ 53 | # pitch_weight * dpitch, loudness_weight * dloud 54 | distance = dur_weight * ddur \ 55 | + loudness_weight * dloud \ 56 | + timbre_weight * dtimbre \ 57 | + pitch_weight * dpitch; 58 | distances.append(distance) 59 | 60 | return distances 61 | 62 | 63 | def run(self): 64 | st = modify.Modify() 65 | collect = audio.AudioQuantumList() 66 | used = [] 67 | for a in self.segs: 68 | seg_index = a.absolute_context()[0] 69 | 70 | distances = self.get_distance_from(a) 71 | 72 | distances[seg_index] = sys.maxint 73 | for u in used: 74 | distances[u] = sys.maxint 75 | 76 | match_index = distances.index(min(distances)) 77 | match = self.segs[match_index] 78 | print seg_index, match_index 79 | # make the length of the new seg match the length 80 | # of the old seg 81 | collect.append(match) 82 | used.append(match_index) 83 | out = video.getpieces(self.av, collect) 84 | out.save(self.output_filename) 85 | 86 | def main(): 87 | try: 88 | input_filename = sys.argv[1] 89 | if len(sys.argv) > 2: 90 | output_filename = sys.argv[2] 91 | else: 92 | output_filename = "aa2_" + input_filename 93 | except: 94 | print usage 95 | sys.exit(-1) 96 | AfromA(input_filename, output_filename).run() 97 | 98 | 99 | if __name__=='__main__': 100 | tic = time.time() 101 | main() 102 | toc = time.time() 103 | print "Elapsed time: %.3f sec" % float(toc-tic) 104 | -------------------------------------------------------------------------------- /examples/videx/vafroma3.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/env python 3 | # encoding: utf=8 4 | 5 | """ 6 | vafroma3.py 7 | 8 | Re-synthesize video A using the segments of song A. 9 | Tries to use longer sequences of video by boosting the distance neighbors of similar segments. 10 | 11 | By Ben Lacker, P. Lamere 12 | """ 13 | import numpy 14 | import sys 15 | import time 16 | import echonest.remix.audio as audio 17 | import echonest.remix.video as video 18 | import echonest.remix.modify as modify 19 | 20 | usage=""" 21 | Usage: 22 | python vafroma3.py 23 | 24 | Example: 25 | python vafroma3.py BillieJeanMusicVideo.mp4 26 | """ 27 | 28 | 29 | dur_weight = 1000 30 | #dur_weight = 100 31 | timbre_weight = .001 32 | pitch_weight = 10 33 | loudness_weight = 1 34 | 35 | class AfromA(object): 36 | def __init__(self, input_filename, output_filename): 37 | self.av = video.loadav(input_filename) 38 | self.segs = self.av.audio.analysis.segments 39 | self.output_filename = output_filename 40 | 41 | def get_distance_from(self, seg): 42 | distances = [] 43 | for a in self.segs: 44 | ddur = numpy.square(seg.duration - a.duration) 45 | dloud = numpy.square(seg.loudness_max - a.loudness_max) 46 | 47 | timbre_diff = numpy.subtract(seg.timbre, a.timbre) 48 | dtimbre = (numpy.sum(numpy.square(timbre_diff))) 49 | 50 | pitch_diff = numpy.subtract(seg.pitches, a.pitches) 51 | dpitch = (numpy.sum(numpy.square(pitch_diff))) 52 | 53 | #print dur_weight * ddur, timbre_weight * dtimbre, \ 54 | # pitch_weight * dpitch, loudness_weight * dloud 55 | distance = dur_weight * ddur \ 56 | + loudness_weight * dloud \ 57 | + timbre_weight * dtimbre \ 58 | + pitch_weight * dpitch; 59 | distances.append(distance) 60 | 61 | return distances 62 | 63 | 64 | def run(self): 65 | st = modify.Modify() 66 | last_index = 0 67 | collect = audio.AudioQuantumList() 68 | match_index = -1 69 | for a in self.segs: 70 | seg_index = a.absolute_context()[0] 71 | 72 | distances = self.get_distance_from(a) 73 | 74 | distances[seg_index] = sys.maxint 75 | 76 | if match_index < len(distances) -1: 77 | distances[match_index + 1] *= .3 78 | 79 | match_index = distances.index(min(distances)) 80 | match = self.segs[match_index] 81 | print seg_index, match_index 82 | # make the length of the new seg match the length 83 | # of the old seg 84 | collect.append(match) 85 | out = video.getpieces(self.av, collect) 86 | out.save(self.output_filename) 87 | 88 | def main(): 89 | try: 90 | input_filename = sys.argv[1] 91 | if len(sys.argv) > 2: 92 | output_filename = sys.argv[2] 93 | else: 94 | output_filename = "aa3_" + input_filename 95 | except: 96 | print usage 97 | sys.exit(-1) 98 | AfromA(input_filename, output_filename).run() 99 | 100 | 101 | if __name__=='__main__': 102 | tic = time.time() 103 | main() 104 | toc = time.time() 105 | print "Elapsed time: %.3f sec" % float(toc-tic) 106 | -------------------------------------------------------------------------------- /examples/videx/vdissoc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | vdissoc.py 6 | 7 | The video version of step-by-section.py. 8 | 9 | For each bar, take one of the nearest (in timbre) beats 10 | to the last beat, chosen from all of the beats that fall 11 | on the one in this section. Repeat for all the twos, etc. 12 | 13 | This version divides things by section, retaining the 14 | structure and approximate length of the original. The 15 | variation parameter, (_v_) means there's a roughly 16 | one in _v_ chance that the actual next beat is chosen. A 17 | musical M-x dissociated-press. 18 | 19 | Originally by Adam Lindsay, 2009-06-27. 20 | Refactored by Thor Kell, 2012-15-12 21 | """ 22 | import random 23 | import numpy 24 | from echonest.remix import video, audio 25 | 26 | usage = """ 27 | Usage: 28 | python vdissoc.py inputFilenameOrUrl outputFilename [variation] 29 | 30 | variation is the number of near candidates chosen from. [default=4] 31 | 32 | Example: 33 | python vdissoc.py 'http://www.youtube.com/watch?v=Es7mk19wMrk' Seventh.mp4 34 | """ 35 | def main(infile, outfile, choices=4): 36 | if infile.startswith("http://"): 37 | av = video.loadavfromyoutube(infile) 38 | else: 39 | av = video.loadav(infile) 40 | 41 | meter = av.audio.analysis.time_signature['value'] 42 | sections = av.audio.analysis.sections 43 | output = audio.AudioQuantumList() 44 | 45 | for section in sections: 46 | beats = [] 47 | bars = section.children() 48 | for bar in bars: 49 | beats.extend(bar.children()) 50 | 51 | if not bars or not beats: 52 | continue 53 | 54 | beat_array = [] 55 | for m in range(meter): 56 | metered_beats = [] 57 | for b in beats: 58 | if beats.index(b) % meter == m: 59 | metered_beats.append(b) 60 | beat_array.append(metered_beats) 61 | 62 | # Always start with the first beat 63 | output.append(beat_array[0][0]); 64 | for x in range(1, len(bars) * meter): 65 | meter_index = x % meter 66 | next_candidates = beat_array[meter_index] 67 | 68 | def sorting_function(chunk, target_chunk=output[-1]): 69 | timbre = chunk.mean_timbre() 70 | target_timbre = target_chunk.mean_timbre() 71 | timbre_distance = numpy.linalg.norm(numpy.array(timbre) - numpy.array(target_timbre)) 72 | return timbre_distance 73 | 74 | next_candidates = sorted(next_candidates, key=sorting_function) 75 | next_index = random.randint(0, min(choices, len(next_candidates) - 1)) 76 | output.append(next_candidates[next_index]) 77 | 78 | out = video.getpieces(av, output) 79 | out.save(outfile) 80 | 81 | if __name__ == '__main__': 82 | import sys 83 | try: 84 | inputFilename = sys.argv[1] 85 | outputFilename = sys.argv[2] 86 | if len(sys.argv) > 3: 87 | variation = int(sys.argv[3]) 88 | else: 89 | variation = 4 90 | except: 91 | print usage 92 | sys.exit(-1) 93 | main(inputFilename, outputFilename, variation) 94 | -------------------------------------------------------------------------------- /examples/videx/vone.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | vone.py 5 | 6 | Created by Ben Lacker on 2009-06-19. 7 | Copyright (c) 2009 __MyCompanyName__. All rights reserved. 8 | """ 9 | 10 | import sys 11 | import os 12 | from echonest.remix import audio, video 13 | 14 | usage = """ 15 | Usage: 16 | python vone.py 17 | 18 | Example: 19 | python vone.py EverythingIsOnTheOne.mpg EverythingIsReallyOnTheOne.mpg 20 | """ 21 | 22 | 23 | def main(input_filename, output_filename): 24 | if input_filename.startswith("http://") or input_filename.startswith("https://"): 25 | av = video.loadavfromyoutube(input_filename) 26 | else: 27 | av = video.loadav(input_filename) 28 | collect = audio.AudioQuantumList() 29 | for bar in av.audio.analysis.bars: 30 | collect.append(bar.children()[0]) 31 | out = video.getpieces(av, collect) 32 | out.save(output_filename) 33 | 34 | 35 | if __name__ == '__main__': 36 | try: 37 | input_filename = sys.argv[1] 38 | output_filename = sys.argv[2] 39 | except: 40 | print usage 41 | sys.exit(-1) 42 | main(input_filename, output_filename) 43 | -------------------------------------------------------------------------------- /examples/videx/vreverse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | vreverse.py 5 | 6 | Created by Ben Lacker on 2009-06-19. 7 | Copyright (c) 2009 __MyCompanyName__. All rights reserved. 8 | """ 9 | 10 | import sys 11 | import os 12 | 13 | from echonest.remix import video 14 | 15 | usage = """ 16 | Usage: 17 | python vreverse.py 18 | 19 | Example: 20 | python vreverse.py beats YouCanCallMeAl.mpg AlMeCallCanYou.mpg 21 | """ 22 | 23 | 24 | def main(toReverse, inputFilename, outputFilename): 25 | if inputFilename.startswith("http://"): 26 | av = video.loadavfromyoutube(inputFilename) 27 | else: 28 | av = video.loadav(inputFilename) 29 | if toReverse == 'tatums': 30 | chunks = av.audio.analysis.tatums 31 | elif toReverse == 'beats': 32 | chunks = av.audio.analysis.beats 33 | chunks.reverse() 34 | out = video.getpieces(av, chunks) 35 | out.save(outputFilename) 36 | 37 | if __name__ == '__main__': 38 | try : 39 | toReverse = sys.argv[1] 40 | inputFilename = sys.argv[2] 41 | outputFilename = sys.argv[3] 42 | except : 43 | print usage 44 | sys.exit(-1) 45 | if not toReverse in ["beats", "tatums"]: 46 | print usage 47 | sys.exit(-1) 48 | main(toReverse, inputFilename, outputFilename) 49 | -------------------------------------------------------------------------------- /external/cAction/setup.py: -------------------------------------------------------------------------------- 1 | # created 5/11/2010 by Jason 2 | from distutils.core import setup, Extension 3 | import os, sys 4 | import numpy 5 | 6 | cAction = Extension("cAction", 7 | sources = ['actionmodule.cpp'], 8 | extra_compile_args = [], 9 | include_dirs = [numpy.get_include(), numpy.get_numarray_include()], 10 | depends=[__file__] # force rebuild whenever this script is changed. 11 | ) 12 | 13 | setup( name="cAction", 14 | version = '0.1', 15 | description = 'c implementation of algorithms from action.py', 16 | author = 'Jason Sundram', 17 | author_email = 'jason@echonest.com', 18 | url = 'http://code.echonest.com/p/echo-nest-remix', 19 | ext_modules=[cAction], 20 | requires=['numpy'] 21 | ) 22 | 23 | -------------------------------------------------------------------------------- /external/en-ffmpeg/mac/en-ffmpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/en-ffmpeg/mac/en-ffmpeg -------------------------------------------------------------------------------- /external/en-ffmpeg/win/en-ffmpeg.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/en-ffmpeg/win/en-ffmpeg.exe -------------------------------------------------------------------------------- /external/pydirac225/DIRAC LE License Agreement.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pydirac225/DIRAC LE License Agreement.txt -------------------------------------------------------------------------------- /external/pydirac225/libs/Darwin/libDirac.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pydirac225/libs/Darwin/libDirac.a -------------------------------------------------------------------------------- /external/pydirac225/libs/Linux/libDirac.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pydirac225/libs/Linux/libDirac.a -------------------------------------------------------------------------------- /external/pydirac225/libs/Linux/libDirac64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pydirac225/libs/Linux/libDirac64.a -------------------------------------------------------------------------------- /external/pydirac225/libs/Windows/Dirac.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pydirac225/libs/Windows/Dirac.lib -------------------------------------------------------------------------------- /external/pydirac225/libs/Windows/DiracLE.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pydirac225/libs/Windows/DiracLE.dll -------------------------------------------------------------------------------- /external/pydirac225/setup.py: -------------------------------------------------------------------------------- 1 | # created 4/21/2010 by Jason 2 | # http://docs.python.org/extending/building.html 3 | from distutils.core import setup, Extension 4 | import os 5 | import numpy 6 | 7 | platform = os.uname()[0] if hasattr(os, 'uname') else 'Windows' 8 | link_args = ['-framework', 'Carbon'] if platform == 'Darwin' else [] 9 | 10 | dirac = Extension( "dirac", 11 | sources = ['diracmodule.cpp', 'source/Dirac_LE.cpp'], 12 | extra_compile_args = [], 13 | include_dirs = ['source', numpy.get_include()], 14 | libraries = ['Dirac'], 15 | library_dirs = [os.path.join('libs', platform)], 16 | extra_link_args = link_args, 17 | depends=[__file__] # force rebuild whenever this script is changed. 18 | ) 19 | 20 | setup( name="dirac", 21 | version = '0.2', 22 | description = 'Python interface to Dirac LE', 23 | author = 'Tristan Jehan', 24 | author_email = 'tristan@echonest.com', 25 | url = 'http://code.echonest.com/p/echo-nest-remix', 26 | ext_modules=[dirac], 27 | requires=['numpy'] 28 | ) 29 | -------------------------------------------------------------------------------- /external/pydirac225/source/Dirac_LE.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dirac_LE.h 3 | * Dirac_LE_Lib 4 | * 5 | * Created by Tristan Jehan on 4/15/10. 6 | * Copyright 2010 The Echo Nest. All rights reserved. 7 | * 8 | * IMPORTANT: This file and its contents are subject to the terms set forth in the 9 | * "License Agreement.txt" file that accompanies this distribution. 10 | * 11 | * Copyright © 2005-2010 Stephan M. Bernsee, http://www.dspdimension.com. All Rights Reserved 12 | */ 13 | 14 | #include "Dirac.h" 15 | typedef unsigned int uint; 16 | 17 | #define TIME 1.0f 18 | #define QUALITY 0 // 0=decent/fast, 1=good/slow, 2=best/very_slow 19 | 20 | // Utilities 21 | float limiter(float val); 22 | float **allocateAudioBuffer(uint numChannels, uint numFrames); 23 | void deallocateAudioBuffer(float **samples, uint numChannels); 24 | void interlace(float *out, float **in, uint numFrames, uint numChannels); 25 | void deinterlace(float **out, float *in, uint numFrames, uint numChannels); 26 | 27 | // This function time-stretches 'inDuration' seconds to a buffer of 'outDuration' seconds. 28 | // It takes 'numChannels' from audio buffer 'inSamples' and writes the result into pre-allocated audio buffer 'outSamples'. 29 | // 'quality' is an integer from 0 (lowest quality / fast processing) to 2 (highest quality / slow processing) 30 | // returns 0 if everything went well and a negative eror number in case of a problem. 31 | int time_scale(float **outSamples, double outDuration, float **inSamples, double inDuration, long numChannels, float sampleRate, uint quality=QUALITY); 32 | 33 | // Same as above but with lists of times and durations as an input and durations as an output. 34 | // We don't allow pitch-shifting in the case of a list because of unavoidable artifacts with the limitations of dirac LE. 35 | int time_scale_list(float **outSamples, double *outDurations, float **inSamples, double *inDurations, uint numChunks, long numChannels, float sampleRate, uint quality=QUALITY); -------------------------------------------------------------------------------- /external/pysoundtouch14/build/lib.linux-i686-2.5/soundtouch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pysoundtouch14/build/lib.linux-i686-2.5/soundtouch.so -------------------------------------------------------------------------------- /external/pysoundtouch14/build/lib.macosx-10.5-i386-2.5/soundtouch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pysoundtouch14/build/lib.macosx-10.5-i386-2.5/soundtouch.so -------------------------------------------------------------------------------- /external/pysoundtouch14/build/lib.win32-2.6/soundtouch.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/pysoundtouch14/build/lib.win32-2.6/soundtouch.pyd -------------------------------------------------------------------------------- /external/pysoundtouch14/libsoundtouch/AAFilter.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | /// 3 | /// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo 4 | /// while maintaining the original pitch by using a time domain WSOLA-like method 5 | /// with several performance-increasing tweaks. 6 | /// 7 | /// Anti-alias filter is used to prevent folding of high frequencies when 8 | /// transposing the sample rate with interpolation. 9 | /// 10 | /// Author : Copyright (c) Olli Parviainen 11 | /// Author e-mail : oparviai 'at' iki.fi 12 | /// SoundTouch WWW: http://www.surina.net/soundtouch 13 | /// 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $ 17 | // File revision : $Revision: 4 $ 18 | // 19 | // $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $ 20 | // 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // License : 24 | // 25 | // SoundTouch audio processing library 26 | // Copyright (c) Olli Parviainen 27 | // 28 | // This library is free software; you can redistribute it and/or 29 | // modify it under the terms of the GNU Lesser General Public 30 | // License as published by the Free Software Foundation; either 31 | // version 2.1 of the License, or (at your option) any later version. 32 | // 33 | // This library is distributed in the hope that it will be useful, 34 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 36 | // Lesser General Public License for more details. 37 | // 38 | // You should have received a copy of the GNU Lesser General Public 39 | // License along with this library; if not, write to the Free Software 40 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 41 | // 42 | //////////////////////////////////////////////////////////////////////////////// 43 | 44 | #ifndef AAFilter_H 45 | #define AAFilter_H 46 | 47 | #include "STTypes.h" 48 | 49 | namespace soundtouch 50 | { 51 | 52 | class AAFilter 53 | { 54 | protected: 55 | class FIRFilter *pFIR; 56 | 57 | /// Low-pass filter cut-off frequency, negative = invalid 58 | double cutoffFreq; 59 | 60 | /// num of filter taps 61 | uint length; 62 | 63 | /// Calculate the FIR coefficients realizing the given cutoff-frequency 64 | void calculateCoeffs(); 65 | public: 66 | AAFilter(uint length); 67 | 68 | ~AAFilter(); 69 | 70 | /// Sets new anti-alias filter cut-off edge frequency, scaled to sampling 71 | /// frequency (nyquist frequency = 0.5). The filter will cut off the 72 | /// frequencies than that. 73 | void setCutoffFreq(double newCutoffFreq); 74 | 75 | /// Sets number of FIR filter taps, i.e. ~filter complexity 76 | void setLength(uint newLength); 77 | 78 | uint getLength() const; 79 | 80 | /// Applies the filter to the given sequence of samples. 81 | /// Note : The amount of outputted samples is by value of 'filter length' 82 | /// smaller than the amount of input samples. 83 | uint evaluate(SAMPLETYPE *dest, 84 | const SAMPLETYPE *src, 85 | uint numSamples, 86 | uint numChannels) const; 87 | }; 88 | 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /external/pysoundtouch14/libsoundtouch/cpu_detect.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | /// 3 | /// A header file for detecting the Intel MMX instructions set extension. 4 | /// 5 | /// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the 6 | /// routine implementations for x86 Windows, x86 gnu version and non-x86 7 | /// platforms, respectively. 8 | /// 9 | /// Author : Copyright (c) Olli Parviainen 10 | /// Author e-mail : oparviai 'at' iki.fi 11 | /// SoundTouch WWW: http://www.surina.net/soundtouch 12 | /// 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $ 16 | // File revision : $Revision: 4 $ 17 | // 18 | // $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $ 19 | // 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // License : 23 | // 24 | // SoundTouch audio processing library 25 | // Copyright (c) Olli Parviainen 26 | // 27 | // This library is free software; you can redistribute it and/or 28 | // modify it under the terms of the GNU Lesser General Public 29 | // License as published by the Free Software Foundation; either 30 | // version 2.1 of the License, or (at your option) any later version. 31 | // 32 | // This library is distributed in the hope that it will be useful, 33 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35 | // Lesser General Public License for more details. 36 | // 37 | // You should have received a copy of the GNU Lesser General Public 38 | // License along with this library; if not, write to the Free Software 39 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 40 | // 41 | //////////////////////////////////////////////////////////////////////////////// 42 | 43 | #ifndef _CPU_DETECT_H_ 44 | #define _CPU_DETECT_H_ 45 | 46 | #include "STTypes.h" 47 | 48 | #define SUPPORT_MMX 0x0001 49 | #define SUPPORT_3DNOW 0x0002 50 | #define SUPPORT_ALTIVEC 0x0004 51 | #define SUPPORT_SSE 0x0008 52 | #define SUPPORT_SSE2 0x0010 53 | 54 | /// Checks which instruction set extensions are supported by the CPU. 55 | /// 56 | /// \return A bitmask of supported extensions, see SUPPORT_... defines. 57 | uint detectCPUextensions(void); 58 | 59 | /// Disables given set of instruction extensions. See SUPPORT_... defines. 60 | void disableExtensions(uint wDisableMask); 61 | 62 | #endif // _CPU_DETECT_H_ 63 | -------------------------------------------------------------------------------- /external/pysoundtouch14/setup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # LGPL via Soundtouch (LGPL) 3 | # Based on http://trac2.assembla.com/pkaudio/wiki/pysoundtouch 4 | # but updated for soundtouch 1.4, python 2.5/2.6, numpy by blacker@echonest.com, brian@echonest.com 6/2009 5 | 6 | import os 7 | from distutils.core import setup, Extension 8 | 9 | sources = ['AAFilter.cpp', 10 | 'FIFOSampleBuffer.cpp', 11 | 'FIRFilter.cpp', 12 | 'RateTransposer.cpp', 13 | 'SoundTouch.cpp', 14 | 'TDStretch.cpp', 15 | 'BPMDetect.cpp', 16 | 'PeakFinder.cpp', 17 | 'mmx_optimized.cpp', 18 | 'sse_optimized.cpp' 19 | ] 20 | 21 | sources_gcc = ['cpu_detect_x86_gcc.cpp', 22 | ] 23 | 24 | sources_win = ['cpu_detect_x86_win.cpp', 25 | '3dnow_win.cpp', 26 | ] 27 | 28 | extra_compile_args = [] 29 | # Is this is posix platform, or is it windows? 30 | if hasattr(os, 'uname'): 31 | sources += sources_gcc 32 | extra_compile_args=['-O3', 33 | '-I', '/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/numpy/core/include', # mac 34 | '-I', '/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/numpy/numarray', # mac 35 | '-I', '/usr/lib/python2.5/site-packages/numpy/numarray/numpy'] # lin 36 | else: 37 | sources += sources_win 38 | extra_compile_args=['-IC:\Python26\Lib\site-packages\\numpy\\numarray','-IC:\Python26\Lib\site-packages\\numpy\core\include'] # win 39 | 40 | libSoundTouch_sources = [os.path.join('libsoundtouch', i) for i in sources] 41 | 42 | soundtouch = Extension('soundtouch', sources=['soundtouchmodule.cpp',] + libSoundTouch_sources, extra_compile_args = extra_compile_args) 43 | 44 | setup(name = 'soundtouch', 45 | version = '0.2', 46 | description = 'Python libSoundTouch interface', 47 | author = 'Patrick Kidd Stinson, Brian Whitman, Ben Lacker', 48 | author_email = 'brian@echonest.com', 49 | url='http://code.echonest.com/p/echo-nest-remix', 50 | ext_modules = [soundtouch]) 51 | 52 | -------------------------------------------------------------------------------- /external/youtube-dl/youtube-dl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/external/youtube-dl/youtube-dl -------------------------------------------------------------------------------- /fix_develop_install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Fixes the paths due to package dirs being ignored by setup.py develop: 3 | # https://bitbucket.org/tarek/distribute/issue/177/setuppy-develop-doesnt-support-package_dir 4 | 5 | # Run this, with sudo, after running python setup.py develop. 6 | 7 | import sys 8 | import os 9 | import shutil 10 | 11 | # Get the location of easy-install.pth 12 | temp_path = sys.path 13 | final_python_path = list(set(temp_path)) 14 | for path in final_python_path: 15 | try: 16 | files = os.listdir(path) 17 | if "easy-install.pth" in files: 18 | path_to_easy_install = path 19 | break 20 | except OSError: # In case sys.path has dirs that have been deleted 21 | pass 22 | 23 | # Get the location of the remix installaton. 24 | f = open(path_to_easy_install + os.sep + 'remix.egg-link', 'r') 25 | for line in f: 26 | if os.sep in line: 27 | path_to_remix = line.strip() 28 | break 29 | f.close() 30 | 31 | # Do the modfication: 32 | easy_install_path = path_to_easy_install + os.sep + 'easy-install.pth' 33 | remix_source_string = path_to_remix + os.sep + "src\n" 34 | pyechonest_source_string = path_to_remix + os.sep + "pyechonest\n" 35 | 36 | print "Adding %s and %s to %s" % (remix_source_string, pyechonest_source_string, easy_install_path) 37 | f = open(easy_install_path, 'a') 38 | f.write(remix_source_string) 39 | f.write(pyechonest_source_string) 40 | f.close() 41 | 42 | # Copy youtube-dl out 43 | print "Copying youtube-dl to /usr/local/bin" 44 | # If we're in a virtualenv: 45 | if 'real_prefix' in dir(sys): 46 | data_path = os.path.join(sys.prefix, "local/bin/youtube-dl") 47 | else: 48 | data_path = '/usr/local/bin/youtube-dl' 49 | shutil.copyfile('external/youtube-dl/youtube-dl', data_path) 50 | os.chmod(data_path, 0755) 51 | 52 | -------------------------------------------------------------------------------- /src/echonest/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 'remix' ] 2 | -------------------------------------------------------------------------------- /src/echonest/remix/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 'action', 'audio', 'local_db', 'modify', 'support', 'video' ] 2 | -------------------------------------------------------------------------------- /src/echonest/remix/local_db.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | local_db.py 5 | 6 | Functions for saving analysis and wave files to local storage 7 | """ 8 | 9 | import os 10 | import json 11 | import shutil 12 | import logging 13 | 14 | LOG = logging.getLogger(__name__) 15 | HOME = os.path.expanduser("~") 16 | REMIX_PATH = '.remix-db' 17 | REMIX_FOLDER = HOME + os.path.sep + REMIX_PATH 18 | AUDIO_FOLDER = REMIX_FOLDER + os.path.sep + 'audio' 19 | ANALYSIS_FOLDER = REMIX_FOLDER + os.path.sep + 'analysis' 20 | DATABASE = REMIX_FOLDER + os.path.sep + 'database.db' 21 | 22 | def check_and_create_local_db(): 23 | '''If the local db does not exist, create it.''' 24 | home_dir = os.listdir(HOME) 25 | if REMIX_PATH in home_dir: 26 | LOG.info("Found local database.") 27 | return 28 | else: 29 | LOG.info("Local database not found, creating...") 30 | 31 | os.mkdir(REMIX_FOLDER) 32 | os.mkdir(AUDIO_FOLDER) 33 | os.mkdir(ANALYSIS_FOLDER) 34 | 35 | db_file = open(DATABASE, 'wb') 36 | db_file.close() 37 | LOG.info("Local database created.") 38 | 39 | def check_db(track_md5): 40 | '''Check the DB and see if the track is in it.''' 41 | with open(DATABASE, 'r') as db_file: 42 | for line in db_file: 43 | if track_md5 == line.strip(): 44 | return True 45 | return False 46 | 47 | def save_to_local(track_md5, audio_file, pyechonest_track): 48 | '''Save a track to the db.''' 49 | with open(DATABASE, 'a') as db_file: 50 | db_file.write(track_md5 + '\n') 51 | 52 | save_audio_to_local(track_md5, audio_file) 53 | save_analysis_to_local(track_md5, pyechonest_track) 54 | 55 | def save_audio_to_local(track_md5, audio_file): 56 | '''Copy the uncompressed audio file to the db.''' 57 | target_file = AUDIO_FOLDER + os.path.sep + track_md5 + '.wav' 58 | shutil.copyfile(audio_file, target_file) 59 | 60 | def save_analysis_to_local(track_md5, pyechonest_track): 61 | '''Save the pyechonest track dict as json to the db.''' 62 | target_file = ANALYSIS_FOLDER + os.path.sep + track_md5 + '.analysis' 63 | with open(target_file, 'wb') as db_file: 64 | json.dump(pyechonest_track.__dict__, db_file) 65 | 66 | def get_audio_file(track_md5): 67 | '''Get an audio file from the db.''' 68 | target_file = AUDIO_FOLDER + os.path.sep + track_md5 + '.wav' 69 | return target_file 70 | 71 | def get_analysis_file(track_md5): 72 | '''Get an analysis file from the db.''' 73 | target_file = ANALYSIS_FOLDER + os.path.sep + track_md5 + '.analysis' 74 | return target_file 75 | -------------------------------------------------------------------------------- /src/echonest/remix/support/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 'midi', 'ffmpeg' ] 2 | -------------------------------------------------------------------------------- /src/echonest/remix/support/exceptionthread.py: -------------------------------------------------------------------------------- 1 | """ 2 | ExceptionThread.py 3 | by Peter Sobot, 2012-04-23 4 | https://gist.github.com/2386993 5 | 6 | Base class for a thread that tracks its own exceptions and 7 | raises them when joined by the main thread. Can check for 8 | an exception by doing .join(0) from another thread. 9 | """ 10 | 11 | import Queue 12 | import threading 13 | import sys 14 | 15 | __author__ = 'psobot' 16 | 17 | 18 | class ExceptionThread(threading.Thread): 19 | def __init__(self, *args, **kwargs): 20 | threading.Thread.__init__(self, *args, **kwargs) 21 | self.__status_queue = Queue.Queue() 22 | 23 | def run(self, *args, **kwargs): 24 | try: 25 | threading.Thread.run(self) 26 | except Exception: 27 | self.__status_queue.put(sys.exc_info()) 28 | self.__status_queue.put(None) 29 | 30 | def join(self, num=None): 31 | if not self.__status_queue: 32 | return 33 | try: 34 | exc_info = self.__status_queue.get(True, num) 35 | if exc_info: 36 | raise exc_info[1], None, exc_info[2] 37 | except Queue.Empty: 38 | return 39 | self.__status_queue = None 40 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/DataTypeConverters.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/DataTypeConverters.py -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/MidiInFile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: ISO-8859-1 -*- 2 | 3 | from RawInstreamFile import RawInstreamFile 4 | from MidiFileParser import MidiFileParser 5 | 6 | 7 | class MidiInFile: 8 | 9 | """ 10 | 11 | Parses a midi file, and triggers the midi events on the outStream 12 | object. 13 | 14 | Get example data from a minimal midi file, generated with cubase. 15 | >>> test_file = 'C:/Documents and Settings/maxm/Desktop/temp/midi/src/midi/tests/midifiles/minimal-cubase-type0.mid' 16 | 17 | Do parsing, and generate events with MidiToText, 18 | so we can see what a minimal midi file contains 19 | >>> from MidiToText import MidiToText 20 | >>> midi_in = MidiInFile(MidiToText(), test_file) 21 | >>> midi_in.read() 22 | format: 0, nTracks: 1, division: 480 23 | ---------------------------------- 24 | 25 | Start - track #0 26 | sequence_name: Type 0 27 | tempo: 500000 28 | time_signature: 4 2 24 8 29 | note_on - ch:00, note:48, vel:64 time:0 30 | note_off - ch:00, note:48, vel:40 time:480 31 | End of track 32 | 33 | End of file 34 | 35 | 36 | """ 37 | 38 | def __init__(self, outStream, infile): 39 | # these could also have been mixins, would that be better? Nah! 40 | self.raw_in = RawInstreamFile(infile) 41 | self.parser = MidiFileParser(self.raw_in, outStream) 42 | 43 | 44 | def read(self): 45 | "Start parsing the file" 46 | p = self.parser 47 | p.parseMThdChunk() 48 | p.parseMTrkChunks() 49 | 50 | 51 | def setData(self, data=''): 52 | "Sets the data from a plain string" 53 | self.raw_in.setData(data) 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/MidiInStream.py: -------------------------------------------------------------------------------- 1 | # -*- coding: ISO-8859-1 -*- 2 | 3 | from MidiOutStream import MidiOutStream 4 | 5 | class MidiInStream: 6 | 7 | """ 8 | Takes midi events from the midi input and calls the apropriate 9 | method in the eventhandler object 10 | """ 11 | 12 | def __init__(self, midiOutStream, device): 13 | 14 | """ 15 | 16 | Sets a default output stream, and sets the device from where 17 | the input comes 18 | 19 | """ 20 | 21 | if midiOutStream is None: 22 | self.midiOutStream = MidiOutStream() 23 | else: 24 | self.midiOutStream = midiOutStream 25 | 26 | 27 | def close(self): 28 | 29 | """ 30 | Stop the MidiInstream 31 | """ 32 | 33 | 34 | def read(self, time=0): 35 | 36 | """ 37 | 38 | Start the MidiInstream. 39 | 40 | "time" sets timer to specific start value. 41 | 42 | """ 43 | 44 | 45 | def resetTimer(self, time=0): 46 | """ 47 | 48 | Resets the timer, probably a good idea if there is some kind 49 | of looping going on 50 | 51 | """ 52 | 53 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/RawOutstreamFile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: ISO-8859-1 -*- 2 | 3 | # standard library imports 4 | import sys 5 | from types import StringType 6 | from struct import unpack 7 | from cStringIO import StringIO 8 | 9 | # custom import 10 | from DataTypeConverters import writeBew, writeVar, fromBytes 11 | 12 | class RawOutstreamFile: 13 | 14 | """ 15 | 16 | Writes a midi file to disk. 17 | 18 | """ 19 | 20 | def __init__(self, outfile=''): 21 | self.buffer = StringIO() 22 | self.outfile = outfile 23 | 24 | 25 | # native data reading functions 26 | 27 | 28 | def writeSlice(self, str_slice): 29 | "Writes the next text slice to the raw data" 30 | self.buffer.write(str_slice) 31 | 32 | 33 | def writeBew(self, value, length=1): 34 | "Writes a value to the file as big endian word" 35 | self.writeSlice(writeBew(value, length)) 36 | 37 | 38 | def writeVarLen(self, value): 39 | "Writes a variable length word to the file" 40 | var = self.writeSlice(writeVar(value)) 41 | 42 | 43 | def write(self): 44 | "Writes to disc" 45 | if self.outfile: 46 | if isinstance(self.outfile, StringType): 47 | outfile = open(self.outfile, 'wb') 48 | outfile.write(self.getvalue()) 49 | outfile.close() 50 | else: 51 | self.outfile.write(self.getvalue()) 52 | else: 53 | sys.stdout.write(self.getvalue()) 54 | 55 | def getvalue(self): 56 | return self.buffer.getvalue() 57 | 58 | 59 | if __name__ == '__main__': 60 | 61 | out_file = 'test/midifiles/midiout.mid' 62 | out_file = '' 63 | rawOut = RawOutstreamFile(out_file) 64 | rawOut.writeSlice('MThd') 65 | rawOut.writeBew(6, 4) 66 | rawOut.writeBew(1, 2) 67 | rawOut.writeBew(2, 2) 68 | rawOut.writeBew(15360, 2) 69 | rawOut.write() 70 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: ISO-8859-1 -*- 2 | """ 3 | This is the documentation for the midi package 4 | ============================================== 5 | 6 | 7 | The modules follows the following naming convention: 8 | 9 | 10 | MidiIn.py 11 | --------------------- 12 | 13 | The MidiIn modules reads midi content for a specific type of stream. Ie. a file or a midi port. It then generates events and triggers them on a MidiOutStream. 14 | 15 | 16 | MidiOut.py 17 | ---------------------- 18 | 19 | The MidiOut modules are event handlers, that reacts to events generated by a a Midi in module. 20 | 21 | 22 | MidiInBase.py 23 | --------------- 24 | 25 | The base class for input streams. 26 | 27 | 28 | MidiOutBase.py 29 | ---------------- 30 | 31 | The base class for the output streams. 32 | 33 | 34 | 35 | 36 | 37 | 38 | Internal modules 39 | ================ 40 | 41 | 42 | DataTypeConverters.py 43 | --------------------- 44 | 45 | A collection of functions that converts the special data types used in midi files to and from strings. 46 | 47 | 48 | constants.py 49 | ------------ 50 | 51 | A collection of constants from the midi spec. 52 | 53 | """ 54 | #import MidiOutStream 55 | #import MidiInStream 56 | #import MidiInFile 57 | #import MidiToText -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/changes.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------ 2 | r409 | maxm | 2006-01-05 16:37:29 +0100 (to, 05 jan 2006) | 1 line 3 | 4 | Made RawOutstreamFile.py write to std out if no outfile is given. 5 | ------------------------------------------------------------------------ 6 | r403 | maxm | 2006-01-05 13:34:11 +0100 (to, 05 jan 2006) | 1 line 7 | 8 | 9 | ------------------------------------------------------------------------ 10 | r402 | maxm | 2006-01-05 13:33:56 +0100 (to, 05 jan 2006) | 1 line 11 | 12 | - Fixed minor bugs, added coding headers 13 | ------------------------------------------------------------------------ 14 | r401 | maxm | 2006-01-01 23:09:17 +0100 (s_, 01 jan 2006) | 1 line 15 | 16 | Fixed sysex dispathcer bug. 17 | ------------------------------------------------------------------------ 18 | r268 | maxm | 2005-02-04 12:26:59 +0100 (fr, 04 feb 2005) | 1 line 19 | 20 | 21 | ------------------------------------------------------------------------ 22 | r128 | maxm | 2004-12-18 14:05:27 +0100 (l_, 18 dec 2004) | 1 line 23 | 24 | Fixed bug when using relative time 25 | ------------------------------------------------------------------------ 26 | r15 | maxm | 2004-03-09 15:01:41 +0100 (ti, 09 mar 2004) | 1 line 27 | 28 | made a copy to meta folder 29 | ------------------------------------------------------------------------ 30 | r13 | maxm | 2004-03-09 09:17:23 +0100 (ti, 09 mar 2004) | 1 line 31 | 32 | Deleted .pyc files 33 | ------------------------------------------------------------------------ 34 | r12 | maxm | 2004-03-09 09:15:54 +0100 (ti, 09 mar 2004) | 1 line 35 | 36 | Removed file/folder 37 | ------------------------------------------------------------------------ 38 | r3 | maxm | 2004-03-08 23:16:25 +0100 (ma, 08 mar 2004) | 1 line 39 | 40 | Adde midi 41 | ------------------------------------------------------------------------ 42 | r1 | maxm | 2004-03-08 22:49:23 +0100 (ma, 08 mar 2004) | 1 line 43 | 44 | Initial Import 45 | ------------------------------------------------------------------------ 46 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/example_mimimal_type0.py: -------------------------------------------------------------------------------- 1 | from MidiOutFile import MidiOutFile 2 | 3 | """ 4 | This is an example of the smallest possible type 0 midi file, where 5 | all the midi events are in the same track. 6 | """ 7 | 8 | out_file = 'midiout/minimal_type0.mid' 9 | midi = MidiOutFile(out_file) 10 | 11 | # non optional midi framework 12 | midi.header() 13 | midi.start_of_track() 14 | 15 | 16 | # musical events 17 | 18 | midi.update_time(0) 19 | midi.note_on(channel=0, note=0x40) 20 | 21 | midi.update_time(192) 22 | midi.note_off(channel=0, note=0x40) 23 | 24 | 25 | # non optional midi framework 26 | midi.update_time(0) 27 | midi.end_of_track() 28 | 29 | midi.eof() 30 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/example_print_channel_0.py: -------------------------------------------------------------------------------- 1 | from MidiOutStream import MidiOutStream 2 | from MidiInFile import MidiInFile 3 | 4 | """ 5 | This prints all note on events on midi channel 0 6 | """ 7 | 8 | 9 | class Transposer(MidiOutStream): 10 | 11 | "Transposes all notes by 1 octave" 12 | 13 | def note_on(self, channel=0, note=0x40, velocity=0x40): 14 | if channel == 0: 15 | print channel, note, velocity, self.rel_time() 16 | 17 | 18 | event_handler = Transposer() 19 | 20 | in_file = 'midiout/minimal_type0.mid' 21 | midi_in = MidiInFile(event_handler, in_file) 22 | midi_in.read() 23 | 24 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/example_print_events.py: -------------------------------------------------------------------------------- 1 | from MidiToText import MidiToText 2 | 3 | """ 4 | This is an example that uses the MidiToText eventhandler. When an 5 | event is triggered on it, it prints the event to the console. 6 | """ 7 | 8 | midi = MidiToText() 9 | 10 | # non optional midi framework 11 | midi.header() 12 | midi.start_of_track() 13 | 14 | 15 | # musical events 16 | 17 | midi.update_time(0) 18 | midi.note_on(channel=0, note=0x40) 19 | 20 | midi.update_time(192) 21 | midi.note_off(channel=0, note=0x40) 22 | 23 | 24 | # non optional midi framework 25 | midi.update_time(0) 26 | midi.end_of_track() # not optional! 27 | 28 | midi.eof() 29 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/example_print_file.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is an example that uses the MidiToText eventhandler. When an 3 | event is triggered on it, it prints the event to the console. 4 | 5 | It gets the events from the MidiInFile. 6 | 7 | So it prints all the events from the infile to the console. great for 8 | debugging :-s 9 | """ 10 | 11 | 12 | # get data 13 | test_file = 'test/midifiles/minimal-cubase-type0.mid' 14 | 15 | # do parsing 16 | from MidiInFile import MidiInFile 17 | from MidiToText import MidiToText # the event handler 18 | midiIn = MidiInFile(MidiToText(), test_file) 19 | midiIn.read() 20 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/example_transpose_octave.py: -------------------------------------------------------------------------------- 1 | from MidiOutFile import MidiOutFile 2 | from MidiInFile import MidiInFile 3 | 4 | """ 5 | This is an example of the smallest possible type 0 midi file, where 6 | all the midi events are in the same track. 7 | """ 8 | 9 | 10 | class Transposer(MidiOutFile): 11 | 12 | "Transposes all notes by 1 octave" 13 | 14 | def _transp(self, ch, note): 15 | if ch != 9: # not the drums! 16 | note += 12 17 | if note > 127: 18 | note = 127 19 | return note 20 | 21 | 22 | def note_on(self, channel=0, note=0x40, velocity=0x40): 23 | note = self._transp(channel, note) 24 | MidiOutFile.note_on(self, channel, note, velocity) 25 | 26 | 27 | def note_off(self, channel=0, note=0x40, velocity=0x40): 28 | note = self._transp(channel, note) 29 | MidiOutFile.note_off(self, channel, note, velocity) 30 | 31 | 32 | out_file = 'midiout/transposed.mid' 33 | midi_out = Transposer(out_file) 34 | 35 | #in_file = 'midiout/minimal_type0.mid' 36 | #in_file = 'test/midifiles/Lola.mid' 37 | in_file = 'test/midifiles/tennessee_waltz.mid' 38 | midi_in = MidiInFile(midi_out, in_file) 39 | midi_in.read() 40 | 41 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/experimental/EventDispatcherBase.py: -------------------------------------------------------------------------------- 1 | class EventDispatcherBase: 2 | 3 | 4 | def __init__(self, outstream): 5 | """ 6 | The event dispatcher generates events on the outstream. This 7 | is the base implementation. It is more like an interface for 8 | how the EventDispatcher. It has the methods that are used by 9 | the Midi Parser. 10 | """ 11 | # internal values, don't mess with 'em directly 12 | self.outstream = outstream 13 | 14 | 15 | def eof(self): 16 | "End of file!" 17 | self.outstream.eof() 18 | 19 | 20 | def update_time(self, new_time=0, relative=1): 21 | "Updates relative/absolute time." 22 | self.outstream.update_time(new_time, relative) 23 | 24 | # 'official' midi events 25 | 26 | def header(self, format, nTracks, division): 27 | "Triggers the header event" 28 | self.outstream.header(format, nTracks, division) 29 | 30 | 31 | def start_of_track(self, current_track): 32 | "Triggers the start of track event" 33 | 34 | # I do this twice so that users can overwrite the 35 | # start_of_track event handler without worrying whether the 36 | # track number is updated correctly. 37 | self.outstream.set_current_track(current_track) 38 | self.outstream.start_of_track(current_track) 39 | 40 | # Event dispatchers for midi events 41 | 42 | def channel_messages(self, hi_nible, channel, data): 43 | "Dispatches channel messages" 44 | self.outstream.channel_message(hi_nible, channel, data) 45 | 46 | 47 | def continuous_controllers(self, channel, controller, value): 48 | "Dispatches channel messages" 49 | self.outstream.continuous_controller(channel, controller, value) 50 | 51 | 52 | def system_commons(self, common_type, common_data): 53 | "Dispatches system common messages" 54 | self.outstream.system_common(common_type, common_data) 55 | 56 | 57 | def meta_event(self, meta_type, data): 58 | "Dispatches meta events" 59 | self.outstream.meta_event(meta_type, data) 60 | 61 | 62 | def sysex_events(self, data): 63 | "Dispatcher for sysex events" 64 | self.outstream.sysex_event(data) 65 | 66 | 67 | 68 | if __name__ == '__main__': 69 | 70 | 71 | from MidiToText import MidiToText 72 | from constants import NOTE_ON 73 | 74 | outstream = MidiToText() 75 | dispatcher = EventDispatcherBase(outstream) 76 | dispatcher.channel_messages(NOTE_ON, 0x00, '\x40\x40') -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/experimental/readme.txt: -------------------------------------------------------------------------------- 1 | Stuff that I am just playing around with -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/midiout/minimal_type0.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/midiout/minimal_type0.mid -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/midiout/transposed.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/midiout/transposed.mid -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/readme.txt: -------------------------------------------------------------------------------- 1 | This is the documentation for the midi package 2 | ============================================== 3 | 4 | 5 | The modules follows the following naming convention: 6 | 7 | 8 | MidiIn.py 9 | --------------------- 10 | 11 | The MidiIn modules reads midi content for a specific type of stream. Ie. a file or a midi port. It then generates events and triggers them on a MidiOutStream. 12 | 13 | 14 | MidiOut.py 15 | ---------------------- 16 | 17 | The MidiOut modules are event handlers, that reacts to events generated by a a Midi in module. 18 | 19 | 20 | MidiInBase.py 21 | --------------- 22 | 23 | The base class for input streams. 24 | 25 | 26 | MidiOutBase.py 27 | ---------------- 28 | 29 | The base class for the output streams. 30 | 31 | 32 | 33 | 34 | 35 | 36 | Internal modules 37 | ================ 38 | 39 | 40 | DataTypeConverters.py 41 | --------------------- 42 | 43 | A collection of functions that converts the special data types used in midi files to and from strings. 44 | 45 | 46 | constants.py 47 | ------------ 48 | 49 | A collection of constants from the midi spec. 50 | 51 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/midiout.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/test/midifiles/midiout.mid -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/minimal-cubase-type0.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/test/midifiles/minimal-cubase-type0.mid -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/minimal-cubase-type1.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/test/midifiles/minimal-cubase-type1.mid -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/minimal.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/src/echonest/remix/support/midi/test/midifiles/minimal.mid -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/minimal.txt: -------------------------------------------------------------------------------- 1 | MThd | Format=1 | # of Tracks=2 | Division=15360 2 | 3 | 4 | 5 | 6 | Track #0 ****************************************** 7 | Time Event 8 | 9 | 1: 1: 0 |Time Sig | 4/4 | MIDI-clocks\click=24 | 32nds\quarter=8 10 | |Tempo | BPM=120 | micros\quarter=500000 11 | 101: 1: 0 |End of track| 12 | 13 | 14 | 15 | 16 | 17 | Track #1 ****************************************** 18 | Time Event 19 | 20 | 1: 1: 0 |Track Name | len=7 | 21 | 0x53 0x79 0x6E 0x74 0x68 0x20 0x31 22 | |Instrument | len=7 | 23 | 0x53 0x79 0x6E 0x74 0x68 0x20 0x31 24 | |On Note | chan= 1 | pitch=C 1 | vol=127 25 | 2: 1: 0 |Off Note | chan= 1 | pitch=c 1 | vol=0 26 | 101: 1: 0 |End of track| 27 | -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/minimal_analyse.txt: -------------------------------------------------------------------------------- 1 | 4D 54 68 64 MThd 2 | 00 00 00 06 len: 6 3 | 00 01 Type: 1 4 | 00 02 tracks: 2 5 | 3C 00 tempo: 15360 6 | 7 | 8 | 9 | 4D 54 72 6B MTrk 10 | 00 00 00 16 len: 22 11 | 12 | 00 time 13 | FF 58 04 Time Signature 14 | 04 02 18 08 4/4 24 8 15 | 16 | 00 time 17 | FF 51 03 TEMPO: 18 | 07 A1 20 500.000 mySec 19 | 20 | 82 F7 80 00 time ## oh bugger, it's buggy. 21 | FF 2F 00 End Of Track 22 | 23 | 24 | 25 | 4D 54 72 6B MTrk 26 | 00 00 00 2C len: 44 27 | 28 | 00 time 29 | FF 03 Sequence/Track Name 30 | 07 len: 7 31 | 53 79 6E 74 32 | 68 20 31 'Synth 1' 33 | 34 | 00 time 35 | FF 04 Instrument 36 | 07 len: 7 37 | 53 79 6E 74 38 | 68 20 31 'Synth 1' 39 | 40 | 00 time 41 | FF 21 01 Midi port 42 | 04 Port #5 43 | 44 | 00 time 45 | 90 24 7F Note ON 46 | 83 E0 00 Note OFF 47 | 48 | 00 time 49 | 80 24 00 Note OFF 50 | 51 | 00 82 F3 A0 52 | 53 | 00 54 | FF 2F 00 End Of Track -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/midifiles/readme.txt: -------------------------------------------------------------------------------- 1 | These files are used for testing the midi package 2 | ================================================= 3 | 4 | minimal.mid 5 | ----------- 6 | 7 | A minimal working midifile. Plays a one bar "middle C" at 120 bpm. The absolute simplest file I could get to play in midi devices. -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/test/readme.txt: -------------------------------------------------------------------------------- 1 | Embarrasingly empty. 2 | 3 | Why don't you write some tests? -------------------------------------------------------------------------------- /src/echonest/remix/support/midi/version.txt: -------------------------------------------------------------------------------- 1 | 0.1.4 -------------------------------------------------------------------------------- /tests/TESTING.txt: -------------------------------------------------------------------------------- 1 | Test that an Echo-Nest-Remix-compatible version of ffmpeg is installed. 2 | 3 | Run the tests like this: 4 | python test_ffmpeg.py 5 | 6 | If you want to test that your version of ffmpeg can handle a particular file, 7 | (like if you're planning on analyzing OggVorbis files and want to make sure 8 | your ffmpeg can decode them), run like this: 9 | python test_ffmpeg.py my_crazy_audio_file.mp47 10 | 11 | If any of these tests fail, chances are you are using a version of ffmpeg 12 | that doesn't have all the codecs it needs installed. To remedy this, either 13 | find and install the missing codecs, or use the version of en-ffmpeg provided 14 | by The Echo Nest. To use the provided en-ffmpeg, copy the binary appropriate 15 | to your OS from external/en-ffmpeg/ to the location where your system keeps 16 | binaries (on mac this is /usr/local/bin/). 17 | 18 | The audio file provided for testing, input_file.mp3, is "Guppies" by 19 | Raleigh Moncrief, licensed under a Creative Commons Attribution-NonCommercial License. 20 | http://freemusicarchive.org/music/Raleigh_Moncrief/Vitamins_EP/Raleigh_Moncrief_-_Vitamins_EP_-_02_Guppies -------------------------------------------------------------------------------- /tests/input_file.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tests/input_file.mp3 -------------------------------------------------------------------------------- /tests/test_ffmpeg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | Test that an Echo-Nest-Remix-compatible version of ffmpeg is installed. 5 | 6 | Run the tests like this: 7 | python test_ffmpeg.py 8 | 9 | If you want to test that your version of ffmpeg can handle a particular file, 10 | (like if you're planning on analyzing OggVorbis files and want to make sure 11 | your ffmpeg can decode them), run like this: 12 | python test_ffmpeg.py my_crazy_audio_file.mp47 13 | """ 14 | 15 | import os 16 | import sys 17 | import tempfile 18 | 19 | from echonest import audio 20 | 21 | def main(): 22 | """Run some tests""" 23 | if len(sys.argv) > 1: 24 | input_filename = sys.argv[1] 25 | else: 26 | input_filename = 'input_file.mp3' 27 | test_en_ffmpeg_exists(input_filename) 28 | test_round_trip(input_filename) 29 | 30 | def test_en_ffmpeg_exists(input_filename): 31 | """Don't do any conversion, just see if en-ffmpeg, the command used 32 | by Remix, is installed.""" 33 | result = audio.ffmpeg(input_filename, overwrite=False, verbose=True) 34 | audio.ffmpeg_error_check(result[1]) 35 | 36 | def test_round_trip(input_filename): 37 | """Convert the input file to a wav file, then back to an mp3 file.""" 38 | result = audio.ffmpeg(input_filename, overwrite=False, verbose=True) 39 | audio.ffmpeg_error_check(result[1]) 40 | sampleRate, numChannels = audio.settings_from_ffmpeg(result[1]) 41 | 42 | temp_file_handle, temp_filename = tempfile.mkstemp(".wav") 43 | result = audio.ffmpeg(input_filename, temp_filename, overwrite=True, 44 | numChannels=numChannels, sampleRate=sampleRate, verbose=True) 45 | audio.ffmpeg_error_check(result[1]) 46 | 47 | temp_filesize = os.path.getsize(temp_filename) 48 | print 'temp file size: %s bytes' % temp_filesize 49 | 50 | output_filename = 'output_file.mp3' 51 | result = audio.ffmpeg(temp_filename, output_filename, overwrite=True, 52 | numChannels=numChannels, sampleRate=sampleRate, verbose=True) 53 | audio.ffmpeg_error_check(result[1]) 54 | 55 | if temp_file_handle is not None: 56 | os.close(temp_file_handle) 57 | os.remove(temp_filename) 58 | 59 | input_filesize = os.path.getsize(input_filename) 60 | output_filesize = os.path.getsize(output_filename) 61 | difference = output_filesize - input_filesize 62 | args = (input_filesize, output_filesize, difference) 63 | print 'input file size: %s bytes | output file size: %s bytes | difference: %s bytes ' % args 64 | if abs(int(difference)) > 1000: 65 | print 'input and output files are different sizes. something might be wrong with your ffmpeg.' 66 | else: 67 | print 'Ok!' 68 | 69 | if __name__ == '__main__': 70 | main() 71 | 72 | -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/cowbell0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/cowbell0.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/cowbell1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/cowbell1.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/cowbell2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/cowbell2.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/cowbell3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/cowbell3.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/cowbell4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/cowbell4.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/trill.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/trill.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken0.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken1.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken10.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken10.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken11.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken11.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken12.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken12.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken13.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken13.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken14.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken14.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken15.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken15.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken2.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken3.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken4.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken5.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken6.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken7.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken7.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken8.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken8.wav -------------------------------------------------------------------------------- /tutorial/cowbell/cowbell/sounds/walken9.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/cowbell/sounds/walken9.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/cowbell0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/cowbell0.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/cowbell1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/cowbell1.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/cowbell2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/cowbell2.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/cowbell3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/cowbell3.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/cowbell4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/cowbell4.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/trill.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/trill.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken0.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken1.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken10.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken10.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken11.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken11.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken12.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken12.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken13.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken13.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken14.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken14.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken15.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken15.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken2.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken3.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken4.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken5.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken6.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken7.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken7.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken8.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken8.wav -------------------------------------------------------------------------------- /tutorial/cowbell/sounds/walken9.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/cowbell/sounds/walken9.wav -------------------------------------------------------------------------------- /tutorial/drums/breaks/AmenBrother.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/drums/breaks/AmenBrother.mp3 -------------------------------------------------------------------------------- /tutorial/drums/breaks/GiveituporTurnitLoose.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/drums/breaks/GiveituporTurnitLoose.mp3 -------------------------------------------------------------------------------- /tutorial/drums/breaks/assemblyline.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/echonest/remix/ca227c9d885689e2fc8cad02171d2c29a167fa73/tutorial/drums/breaks/assemblyline.mp3 -------------------------------------------------------------------------------- /tutorial/limp/lopside.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | lopside.py 6 | 7 | Cut out the final beat or group of tatums in each bar. 8 | Demonstrates the beat hierarchy navigation in AudioQuantum 9 | 10 | Originally by Adam Lindsay, 2009-01-19. 11 | """ 12 | 13 | # This line imports remix! 14 | import echonest.remix.audio as audio 15 | import sys 16 | 17 | usage = """ 18 | Usage: 19 | python lopside.py [tatum|beat] 20 | Beat is selected by default. 21 | 22 | Example: 23 | python lopside.py beat aha.mp3 ahawaltz.mp3 24 | """ 25 | 26 | # Lopside changes the meter of a track! 27 | # It does this by removing the last beat of every bar. 28 | # So a song that is in 4 will be in 3. 29 | # It does this by looping over the component bars of the track. 30 | # Then, it adds all but the last beat of each bar to a list. 31 | # That list is then used to create the output audio file. 32 | 33 | def main(units, inputFile, outputFile): 34 | # This takes your input track, sends it to the analyzer, and returns the results. 35 | audiofile = audio.LocalAudioFile(inputFile) 36 | 37 | # This makes a new list of "AudioQuantums". 38 | # Those are just any discrete chunk of audio: bars, beats, etc 39 | collect = audio.AudioQuantumList() 40 | 41 | # If the analysis can't find any bars, stop! 42 | # (This might happen with really ambient music) 43 | if not audiofile.analysis.bars: 44 | print "No bars found in this analysis!" 45 | print "No output." 46 | sys.exit(-1) 47 | 48 | # This loop puts all but the last of each bar into the new list! 49 | for b in audiofile.analysis.bars[0:-1]: 50 | collect.extend(b.children()[0:-1]) 51 | 52 | # If we're using tatums instead of beats, we want all but the last half (round down) of the last beat 53 | # A tatum is the smallest rhythmic subdivision of a beat -- http://en.wikipedia.org/wiki/Tatum_grid 54 | if units.startswith("tatum"): 55 | half = - (len(b.children()[-1].children()) // 2) 56 | collect.extend(b.children()[-1].children()[0:half]) 57 | 58 | # Endings were rough, so leave everything after the start of the final bar intact: 59 | last = audio.AudioQuantum(audiofile.analysis.bars[-1].start, 60 | audiofile.analysis.duration - 61 | audiofile.analysis.bars[-1].start) 62 | collect.append(last) 63 | 64 | # This assembles the pieces of audio defined in collect from the analyzed audio file. 65 | out = audio.getpieces(audiofile, collect) 66 | 67 | # This writes the newly created audio to the given file. 68 | out.encode(outputFile) 69 | 70 | # The wrapper for the script. 71 | if __name__ == '__main__': 72 | try: 73 | # This gets the units type, and the filenames to read from and write to. 74 | units = sys.argv[-3] 75 | inputFilename = sys.argv[-2] 76 | outputFilename = sys.argv[-1] 77 | except: 78 | # If things go wrong, exit! 79 | print usage 80 | sys.exit(-1) 81 | main(units, inputFilename, outputFilename) 82 | -------------------------------------------------------------------------------- /tutorial/one/one.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | """ 4 | one.py 5 | 6 | Digest only the first beat of every bar. 7 | 8 | By Ben Lacker, 2009-02-18. 9 | """ 10 | # This line imports remix! 11 | import echonest.remix.audio as audio 12 | 13 | usage = """ 14 | Usage: 15 | python one.py 16 | 17 | Example: 18 | python one.py EverythingIsOnTheOne.mp3 EverythingIsReallyOnTheOne.mp3 19 | """ 20 | 21 | # One outputs only the first beat of each bar! 22 | # It does this by looping over the component bars of the track. 23 | # Then, it adds the first beat of each bar to a list. 24 | # That list is then used to create the output audio file. 25 | 26 | def main(input_filename, output_filename): 27 | # This takes your input track, sends it to the analyzer, and returns the results. 28 | audiofile = audio.LocalAudioFile(input_filename) 29 | 30 | # This gets a list of every bar in the track. 31 | # You can manipulate this just like any other Python list! 32 | bars = audiofile.analysis.bars 33 | 34 | # This makes a new list of "AudioQuantums". 35 | # Those are just any discrete chunk of audio: bars, beats, etc. 36 | collect = audio.AudioQuantumList() 37 | 38 | # This loop puts the first item in the children of each bar into the new list. 39 | # A bar's children are beats! Simple as that. 40 | for bar in bars: 41 | collect.append(bar.children()[0]) 42 | 43 | # This assembles the pieces of audio defined in collect from the analyzed audio file. 44 | out = audio.getpieces(audiofile, collect) 45 | 46 | # This writes the newly created audio to the given file. 47 | out.encode(output_filename) 48 | 49 | 50 | # The wrapper for the script. 51 | if __name__ == '__main__': 52 | import sys 53 | try: 54 | # This gets the filenames to read from and write to. 55 | input_filename = sys.argv[1] 56 | output_filename = sys.argv[2] 57 | except: 58 | # If things go wrong, exit! 59 | print usage 60 | sys.exit(-1) 61 | main(input_filename, output_filename) 62 | -------------------------------------------------------------------------------- /tutorial/reverse/reverse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | reverse.py 6 | 7 | Reverse the beats or segments of a song. 8 | 9 | Originally created by Robert Ochshorn on 2008-06-11. Refactored by 10 | Joshua Lifton 2008-09-07. 11 | """ 12 | 13 | import echonest.remix.audio as audio 14 | 15 | usage = """ 16 | Usage: 17 | python reverse.py 18 | 19 | Example: 20 | python reverse.py beats YouCanCallMeAl.mp3 AlMeCallCanYou.mp3 21 | """ 22 | 23 | # Reverse plays the beats or segments of a sound backwards! 24 | # It does this by getting a list of every beat or segment in a track. 25 | # Then, it reverses the list. 26 | # This reversed list is used to create the output file. 27 | 28 | def main(toReverse, inputFilename, outputFilename): 29 | # This takes your input track, sends it to the analyzer, and returns the results. 30 | audioFile = audio.LocalAudioFile(inputFilename) 31 | 32 | # Checks what sort of reversing we're doing. 33 | if toReverse == 'beats' : 34 | # This gets a list of every beat in the track. 35 | chunks = audioFile.analysis.beats 36 | elif toReverse == 'segments' : 37 | # This gets a list of every segment in the track. 38 | # Segments are the smallest chunk of audio that Remix deals with 39 | chunks = audioFile.analysis.segments 40 | else : 41 | print usage 42 | return 43 | 44 | # Reverse the list! 45 | chunks.reverse() 46 | 47 | # This assembles the pieces of audio defined in chunks from the analyzed audio file. 48 | reversedAudio = audio.getpieces(audioFile, chunks) 49 | # This writes the newly created audio to the given file. 50 | reversedAudio.encode(outputFilename) 51 | 52 | # The wrapper for the script. 53 | if __name__ == '__main__': 54 | import sys 55 | try : 56 | # This gets what sort of reversing we're doing, and the filenames to read from and write to. 57 | toReverse = sys.argv[1] 58 | inputFilename = sys.argv[2] 59 | outputFilename = sys.argv[3] 60 | except : 61 | # If things go wrong, exit! 62 | print usage 63 | sys.exit(-1) 64 | if not toReverse in ["beats", "segments"]: 65 | print usage 66 | sys.exit(-1) 67 | main(toReverse, inputFilename, outputFilename) 68 | -------------------------------------------------------------------------------- /tutorial/selection/tonic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf=8 3 | 4 | """ 5 | tonic.py 6 | 7 | Digest all beats, tatums, or bars that start in the key of the song. 8 | Demonstrates content-based selection filtering via AudioQuantumLists 9 | 10 | Originally by Adam Lindsay, 2008-09-15. 11 | Refactored by Thor Kell, 2012-11-01 12 | """ 13 | import echonest.remix.audio as audio 14 | 15 | usage = """ 16 | Usage: 17 | python tonic.py 18 | 19 | Example: 20 | python tonic.py beats HereComesTheSun.mp3 HereComesTheTonic.mp3 21 | """ 22 | 23 | # Tonic plays only the beats of a song that are playing the tonic note! 24 | # It does this by getting a list of every segment in a track 25 | # Then, it checks to see which segments are playing the tonic. 26 | # Then, any beats that include those segments are added to a list. 27 | # This list is used to create the output track. 28 | 29 | ACCEPTED_UNITS = ["tatums", "beats", "bars"] 30 | 31 | def main(units, inputFile, outputFile): 32 | audiofile = audio.LocalAudioFile(inputFile) 33 | tonic = audiofile.analysis.key['value'] 34 | 35 | chunks = audiofile.analysis.__getattribute__(units) 36 | 37 | # Get the segments 38 | all_segments = audiofile.analysis.segments 39 | 40 | # Find tonic segments 41 | tonic_segments = audio.AudioQuantumList(kind="segment") 42 | for segment in all_segments: 43 | pitches = segment.pitches 44 | if pitches.index(max(pitches)) == tonic: 45 | tonic_segments.append(segment) 46 | 47 | # Find each chunk that matches each segment 48 | out_chunks = audio.AudioQuantumList(kind=units) 49 | for chunk in chunks: 50 | for segment in tonic_segments: 51 | if chunk.start >= segment.start and segment.end >= chunk.start: 52 | out_chunks.append(chunk) 53 | break 54 | 55 | out = audio.getpieces(audiofile, out_chunks) 56 | out.encode(outputFile) 57 | 58 | if __name__ == '__main__': 59 | import sys 60 | try: 61 | units = sys.argv[-3] 62 | inputFilename = sys.argv[-2] 63 | outputFilename = sys.argv[-1] 64 | except: 65 | print usage 66 | sys.exit(-1) 67 | if not units in ACCEPTED_UNITS: 68 | print usage 69 | sys.exit(-1) 70 | main(units, inputFilename, outputFilename) 71 | -------------------------------------------------------------------------------- /tutorial/stretch/beatshift.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | beatshift.py 5 | 6 | Pitchshift each beat based on its position in the bar. 7 | Beat one is unchanged, beat two is shifted down one half step, 8 | beat three is shifted down two half steps, etc. 9 | 10 | Created by Ben Lacker on 2009-06-24. 11 | Refactored by Thor Kell on 2013-03-06. 12 | """ 13 | 14 | # Import other things 15 | import numpy 16 | import os 17 | import random 18 | import sys 19 | import time 20 | 21 | # This line imports remix! 22 | from echonest.remix import audio, modify 23 | 24 | usage = """ 25 | Usage: 26 | python beatshift.py 27 | Exampel: 28 | python beatshift.py CryMeARiver.mp3 CryMeAShifty.mp3 29 | """ 30 | 31 | # Beatshift changes the pitch of each beat! 32 | # It does this by looping over the component beats of the track. 33 | # Then, it pitchshifts each beat relative to it's position in the bar 34 | # This pitch-shifted beat is added to a list. 35 | # That list is then used to create the output audio file. 36 | 37 | def main(input_filename, output_filename): 38 | # Just a local alias to the soundtouch library, which handles the pitch shifting. 39 | soundtouch = modify.Modify() 40 | 41 | # This takes your input track, sends it to the analyzer, and returns the results. 42 | audiofile = audio.LocalAudioFile(input_filename) 43 | 44 | # This gets a list of every beat in the track. 45 | # You can manipulate this just like any other Python list! 46 | beats = audiofile.analysis.beats 47 | 48 | # This creates a new chunk of audio that is the same size and shape as the input file 49 | # We can do this because we know that our output will be the same size as our input 50 | out_shape = (len(audiofile.data),) 51 | out_data = audio.AudioData(shape=out_shape, numChannels=1, sampleRate=44100) 52 | 53 | # This loop pitch-shifts each beat and adds it to the new file! 54 | for i, beat in enumerate(beats): 55 | # Pitch shifting only works on the data from each beat, not the beat objet itself 56 | data = audiofile[beat].data 57 | # The amount to pitch shift each beat. 58 | # local_context just returns a tuple the position of a beat within its parent bar. 59 | # (0, 4) for the first beat of a bar, for example 60 | number = beat.local_context()[0] % 12 61 | # Do the shift! 62 | new_beat = soundtouch.shiftPitchSemiTones(audiofile[beat], number*-1) 63 | out_data.append(new_beat) 64 | 65 | # Write the new file 66 | out_data.encode(output_filename) 67 | 68 | # The wrapper for the script. 69 | if __name__ == '__main__': 70 | import sys 71 | try: 72 | # This gets the filenames to read from and write to. 73 | input_filename = sys.argv[1] 74 | output_filename = sys.argv[2] 75 | except: 76 | # If things go wrong, exit! 77 | print usage 78 | sys.exit(-1) 79 | main(input_filename, output_filename) 80 | -------------------------------------------------------------------------------- /tutorial/stretch/cycle_dirac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | cycle.py 5 | 6 | Periodically time-compress and timestretch the beats in each measure. 7 | Things start fast and ends slow. 8 | This version uses the dirac timestretching library. 9 | It is slower than SoundTouch, but is higher quality. 10 | 11 | Created by Thor Kell on 2013-05-06, based on code by Ben Lacker. 12 | """ 13 | # Import other things 14 | import math 15 | import os 16 | import sys 17 | # Import the timestretching library. 18 | import dirac 19 | # This line imports remix! 20 | from echonest.remix import audio 21 | 22 | usage = """ 23 | Usage: 24 | python cycle.py 25 | Exampel: 26 | python cycle.py CryMeARiver.mp3 CryCycle.mp3 27 | """ 28 | 29 | # Cycle timestreches each beat! 30 | 31 | # Remix has two timestreching libraries, dirac and SoundTouch. 32 | # This version uses the dirac timeScale function. 33 | # Dirac is slower, but higher quality. 34 | 35 | # Cycle works by looping over every bar and beat within each bar. 36 | # A stretch ratio is calculate based on what beat and bar it is. 37 | # Then the data is timestretched by this ratio, and added to the output. 38 | 39 | def main(input_filename, output_filename): 40 | # This takes your input track, sends it to the analyzer, and returns the results. 41 | audiofile = audio.LocalAudioFile(input_filename) 42 | 43 | # This gets a list of every bar in the track. 44 | bars = audiofile.analysis.bars 45 | 46 | # The output array 47 | collect = [] 48 | 49 | # This loop streches each beat by a varying ratio, and then re-assmbles them. 50 | for bar in bars: 51 | # Caculate a stretch ratio that repeats every four bars. 52 | bar_ratio = (bars.index(bar) % 4) / 2.0 53 | # Get the beats in the bar 54 | beats = bar.children() 55 | for beat in beats: 56 | # Find out where in the bar the beat is. 57 | beat_index = beat.local_context()[0] 58 | # Calculate a stretch ratio based on where in the bar the beat is 59 | ratio = beat_index / 2.0 + 0.5 60 | # Note that dirac can't compress by less than 0.5! 61 | ratio = ratio + bar_ratio 62 | # Get the raw audio data from the beat and scale it by the ratio 63 | # dirac only works on raw data, and only takes floating-point ratios 64 | beat_audio = beat.render() 65 | scaled_beat = dirac.timeScale(beat_audio.data, ratio) 66 | # Create a new AudioData object from the scaled data 67 | ts = audio.AudioData(ndarray=scaled_beat, shape=scaled_beat.shape, 68 | sampleRate=audiofile.sampleRate, numChannels=scaled_beat.shape[1]) 69 | # Append the new data to the output list! 70 | collect.append(ts) 71 | 72 | # Assemble and write the output data 73 | out = audio.assemble(collect, numChannels=2) 74 | out.encode(output_filename) 75 | 76 | 77 | # The wrapper for the script. 78 | if __name__ == '__main__': 79 | import sys 80 | try: 81 | # This gets the filenames to read from and write to. 82 | input_filename = sys.argv[1] 83 | output_filename = sys.argv[2] 84 | except: 85 | # If things go wrong, exit! 86 | print usage 87 | sys.exit(-1) 88 | main(input_filename, output_filename) 89 | 90 | -------------------------------------------------------------------------------- /tutorial/stretch/cycle_soundtouch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | cycle.py 5 | 6 | Periodically time-compress and time-stretch the beats in each measure. 7 | Each measure starts fast and ends slow. 8 | This version uses the SoundTouch timestretching library. 9 | It is faster than dirac, but is lower quality. 10 | 11 | Created by Ben Lacker on 2009-06-16. 12 | Refactored by Thor Kell on 2013-03-06. 13 | """ 14 | import math 15 | import os 16 | import sys 17 | 18 | from echonest.remix import audio, modify 19 | 20 | usage = """ 21 | Usage: 22 | python cycle.py 23 | Exampel: 24 | python cycle.py CryMeARiver.mp3 CryCycle.mp3 25 | """ 26 | 27 | # Cycle timestreches each beat! 28 | 29 | # Remix has two timestreching libraries, dirac and SoundTouch. 30 | # This version uses the SoundTouch timeScale function. 31 | # SoundTouch is faster, but lower quality. 32 | # Cycle works by looping beat within each bar. 33 | # A stretch ratio is calculate based on what beat it is. 34 | # Then the data is timestretched by this ratio, and added to the output. 35 | 36 | def main(input_filename, output_filename): 37 | # This takes your input track, sends it to the analyzer, and returns the results. 38 | audiofile = audio.LocalAudioFile(input_filename) 39 | 40 | # Just a local alias to the soundtouch library, which handles the pitch shifting. 41 | soundtouch = modify.Modify() 42 | 43 | # This gets a list of every bar in the track. 44 | # You can manipulate this just like any other Python list! 45 | beats = audiofile.analysis.beats 46 | 47 | # The output array 48 | collect = [] 49 | 50 | # This loop streches each beat by a varying ratio, and then re-assmbles them. 51 | for beat in beats: 52 | # Find out where in the bar the beat is, and calculate a ratio based on that. 53 | context = beat.local_context() 54 | ratio = (math.cos(math.pi * 2 * context[0]/float(context[1])) / 2) + 1 55 | # Stretch the beat! SoundTouch returns an AudioData object 56 | new = soundtouch.shiftTempo(audiofile[beat], ratio) 57 | # Append the stretched beat to the list of beats 58 | collect.append(new) 59 | 60 | # Assemble and write the output data 61 | out = audio.assemble(collect) 62 | out.encode(output_filename) 63 | 64 | 65 | # The wrapper for the script. 66 | if __name__ == '__main__': 67 | import sys 68 | try: 69 | # This gets the filenames to read from and write to. 70 | input_filename = sys.argv[1] 71 | output_filename = sys.argv[2] 72 | except: 73 | # If things go wrong, exit! 74 | print usage 75 | sys.exit(-1) 76 | main(input_filename, output_filename) 77 | -------------------------------------------------------------------------------- /welcome.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1187 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \margl1440\margr1440\vieww10800\viewh8400\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural 6 | 7 | \f0\fs24 \cf0 Welcome to The Echo Nest Remix API installer!\ 8 | \ 9 | This will install Python libraries that let you do great things with music and video. The libraries will be installed in your Python site-packages folder and will be available system-wide. Full documentation can be found at {\field{\*\fldinst{HYPERLINK "http://echonest.github.com/remix/"}}{\fldrslt http://echonest.github.com/remix/}}\ 10 | \ 11 | You'll probably want to start with example scripts: these are placed in /usr/local/share/echo-nest-remix-examples.\ 12 | \ 13 | You will need an API key set up to use this software. Register for a key at http://developer.echonest.com/ .\ 14 | \ 15 | Then either (1) set the environment variable ECHO_NEST_API_KEY to be your key, or (2) put the lines\ 16 | \ 17 | from pyechonest import config\ 18 | config.ECHO_NEST_API_KEY="your key" \ 19 | \ 20 | at the top of any scripts you run.\ 21 | \ 22 | Please see more information and documentation at {\field{\*\fldinst{HYPERLINK "http://echonest.github.com/remix/"}}{\fldrslt http://echonest.github.com/remix}}, and happy remixing!\ 23 | } --------------------------------------------------------------------------------