Audiobus: Use your music apps together.

What is Audiobus?Audiobus is an award-winning music app for iPhone and iPad which lets you use your other music apps together. Chain effects on your favourite synth, run the output of apps or Audio Units into an app like GarageBand or Loopy, or select a different audio interface output for each app. Route MIDI between apps — drive a synth from a MIDI sequencer, or add an arpeggiator to your MIDI keyboard — or sync with your external MIDI gear. And control your entire setup from a MIDI controller.

Download on the App Store

Audiobus is the app that makes the rest of your setup better.

Learn to Program the Mozaic Workshop to create MIDI FX and Controllers *you could learn something*

McDMcD
edited January 21 in General App Discussion

NOTE: You may use the Mozaic Workshop and never type in a line of text.
Just download and install existing scripts from:

https://patchstorage.com/platform/mozaic/

I'm going to teach you MIDI Programming in Mozaic with a series of typing exercises.
All you need to learn is a text editor but a pencil would also suffice to learn the concepts
involved.

Here's Exercise #1 called:

// EX 1: The MIDI Echo Effect

@OnMidiInput
  SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 0
  SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 1000
  SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 2000
@End

That's it! You've just typed a useful MIDI echo.

What does it do? Every line has a specific result:

OnMidiInput

Every MIDI event that passes through Mosaic with this typing loaded gets processed
by the next 3 Commands. Tap a note on a keyboard and 2 events are generated.

A Note on a specific with 3 values:
1. Channel that is available in Mosaic as MIDIByte1
2. A Note value that will be available as MIDIByte2
3. A Note Velocity that will be available as MIDIByte3

SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 0

This command takes the incoming MIDI event and sends it out (unchanged really).

SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 1000

This is the same command with an added 4th value. This value is a timing delay of
1000. That's 1000 milliseconds  and Mozaic will do the timing and send this out at the right time as echo #1.

SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 2000

This line sends out the 2nd echo with a 2,000 millisecond delay.

End

This tells Mozaic that this is all we need to do for each MIDI Input event.

You have just typed a usable and modifiable Mozaic script. You are a coder assuming you can type. (My typing is abysmal).

That's it for Exercise #1.

OPTIONAL FREE STYLE TYPING:

You can change the MIDI channel by adding or subtracting from MIDIByte1:
MIDIByte1 = MIDIByte1 + 1
For example. The same is true for Notes and Velocities in MIDIByte2 and MIDIByte 3.
Each echo could change the note or the volume for example with some extra typing.

If you want a lot more typing send each note out on all 16 channels. Can you ever get enough
typing practice?

«1345678

