Code Monkey home page Code Monkey logo

midica's Introduction

Get Started | Features | Screenshots | Programming | CLI | Contribute | License

Midica is an interpreter for a Music Programming Language. It translates source code to MIDI.

But it can also be used as a MIDI Player, MIDI compiler or decompiler, Karaoke Player, ALDA Player, ABC Player, LilyPond Player or a MIDI File Analyzer.

You write music with one of the supported languages (MidicaPL, ALDA or ABC).

The built-in music programming language MidicaPL supports the same techniques as regular programming languages, like:

  • Variables and Constants
  • Functions
  • Loops
  • Conditions (if/elsif/else)
  • Including Libraries
  • Code Comments

You write your songs in plain text files using the text editor of your choice. Midica converts these files into MIDI or plays them directly.

Get started

  1. Install Java Runtume Environment (JRE) version 1.7 or higher.
  2. Go to the latest release and download the file midica.jar.
  3. Start Midica using the command: java -jar midica.jar (or just by double-click if your operating system supports that)
  4. Download one of the example files or create your own file and save it with the file extension .midica.
  5. In the Midica application, load this file by pressing the upper right button select file.
  6. Switch to the MidicaPL tab (it's the default tab) and choose this file.
  7. Press the button Start Player and play the sequence

If you prefer to write your music in ALDA or ABC, you need to:

  • Install ALDA or abcMIDI
  • In Step 4: Download an ALDA example or ABC example or create your own file with the extension .alda or .abc.
  • In Step 6: Switch to the ALDA or ABC tab (and maybe adjust the program path).

Features of the Midica Application itself

  • Loading and playing MIDI sequences from:
    • MidicaPL files
    • MIDI files
    • ALDA files (if ALDA is installed)
    • ABC files (if abcMIDI is installed)
    • LilyPond files (if LilyPond is installed)
    • MusicXML, MuseScore, Guitar Pro, Capella, Bagpipe Music Writer, Sonicscores (Overture / Score Writer), PowerTab (if MuseScore is installed)
  • Exporting MIDI sequences
    • As MIDI files
    • As MidicaPL files (experimental)
    • As ALDA files (experimental)
    • As Audio files (wav, au, snd, aiff, aifc)
    • As ABC files (if midi2abc is installed)
    • As Lilypond files (if midi2ly is installed)
    • As PDF, PNG, SVG, FLAC, OGG, MP3, MXL, MusicXML or MSCX (if MuseScore is installed)
  • Integrated MIDI player featuring:
    • Regulation of volume, tempo and pitch transposition
    • Memorizing a position in the MIDI sequence and jumping back to that position
    • Channel Overview (showing current instrument and channel activity)
    • Channel Detail viewer (Note name and number, volume and tick, channel by channel)
    • Channel configuration (Volume, Mute and Solo configurable channel by channel)
    • Quick reloading and reparsing of a loaded file
  • Karaoke Player
    • Integrated as a part of the MIDI player
    • displaying syllables in different colors for future and past
    • displaying syllables in italic, shortly before they must be sung
  • Converter
    • converts various formats to MIDI (MidicaPL, ALDA, ABC, LilyPond, MusicXML, MuseScore, Guitar Pro, Capella, Bagpipe, Overture, Score Writer, PowerTab)
    • converts MIDI to various formats (MidicaPL, ALDA, Audio, ABC, Lilypond, MuseScore, MusicXML and others)
  • Soundbanks
    • Loading Soundfonts (SF2) or Downloadable Sounds (DLS) and using them for playback
      • either from an SF2 or DLS file
      • or via download (with caching, both formats work)
    • Analyzing Soundbank contents
    • Test Soundbanks with the Soundcheck window
    • Using the loaded soundbank for Audio exports
  • Configuration of
    • GUI language (currently English or German)
    • Note System - (6 different systems), e.g. International (C,D,E,F,G,A,B), German (C,D,E,F,G,A,H), Italian (Do,Re,Mi,Fa,Sol,La,Si)
    • Half Tone Symbols (3 different sets)
    • Octave Naming - 4 different systems
    • Syntax (3 different sets of key words for the programming language) - not that important as the syntax can be redefined in MidicaPL anyway
    • Percussion IDs (English or German)
    • Instrument IDs (English or German)
    • Key bindings

Screenshots

You can find a lot of screenshots here: https://www.midica.org/screenshots.html

I will not repeat them all in this Readme. But at least here are three screenshots. The first one shows the main window. The second one shows the player in default mode. The third one shows the player in Karaoke mode.

Programming with Midica

Midica has its own Music Programming Language: MidicaPL. But alternatively you can also code in ALDA or ABC.

For learning, each language has its own resources:

Here we focus on MidicaPL. For a quick reference, here are the links to the main chapters of the MidicaPL tutorial:

Examples of complete songs can be found in the examples directory. In this Readme we just show some short examples to get an impression of the language.

Example 1

This example uses only one channel and lyrics:

// use Piano in channel 0
INSTRUMENTS
	0  ACOUSTIC_GRAND_PIANO  Piano
END

// Every line beginning with "0:" defines events in channel 0
0: (v=95)                   // (...=...) set an option to a value; v = velocity; 95 = forte
0: (l=Hap) c:8.             // (l=...) defines a syllable. "c:8." = dotted eighth middle C
0: (l=py_) c:16             // _ = space; c:16 = sixteenth middle C

// More special characters in syllables:  \c = comma, \r = new line, \n = new paragraph
0: (l=birth) d:4 (l=day_) c (l=to_) f (l=you\c\r) e:2   (l=Hap) c:8. (l=py_)   c:16
0: (l=birth) d:4 (l=day_) c (l=to_) g (l=you.\n)  f:2   (l=Hap) c:8. (l=py...) c:16

This results in a MIDI sequence like this:

Example 2

This example uses nestable blocks and global commands:

// initialize channel 0 and 1
INSTRUMENTS
    0  ACOUSTIC_GRAND_PIANO  Piano (Right Hand)
    1  ACOUSTIC_GRAND_PIANO  Piano (Left Hand)
END

*  key    d/min            // key signature
*  time   3/4              // time signature
*  tempo  170              // tempo in beats per minute

{ q=2                      // outer block to be repeated twice
    { q=3                  // inner block to be repeated 3 times
        
        // in channel 1: switch to mezzo piano (v=70) and play D3 as an 8th note
        1: | (v=70)  d-:4   // the pipe "|" checks for measure borders (optional)
        
        // in channel 0: switch to mezzo piano and play some notes and rests ("-" = rest)
        0: | (v=70)  d:8 - d eb d eb |
        
        // synchronize: bring all channels to the same time
        *
    }
    
    1:  d-:4  f-  c-
    0:  d:8   -   d   eb  f  eb
}

This results in a MIDI sequence like this:

Instead of the nested blocks we could have written this equivalent code:

0: (v=70) | d:8 - d eb d eb | d - d eb d eb | d - d eb d eb | d - d eb f eb |
0:        | d:8 - d eb d eb | d - d eb d eb | d - d eb d eb | d - d eb f eb |
1: (v=70) | d-:4 -:/2       | d-:4 -:/2     | d-:4 -:/2     | d-:4  f-  c-  |
1:        | d-:4 -:/2       | d-:4 -:/2     | d-:4 -:/2     | d-:4  f-  c-  |

Example 3

This example uses a guitar picking pattern with several chords. It produces the beginning of "Dust in the wind":

// use the guitar in channel 0
INSTRUMENTS
	0  STEEL_GUITAR Guitar
END

// define some chords
CHORD cmaj   c-  e- g- c
CHORD cmaj7  c-  e- g- b-
CHORD cadd9  c-  e- g- d
CHORD asus2  a-2 e- a- b-
CHORD asus4  a-2 e- a- d
CHORD amin   a-2 e- a- c

// Define the picking pattern (Travis picking)
// The numbers inside the pattern aren't channel numbers but note indices
PATTERN travis
    : 0,3:4  1:8 2 0 3 1 2
END

// play the chords using this pattern
0: | cmaj:travis  | cmaj7:travis | cadd9:travis | cmaj:travis  |
0: | asus2:travis | asus4:travis | amin:travis  | asus2:travis |

This results in the following sequence:

Example 4

This example uses functions and percussion instruments.
It produces the first beats of "Another one bites the Dust":

// Use bass in channel 5
// Drums are always in channel 9 (automatically)
INSTRUMENTS
    5  E_BASS_FINGER  Bass
END

// anacrusis
* time 1/8
5: (d=30%) a-2:16  g-2              // d=30% --> staccato

// regular bars
* time 4/4
CALL drum-and-bass(bar=1)
CALL drum-and-bass(bar=2) q=2       // q=quantity, so the function will be called twice

FUNCTION drum-and-bass
    CALL bassline(${bar})
    CALL drums  q=4                 // "drums()" is called 4 times without parameters
END

FUNCTION bassline
    5:        e-2:4 e-2 e-2 -:8. e-2:16     e-2:8 e-2 g-2 e-2:16 a-2
    { if $[0] == 1
        5:    -:4+8  a-2:16 g-2
    }
    { else
        5:    -:2
    }
END

// p = 9 = percussion channel
// hhc = hi-hat-closed, bd1 = base-drum-1, sd1 = snare-drum-1
FUNCTION drums
    p:   (v=127) hhc,bd1:8    (v=80) hhc   (v=127) hhc,bd1,sd1   (v=80) hhc
END

The resulting sequence looks like this:

Command Line Interface

By default (without arguments) Midica is started in GUI mode. But you can provide command line arguments:

java -jar midica.jar [ARGUMENTS]

You can see all available arguments with --help:

java -jar midica.jar --help

This explains which arguments are available and how they work:

ARGUMENTS:
--help                : Print this message.
--cli                 : Run in CLI mode (command line interface) without GUI.
                        Exits after all CLI related work is done.
--keep-alive          : Don't exit, even if --cli has been used.
                        Mainly used for unit tests.
--ignore-local-config : Doesn't use local config file. Use default config.
                        Without this argument the config is read from and
                        written into the file '.midica.conf' in the current
                        user's home directory.
--soundbank=PATH      : Use the specified soundbank file (.sf2 or .dls).
--soundbank=URL       : Use the specified soundbank URL (SF2 or DLS).
--import=PATH         : Import from the specified MidicaPL file.
--import-midi=PATH    : Import from the specified MIDI file.
--import-alda=PATH    : Import from the specified ALDA file by calling the
                        alda program. (ALDA needs to be installed.)
--import-abc=PATH     : Import from the specified ABC file by calling
                        abc2midi. (abcMIDI needs to be installed.)
--import-ly=PATH      : Import from the specified LilyPond file by calling
                        lilypond. (LilyPond needs to be installed.)
--import-mscore=PATH  : Import from the specified file using MuseScore
                        (MuseScore needs to be installed.)
--export-midi=PATH    : Export to the specified MIDI file.
--export=PATH         : Export to the specified MidicaPL file. (*)
--export-alda=PATH    : Export to the specified ALDA file. (*)
--export-audio=PATH   : Export to the specified audio file.
                        (Supported file Extensions: .wav, .au, .aif, .aiff)
--export-abc=PATH     : Export to the specified ABC file by calling
                        midi2abc. (abcMIDI needs to be installed.)
--export-ly=PATH      : Export to the specified Lilypond file by calling
                        midi2ly. (Lilypond needs to be installed.)
--export-mscore=PATH  : Export to the specified file using MuseScore.
                        (MuseScore needs to be installed.)

(*) A file is exported to STDOUT if the export PATH is a dash (-).
    E.g. --export=-

Contributing

If you want to contribute, please check the Readme file for Developers.

License

The main part of Midica is published under the MPL 2.0 (Mozilla Public License Version 2.0).

The following third-party software is also included:

midica's People

Contributors

truj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

midica's Issues

Add nestable anonymous blocks supporting options

Something like a macro but without a name that supports the options "quantity" and "multiple".
So that you could write something like:

( q=5
    command
    command
        ( m, q=2
            command
            command
        )
        command
)

add sound effects

Something more or less like this:
channel effect:what/function duration options
E.g. for a pitch band change affecting the whole channel:
0 effect:pitchband/sinus /2 amplitude=20, wavecount=2.5
Or for a polyphonic aftertouch graph affecting only one note:
0 effect:polypressure/line /2 from=-5, to=15, note=c+

Staccato option to legato

Rename staccato to legato (or something similar).
Find a good short name. ('l' is not good because it's planned for lyrics later.)
Rewrite the code accordingly, using:
legato(new) = 1.0 - staccato(old)

Reason:
Than we have a value range from 0 to +infinite. That's much more natural.
That's much more intuitive than minus infinite to +1.0
The negative staccato values are not intuitive, and it's hard to calculate what happens.

globalize macros

Add a pre-parsing run to the MidicaPL parser, only for parsing MACRO definitions.
Then a macro can be called before it is defined.

add new octave naming system

Currently the default is:

c-----
c----
c---
c--
c-
c
c+
c++
...
c+++++

That's not very readable.
Instead of that, implement the following one:

c-5
c-4
c-3
c-2
c-
c
c+
c+2
c+3
...

This should also be the new default.
Additionally:

  • adjust all unit tests
  • adjust readme file
  • adjust example file (or replace it completely by something better)

add transposition option

Add an option for block and include commands to transpose the content by an arbitrary number of half tone steps.
The option name should be shift (short form s) because for transpose there is no reasonable short form available. (t and tr are already used.)

e.g.:

INCLUDE macro shift=-12 // transposed 1 octave lower
( s=12
    ... // transposed 1 octave higher
    ( s=12
        ... // transposed 2 octaves higher
    )
)

read karaoke lyrics only from one single track

Problem:

Currently the karaoke player reads lyrics information from no matter which track. But there are songs containing text/lyrics in different tracks.
This can have different reasons, e.g.:

  • there are different karaoke formats in one song
  • one track contains lyrics, the other one other information

This leads to broken lyrics.

Solution:

  • develop a strategy to find out which track to be regarded as the karaoke track
  • use text/lyrics for karaoke only from this track

Idea for the strategy:

  • check if one of the included formats is soft karaoke, and use the according track, if yes
  • otherwise: count text/lyrics events by track and choose the one with the highest number

Moreover:

  • For the sake of readability, maybe move karaoke parsing away from the SequenceAnalyzer to a new class.

Add tremolo option

Add a tremolo option for channel commands
Example:
0 c /1 tremolo=/8
for tremolo-ing a full note with 8ths

implement a stack trace

The stack trace should be shown on errors MidicaPL parsing.
It should contain:

  • function call information (function name, file, line, parameters, options)
  • nestable block information (file, line, block options)
  • line content, file and number
  • maybe file include information (included from file..., line...)

enable tuplets as block parameters

instead of lowlevel tuplet modifiers on channel command level, also enable tuplets as a nestable block parameter.
e.g.

( t=3:2
    command
    command
    ( t=5:4
        commnad
        commnad
    )
)

Add escape sequence for a comma in lyrics syllables

Currently in the standard configuration it's not possible to include a comma in a lyrics inside of MidicaPL.
Reason: The comma is interpreted as an option separator before so it cannot be used inside a syllable.

Solution:
Add \c as escape sequence to encode commas.

Example:

0  c  /4  l=Hey\c_
0  c  /4  l=you!

This sould result in the lyrics Hey, you!.

add instrument changes in a single line

We need to be able to switch an instrument for a channel without using an INSTRUMENTS block.
Reasons: INSTRUMENTS blocks cannot be nested. But it should be possible to change instruments from inside a nestable block or a macro.

Add note filter in the soundcheck window

There should be a filter for the note/percussion list in the soundcheck window.
According to the table filters.
Maybe the list could be transformed to a table.
Or we need a JList filter.

Support soft karaoke in MidicaPL and in the decompiler

Standard MIDI Karaoke is already supported everywhere in Midica.
Soft Karaoke is currently only supported by the Analyzer and Player.
This causes problems if a Soft Karaoke file is decompiled, or if a MidicaPL file is exported as MIDI and used by software that expects soft karaoke.

  • Add some META tags for soft karaoke in MidicaPL
  • The syllables themselves must still be defined by the user
  • In the decompiler: check, if soft karaoke is used, and if yes: export the according META fields

support variables

Something like this should be possible:

VAR $channel = 0
$channel  c+  /4
VAR $channel = 1
$channel  c+  /4

Fix windows Problems

Tried out with windows for the first time and found a problem that doesn't occur on linux:
As long as no specific soundfont is loaded, the info button throws exceptions, and the info window doesn't open.
After loading a soundfont everything works.
Try again with windows, look at the stack trace and fix the error.

support if / elsif / else in block options

Support new options:

  • if <condition>
  • elsif <condition>
  • else

All these options should work as a block option for nestable blocks.
For convenience reasons, if should also work as a call option or a channel command option. But for elsif and else that does not make sense.

The condition part should support one boolean expression with 2 values and one operator between them. The following operators should be supported:

  • equals (e.g. ==)
  • not equals (e.g. !=)

Maybe the following operators could be supported as well:

  • lower (e.g. <)
  • lower or equal (e.g. <=)
  • higher (e.g. >)
  • higher or equal (e.g. >=)
  • defined (e.g. no operator and only one value)

More complicated boolean expressions could be implemented in the future but for now they are not yet needed. E.g. something like $a==$b||$c<5||$d

unify structures in the SequenceAnalyzer

Track controller and RPN values.
Use these structures to replace more specialized structures like the instrument history or the pitch bend sensitivity MSB/LSB histories.

Target:
This makes it easier to track more details.
It avoids to create a new data structure for each task.

Change Volume Definition

The main volume slider should change the master volume (using a SysEx message).
The channel volume sliders should change the according channel volume directly (not using a calculated value relative to the main volume any more).

show note details in analyzer

In the Midi Sequence analyzer / details field:

  • add a field for further information
  • in this field, add note details for the following message types:
    • note on
    • note off
    • key signature

legato corrections for d=100%

#12 addressed legato overlapping problems.
But the following is still wrong:
0 c /4 d=100%, q=2
In this case, the first note-off is in the same tick as the second note-on.
Move the note-off one tick to the past in this case.

Support function parameters

Rename MACRO to FUNCTION.
Rename INCLUDE to CALL.
Support named or unnamed parameters.
Example for named parameters:

FUNCTION test
    ${channel}   c  /4  v=${velocity}
END
CALL test(channel=4, velocity=100)  q=2

Example for unnamed parameters:

FUNCTION test
    $[0]   c  /4  v=$[1]
END
CALL test(4, 100)  q=2

The parameters shall still be optional.
The following calls are equivalent:

CALL func()
CALL func

make key bindings configurable

  • provide defaults in Config.java
  • main window: add a key binding config button that opens...
  • ... a new key binding config window
  • add a tab in the info window that shows all configured key bindings
  • add tooltips to the elements to be controlled by the key bindings, containing the according key binding

rearrange colors

Move all color definitions to the Config class.
Change colors to make the ui less ugly.

Reduce upper-cased syntax in the default

Only definition and execution commands should be upper-cased.
Tuplets, triplets and percussion shortcuts should be lower-cased.
Maybe percussion shortcuts could also be made shorter.

Add constants

Add the possibility to use variables.
Example:

var $forte = 120
var $staccato = duration=50%
...
0  c  /4  v=$forte
0  c  /4  $staccato

Fix compatibility problems with newer java versions

There are exceptions with java versions later than 8.
Since java 9 the package com.sun.media.sound doesn't exist any more.

  • fix the exceptions
  • replace using the classes of this package by something else
  • restore the according functionality somehow else

Enable Unit Tests

Use JUnit 5. Therefore Java 1.8 or higher is required. But apart from the tests the application could still be available in Java 1.7

Then include unit testing into the precommit hook.

add patterns for chords etc.

Something like this:

// define pattern
PATTERN my_pattern
    0      /4
    1      /8
    2      /8
    0,1,2  /4
END

// use the pattern instead of a note length
5   c,e,g   my_pattern
7   g,e,c   my_pattern

This should be equivalent to:

5  c      /4
5  e      /8
5  g      /8
5  c,e,g  /4
7  g      /4
7  e      /8
7  c      /8
7  g,e,c  /4

Don't allow legato overlappings for the same note

If the duration option is >1.0 and the same note in the same channel is played twice, the overlapping leads to the following sequence:

  • note-on
  • note-on
  • note-off
  • note-off
    For different notes or different channels that's no problem.
    But in the same channel with the same note, it should be avoided.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.