Comments

  • Thank you, much appreciated.

  • McDMcD
    edited January 11

    Here's Typing Exercise #2.

    // EX 2: Logging MIDI Events.

    @OnMidiInput
    
      SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3
      Log {MIDI Instruction+Channel: }, MIDIByte1, { Note: }, MIDIByte2, { Velocity: }, MIDIByte3
    
    @End
    

    That's it! You've just typed a useful MIDI Event Logger that prints the Event Data

    What does it do? Every line has a specific result:

    @OnMidiInput

    Every MIDI event that passes through Mosaic with this typing loaded gets processed
    by the next 2 Commands. Tap a note on a keyboard and 2 events are generated.

    A Note on a specific with 3 values:
    1. Channel that is available in Mosaic as MIDIByte1
    2. A Note value that will be available as MIDIByte2
    3. A Note Velocity that will be available as MIDIByte3
    SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3, 0

    SendMIDIOut MIDIByte1, MIDIByte2, MIDIByte3

    This command takes the incoming MIDI event and sends it out (unchanged really).

    Log {MIDI Instruction+Channel: }, MIDIByte1, { Note: }, MIDIByte2, { Velocity: }, MIDIByte3

    This command prints out the 3 MIDI Events details for every event.

    @End

    This tells Mozaic that this is all we need to do for each MIDI Input event.

    You have just typed a usable MIDI Logging Mozaic script.

    That's it for Exercise #2.

    INTERESTING MIDI DETAIL:
    I run Mozaic in AUM as a MIDI Effect and feed it events from the AUM Keyboard.

    The MIDI Channel shows up as the MIDI Command of "Note ON" plus the
    MIDI Channel. The code for a MIDI ON is 144 in Decimal and the default channel is 0.

    The following MIDI OFF's show up as MIDI ON events (144) but the velocity is set to 0. So the synths play a note of 0 volume which synth programmers know is really an OFF. There is an actual MIDI OFF event of 127, as I recall.

    Synth programmers are prepared to stop notes with either MIDI command coming in. Stopping Notes is really important and complex scripts take great pains to insure every Note Started gets a corresponding Note OFF event.

    Send event too fast to some synths and they will drop a NOTE OFF event and
    you'll need a MIDI Panic to fix it.

    Maybe we should learn to type a MIDI Panic so we don't need to type 16x127 MIDI Note Offs to insure there are no extra hanging notes. But we'd better send it out at a paced mode or we'll stress of synths again with a massive stream of events.

  • Thanks for these, @McD! I’m going to dig into this tomorrow.

  • This is great!
    Thank you for being a teacher. :)

  • You can also just copy the text out using a pencil and get the MIDI learning benefits.
    I should try it on an Apple Watch using the Notes app.

    I typed out the messages on a Mac.

    I think we should tackle "MIDI Rhythmic Note Repeating" next. You know the sample and hold note repeating feature linked to the DAW's metronome.

  • For typing in "Ex 3: Sample and Hold Repeating" script we need to learn a couple more MIDI/Script Events:

    @OnLoad - a block of commands that run everytime the script gets loaded. But just once.

    @OnMetroPulse - an event that Mozaic creates for us that happens in perfect timing with the DAW's metronome. It has a Mozaic setting that divides the metronome into even divisions: 1,2,3,4,5, etc.

    Our script to type in set the Metronome divisions to 4 per beat with PPQN (Pulses per Quarter-note of 4)

    SetMetroPPQN 4

    A MIDI Note in event will determine the channel, note and velocity to play of repeated notes until a new note in changes the Note value.

    The result is a pushing Note Repeater with a hard-coded note length of 100 milliseconds.
    Check this out... the commends typed so far should start to be readable.

    3 event blocks with 4 commands inside in total and we have a Sample and Hold Note Repeater script. Nice work Marvis Beacon!

    @OnLoad
    
      SetMetroPPQN 4
    
    @End
    
    @OnMidiInput
    
      Log {MIDI Instruction+Channel: }, MIDIByte1, { Note: }, MIDIByte2, { Velocity: }, MIDIByte3
    
    @End
    
    @OnMetroPulse
    
      SendMidiOut MIDIByte1, MIDIByte2, 100
      SendMidiOut MIDIByte1, MIDIByte2, 0, 100
    
    @End
    

    Of course you can change the PPQN's or even make many scripts with hardcoded 1,2,3,4,5, etc and start them all on different channels and point to different synths in a DAW using the sample basic code outline shown here.

    What we should do next is control the SetPPQN setting from an Input Knob. Yeah! Let's tweak some stuff Live. With enough typing you can have 8 knobs and tweaking:

    1. volumes
    2. PPQN
    3. octaves
    4. transposing notes
    5. channels out
    6. delay values
    7. additional note to strum #1
    8. additional note to strum #2

    And all it will cost is the time it takes to type it.
    I know you'd need Mozaic to hear it too. But it starts with typing and some MIDI knowledge and about Commands, Events and basic DAW stuff.

    OK. Next lesson "Knobs".

  • McDMcD
    edited January 11

    TIP: Relax when practicing typing... No "carpool tunnel syndrome" please.

  • McDMcD
    edited January 11

    Ex 4: Knob Input.

    OK. Type this one into any editor.

    @OnLoad
    
       ShowLayout 4
       LabelKnob 0, {PPQN=}, 3
       SetMetroPPQN 3
    
    @End
    
    @OnKnobChange
    
       if LastKnob = 0
          PPQN = GetKnobValue 0
          PPQN = Round (TranslateScale PPQN, 0,127, 1, 8)
          Log{PPQN: }, PPQN
          SetMetroPPQN PPQN
          LabelKnob 0, {PPQN=}, PPQN
       endif
    
    @End
    
    @OnMidiInput
    
      if MIDICommand = 0x90
        Log {Note On: }, MIDINote, { velocity: }, MIDIVelocity
        Byte1 = MIDIByte1
        Note = MIDINote
        Velocity1 = MIDIVelocity
        Note = MIDINote
      endif
    
    @End
    
    @OnMetroPulse
    
      SendMidiOut MIDIByte1, MIDIByte2, 100
      SendMidiOut MIDIByte1, MIDIByte2, 0, 100
    
      SendMidiOut MIDIByte1, MIDIByte2+7, 100
      SendMidiOut MIDIByte1, MIDIByte2+7, 0, 100
    
      SendMidiOut MIDIByte1, MIDIByte2+12, 100
      SendMidiOut MIDIByte1, MIDIByte2+12, 0, 100
    
    @End
    

    Lot's of new stuff here and we'll break it down line by line the way programmer's do. By adding comments into the code. First just type pure command text and down below I'll explain the purpose of every line using comments. If you're ready for a real Typing challenge type in the second commented version.

    And the commented version intended to help someone read the commands and understand the intention of the code. This is excessively commented to make each command clear to you. NOTE: aniline striating with "//" is a comment and doesn't
    generate any MIDI or Mozaic actions:

    // OnLoad code block
    @OnLoad
    
      // Select Mozaic's GUI layout option #4 with 4 Knobs
       ShowLayout 4
       // Label the 1st Knob with text "PPQN=3"
       LabelKnob 0, {PPQN=}, 3
       //Set the PPQN value to be 3 pulses per metronome click from the DAW
       SetMetroPPQN 3
    
    @End
    
    @OnKnobChange
    
       // Turn any of the 4 knobs and a KnobChange event is created and this block will run
       // We will only serve the changes on Knob 0 (the first one - upper row - left position)
       // We detect the active Knob with a Mozaic "If test Command"
       if LastKnob = 0
          // Reset the new PPQN to match the Knob dial setting - values 0-127
          PPQN = GetKnobValue 0
          // Convert the 0-127 possible settings into the numbers 1-8
          PPQN = Round (TranslateScale PPQN, 0,127, 1, 8)
          // Log there new PPQN value
          Log{PPQN: }, PPQN
          // Reset the PPQN to the new dialed setting
          SetMetroPPQN PPQN
          // Change the Knob Label to match the new PPQN
          LabelKnob 0, {PPQN=}, PPQN
       endif
    
    @End
    
    // The block the detects the input MIDI notes ad saves the data for use in other blocks.
    @OnMidiInput
    
      // This is something new for a MIDI Note event
      // We are testing to see if the new event is actually a MIDI Note ON
      // Any other MIDI Input will just not get processed
      if MIDICommand = 0x90
        // Let's log these NOTE ON "note" and "velocity" values
        Log {Note On: }, MIDINote, { velocity: }, MIDIVelocity
        //Copy the new values into Variables
        Byte1 = MIDIByte1
        Note = MIDINote
        Velocity1 = MIDIVelocity
      // end of the "if" positive command block
      endif
    
    @End
    
    
    // This is the block that plays the Notes with the DAW's metronome settings.
    // Divided by the Knob 0 setting's PPQN value.
    @OnMetroPulse
    
      // On every PPQN Pulse - send out the NOTE ON ad OFF commands    
      SendMidiOut MIDIByte1, MIDIByte2, 100
      SendMidiOut MIDIByte1, MIDIByte2, 0, 100
    
      // And (this is new) add the parallel 5th musical note by adding 7 to every note
      SendMidiOut MIDIByte1, MIDIByte2+7, 100
      SendMidiOut MIDIByte1, MIDIByte2+7, 0, 100
    
      // And (this is new) add the octave up musical note by adding 12 to every note
      // 12 steps to every octave and the 5th of any note is 7 steps up  
      SendMidiOut MIDIByte1, MIDIByte2+12, 100
      SendMidiOut MIDIByte1, MIDIByte2+12, 0, 100
    
      // This is how 1 note generates "Chords" - Power Chords in this situation.
      // No major or minor 3rds to deal with. That comes later.
    
    @End
    

    I'm sure many will have questions but this definitely some good typing practice.
    Give yourself the rest of the day off. If I have totally lost you. We can do extra smaller
    steps to get here. I did note explain a lot of details about Variables and such and you may ask for smaller examples that do less but help explain in smaller chunks.

  • wow, @McD thanks so much for taking the time to make these lessons! this is exactly the friendly nudge I needed to get over my fear of coding.

  • edited January 11

    is there a free text editor for mac that you might recommend? I don't have a working bluetooth keyboard atm, so I'd rather code on the mac and then import to mozaic.

  • Cool idea and excellent realization for an introduction to midi scripting 👍🏻

  • @palms said:
    is there a free text editor for mac that you might recommend? I don't have a working bluetooth keyboard atm, so I'd rather code on the mac and then import to mozaic.

    I’m a massive fan of Visual Studio Code.
    https://code.visualstudio.com/

  • @Liquidmantis said:

    @palms said:
    is there a free text editor for mac that you might recommend? I don't have a working bluetooth keyboard atm, so I'd rather code on the mac and then import to mozaic.

    I’m a massive fan of Visual Studio Code.
    https://code.visualstudio.com/

    thanks!

  • Good idea here @McD.
    In your initial post for the log example I think you have a cut paste issue where the midi event line has the 1000 from the echo example.

  • @Moderndaycompiler said:
    Good idea here @McD.
    In your initial post for the log example I think you have a cut paste issue where the midi event line has the 1000 from the echo example.

    Thanks. The finer points of formatting is killing me.
    I just noticed the "Markdown" line below the editor. I'll bet there are "marks" to cover some
    of these weird presentation issues.

    I'd put this on the Wiki but who wants to write for 3 people? What Wiki?
    W4 = WWWW: The World Wide What Wiki?

    Wiki's are cool because you can make a link to define every term but what's really cool are
    group authored wiki's that read like MPD diaries. (See I could define MPD = Multi-pole Personality Disorders). Wiki-media made wiki's less fun... everyone was supposed to be able to edit. It trained us to wait for the "editor". So, we're waiting for Wiki editors to put up more stuff.

  • @_ki said:
    Cool idea and excellent realization for an introduction to midi scripting 👍🏻

    Thanks. I think about you every time I write something that could be done with fewer characters using Loops, arrays, etc. Feel free to share optimized versions of any example.

    The more people have sample code to read the easier it is to make that leap to reading/coding comprehension. We can't have too many examples.

    I learn everything from study the coding experts and using cut and paste. Eventually, I could write children's books. Someday I hope to produce some YA programs. I'll never reach the
    Pulitzer Prize level of coders but I don't care. Every the kiddy scripts make me feel like I'm a master of MIDI.

  • @horsetrainer said:
    This is great!
    Thank you for being a teacher. :)

    If you want to learn anything. Teacher it. You really only need to be a few months ahead of the student. And they appreciate that you might remember the parts that were difficult to get at first. After a few years you just say: RTFM.

    By the way the Mozaic Manual is really good at teaching MIDI essentials and explaining all the clever things @Brambos (the author of the manual and the app) did to make the hard things about MIDI easier.

    So, RTFM is important. Type out pages of it to be a really good typist and learn your MIDI/Mozaic fine points.

  • @Philandering_Bastard said:
    Thank you, much appreciated.

    You, philandering bastard, are very welcome. I've been eating for a chance to type that
    and slip one past the moderators for being a dick.

  • @Liquidmantis said:
    Thanks for these, @McD! I’m going to dig into this tomorrow.

    Late work will receive 1/2 credit. I should have mentioned this up front.
    Be advised. At least you're not tardy.

  • McDMcD
    edited January 11

    @palms said:
    wow, @McD thanks so much for taking the time to make these lessons! this is exactly the friendly nudge I needed to get over my fear of coding.

    "Friendly nudge"? We're not coding. We're typing. Coding is where I demand:

    ASSIGNMENT #1:
    Write a script that has 2 knobs.
    One changes the channel of note to a selected channel.
    Two transposes the MIDI by some increment up.
    Plagarism will be detected by our coding checking robots.
    DO YOUR OWN WORK.
    Have Fun!

    That would be coding and that should scare anyone that has never coded.
    Here's the secret to learn coding. Copy working code first. Good coders steal because the computer appreciates good code and hates the stuff that sends it to Albuquerque, turns right. "Should Have Turned Left at Albuquerque". Discuss. HINT: Bugs. Google it.

    NOTE: If you have a short working piece of code please share it here. More code, more typing exercises for those just wanting the practice. My typing is abysmal. Not unlike my coding. So, kill 2 birds and call me in the morning.

  • Amazing. I’ve been very recently considering diving into Mozaic, so thanks so much for starting this thread. Favourited so I can follow.

    +8 :)

  • @ahallam said:
    Amazing. I’ve been very recently considering diving into Mozaic, so thanks so much for starting this thread. Favourited so I can follow.

    No diving please. Just put a foot in the water until the water wings arrive in the book store.
    FYI: "U" misspelled a word. Why do you folks say Al-you-minium? Do you always phoneticize the vowels. God save the Cue-You-Ee-Ee-En? It sounds phoney to Yanks. We continue to bastardize the language... LOL. S'up.

  • @McD said:

    @ahallam said:
    Amazing. I’ve been very recently considering diving into Mozaic, so thanks so much for starting this thread. Favourited so I can follow.

    No diving please. Just put a foot in the water until the water wings arrive in the book store.
    FYI: "U" misspelled a word. Why do you folks say Al-you-minium? Do you always phoneticize the vowels. God save the Cue-You-Ee-Ee-En? It sounds phoney to Yanks. We continue to bastardize the language... LOL. S'up.

    Haha. I’m familiar with code, having spent a little time with both Processing and Python. Just thought Mozaic would provide a venue to look at things yet another time.

    Also, we Canucks say Al-OOOOOO-minum, just like everyone else. :)

  • @ahallam said:
    Haha. I’m familiar with code, having spent a little time with both Processing and Python.

    Cool. The hard thing for me was thinking about event driven designs. You really submit
    "Work Requests" to the @Brambos interpreter that queues up your requests and manages the complex timing details.

    When people actually run the Echo and play a slurry of notes they will be astonished that every single note echos. "I did that?" (No. @Brambos just gave you a MIDI flow tool for $8).

    Still, it gets better from there. You get GUI templates and Sysex routines and all the impossibly hard stuff that Swift forces you to get right. Not that anyone can't learn Swift too.
    Just copy working code until the concepts get embedded in your neural net.

  • @McD said:

    @Philandering_Bastard said:
    Thank you, much appreciated.

    You, philandering bastard, are very welcome. I've been eating for a chance to type that
    and slip one past the moderators for being a dick.

    I aim to serve.

  • @Philandering_Bastard said:
    I aim to serve.

    Aiming appreciated. Some people just piss all over the floor around here.

  • McDMcD
    edited January 11

    Ex 5: The @Description block

    Type in this one:

    @Description
    
    You may type virtually anything in this block of text. But for maintenance reasons it wise to
    start with:
    
    The Script Name and this version of the code. Like:
    MIDI Genie v1.3
    
    The user of the script will have access to this text so you can also include some usage
    details. Like:
    Knob 1 (which in the script we call Knob 0 - long story) = Sets the Pulses Per Metronome Rate
    Knob 2 = undefined - Don't break it. We'll need it later
    Knob 3 = Hmm... how are they numbered in the GUI?
    Knob 4 = Finally.
    Knob 5 = a hidden secret Knob that deletes your email intray. Doesn't work yet.
    
    @End
    
    @OnLoad
    
      // Select Mozaic's GUI layout option #4 with 4 Knobs
       ShowLayout 4
       // Label the 1st Knob with text "PPQN=3"
       LabelKnob 0, {PPQN=}, 3
       //Set the PPQN value to be 3 pulses per metronome click from the DAW
       SetMetroPPQN 3
    
    @End
    
  • @McD said:

    @Philandering_Bastard said:
    I aim to serve.

    Aiming appreciated. Some people just piss all over the floor around here.

    No kidding.

  • Ex 6: Sending CC Commands

    From page 26 of the manual:

    @OnLoad
       ShowLayout 1
       LabelKnob 0, {Volume}
    @End
    
    @OnKnobChange
    if LastKnob = 0
    setting = GetKnobValue 0
          SendMIDICC 0, 7, setting // send out CC#7 on channel 0
       endif
    @End
    

    The only new command is:

    `SendMIDICC 0, 7, setting // send out CC#7 on channel 0

    `
    See how @Barmbos adds that comment at the end of the command line? That's legal.
    Confusing at first until you learn to see "//" as "Let's talk, gentle reader."

    Notice the pattern of channel then data. We can code the channel in a variable and tie the
    specific channel out to a Knob too. By default Knobs swing from 0 to 127. It's that start from 0 thing again. Sometimes MIDI docs will list options from 1-128 and mayhem ensues. It cam make for tricky debugging to understand you are sending a 10 but the device expects 11 to do the thing you desire. I had this issue with Program Changes but that was easy to see that everything was off by 1. Sending on the wrong channel will definitely make hardware break.

    So, watch out for the ZERO is ONE confusion with MIDI.

    Wait until you hear about "Middle C". Another story for another day. Maybe when we
    learn to play our scales. Mozaic knows all the cool scales already like "Melodic Minor Friggin' Pentagrams" and shit. Really. Suitable for Satanic Ritual Raves. More to come.

  • McDMcD
    edited January 12

    EX 7: Tips from a Professional Programmer

    @_Ki is a graduate level degreed programmer that codes for a living. But he likes music production and hanging out with other Music Lovers. It's surprising how many programmers are also musicians. And conversely how many non-programming musicians can make a living.

    Here's how @_Ki names his vegetables (misspelled intentionally... who eats vegetables?):

    variables are In CamelCase
    _localVariables are _Camelcase starting with _
    CONSTANTS_ALL_CAPS
    pParametersCamelCase starting with lowercase p for user event parameters

    CamelCase is the idea that each distinct word in capitalized so you get the random hump look like the middle eastern Uber.

    Here's an example @_ki wrote to change the PAD lights on an Akai:

    // Code untested since i don't own a Arturia MiniLab mkII
    
    @OnLoad
      Call @InitSysexMessage
    
      for pPad = 0 to 15
        pCol = COL_YELLOW
        Call @SetPadColor
      endfor
    
      pCCVal = 64
      for pKnob = 0 to 17
        Call @SetKnobCC 
      endfor
    @End
    
    @InitSysexMessage
      //           black, red, green,yellow,blue,magenta,cyan, white
      colorVal[] = [0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x7F]
      sysPad[] = [ 0x00, 0x20, 0x6B, 0x7F, 0x42, 0x02, 0x00, 0x10, 0x00, 0x00]
    
      COL_BLACK   = 0
      COL_RED     = 1
      COL_GREEN   = 2
      COL_YELLOW  = 3
      COL_BLUE    = 4
      COL_MAGENTA = 4
      COL_CYAN    = 6
      COL_WHITE   = 7
    
      // List of controler ids
      controler[00] = [0x30, 0x01, 0x02, 0x09, 0x0B, 0x0C, 0x0D, 0x0E] // knobs 1-8
      controler[08] = [0x33, 0x03, 0x04, 0x0A, 0x05, 0x06, 0x07, 0x08] // knobs 9-16
      controler[16] = [0x32, 0x35] //  Shift knob1 and shift knob 9
    
      sysCCVal[] = [0x00, 0x20, 0x6B, 0x7F, 0x42, 0x02, 0x00, 0x00, 0x00, 0x00]
    @End
    
    @SetPadColor // pPad, pCol
      sysPad[8] = 0x70 + pPad
      sysPad[9] = colorVal[pCol]   // 0 = black  to  7 = white
      SendSysex sysPad, 10
    @End
    
    @SetKnobCC // pKnob, pCCVal
      sysCCVal[8] = controler[pKnob]
      sysCCVal[9] = pCCVal
      SendSysex sysCCVal, 10
    @End
    

    That's some excellent typing, huh? There's a lot new in this code.
    How many new commands can you spot? You find 'em and I'll explain what they
    do.

    Extra credit for using the manual and explaining what the Manual says it does.
    Best answer gets a used iTunes Gift Card sent via carrier pigeon. I'm in California so...
    keep the pigeon.

    Go!

    • Best answer determined at random from a secret drawing. I reserve the right to play and eat the pigeon.
Sign In or Register to comment.