Assignment for February 17, 2015

Read “Cross-Domain Mapping“, Chapter 2 of Conceptualizing Music by Lawrence M. Zbikowski. [You will need to be on the UCI LAN or accessing it via VPN in order to read this book online.]

Study the following two examples from a past class, regarding linear mapping and linear interpolation. The first one is pretty math-y, but is worth reading carefully so that you understand linear mapping conceptually. The second one gives a few practical (if not super-useful musically) examples of applying linear mapping to convert one range of numbers into another.
1. Linear mapping equation
2. Linear mapping and linear interpolation

In class Anna and Molly will bring instruments for us to experiment with the pitch-detection object sigmund~.

Read the Wikipedia article on pitch tracking. If you want to read more about how pitch detection is accomplished, there’s no shortage of articles online. The page on Pitch Detection Algorithms by Gareth Middleton gives a pretty clear explanation of two algorithms, and you can read Miller Puckette’s description of his fiddle~ object, which was the predecessor of sigmund~, in his article “Real-time audio analysis tools for Pd and MSP” (a .ps PostScript file).

Video crossfade

The concepts of mixing and crossfading, and the mathematics of how to accomplish them, are discussed and demonstrated in the post titled “Mixing and crossfading“.

This post demonstrates how to crossfade between two images or two videos using the jit.xfade object. The jit.xfade object implements the same sort of arithmetic discussed in earlier examples about audio mixing, and it applies the concept to the contents of two Jitter matrices. In its two inlets it expects to receive Jitter matrices, and it uses its ‘xfade’ attribute to scale and add those two matrices. (That is, every value in every cell of the matrices is scaled by some factor, then the two matrices are added, cell-by-cell.) The right matrix is multiplied by the ‘xfade’ value, and the left matrix is multiplied by 1 minus the ‘xfade’ value.

So, for example, when the ‘xfade’ value is 0, the output will be only the left matrix (scaled by 1-0, while the right matrix is scaled by 0) , and when the ‘xfade’ value is 1, its output will be only the right matrix (scaled by 1, while the left matrix is scaled by 1-1 which equals 0). When the ‘xfade’ value is 0.5, the output will be an equal mix of the two matrices, each multiplied by 0.5 (thus halving the brightness of each one) before they’re added together. When the ‘xfade’ value is 0.1, the cells of the right matrix will be multiplied by that value and the cells of the left matrix will be multiplied by 0.9; when the two matrices are added together, the left matrix will be 9 times as bright as the right matrix.

This patch uses the line object to interpolate from 0 to 1, or from 1 to 0, in a specified amount of time.

crossfade between A and B

 

Mixing and crossfading

Mixing or blending two things—whether it’s two sounds or two videos—just means taking a certain amount of thing A and a certain amount of thing B and adding them together.

If you take a full dose of A and a full dose of B—let’s say, a full amplitude sine wave and a full amplitude square wave—and add them together, you’d likely end up with a sum that has an amplitude (or a brightness in the case of video) that’s twice as great as either of them alone. That’s why it’s common to scale A and B down by a certain amount (multiply them by some amount less than 1) so that their sum will eventually equal 1. For example if you multiply the sine tone’s amplitude by 0.25 and the square wave’s amplitude by 0.75, the peak amplitude of their sum will not exceed 1 (and the amplitude of the square wave’s contribution to the mix will be 3 times as great as that of the sine wave).

If you gradually change the level (the multiplier factor) of thing A from 1 to 0, it will fade away from full to none. Conversely, if you gradually change the multiplier applied to thing B from 0 to 1, it will fade from off to full on. If you do both things simultaneously, you get a crossfade from A to B. This is commonly achieved by linearly interpolating the amplitude multiplier of thing A from 1 to 0 (using the output of a line~ object as the multiplier, for example) and using 1 minus that amount as the multiplier for thing B. That ensures that A and B will fade in opposite directions, and that the sum of the two multipliers will at all times be 1.

For examples and explanations of abstractions for basic audio mixing/crossfading, see the following two examples from a previous class:
Mix two signals
Mix two signals (more efficiently)

The example patch below employs the second of those two mixing algorithms, encapsulated in a subpatch, and shows the use of the line~ object to cause a crossfade from one sound to another.

linear crossfade between two sounds

Mixing and crossfading are such common operations in audio and video that it makes sense to have an object dedicated to that purpose. In Jitter, the jit.xfade object gives easy control for mixing or crossfading two matrices (i.e., two images). In MSP, the matrix~ object is a controllable multichannel audio mixer. For simply mixing or crossfading two audio signals, you can use matrix~ 2 1 0. as a 2-in/1-out mixer, as in the example patch below (or you can build a mixer yourself easily enough, save it as an abstraction, and reuse it in any patch as in the previous examples above). This example has a pretty similar effect to the one above, but it allows the mixing/crossfading to be controlled by hand via a slider.

MSP mixer object matrix~

The same principles describes above apply when mixing two images or two videos; one image is faded down to 0 brightness while the other is being faded up to full brightness. The jit.xfade object is the visual equivalent of the mix~ and mix2~ audio mixing abstractions linked above. The use of the jit.xfade object to mix/crossfade Jitter matrices is demonstrated in the next example.

Note that these examples all demonstrate a linear mixing system (a linear crossfade from A to B), which is very simple and direct and works for many situations, but may not always be the most desirable way to get from A to B in all circumstances. A straight line is one very special kind of curve—the most direct path possible between two points. One could use any curve of transition other than a straight line. The curve that’s used for mixing two signals is called the law; different laws are used for different effects. Commonly an exponential curve is used, to compensate for our tendency to perceive relative to the logarithm of the stimulus (known as Fechner’s law).

Assignment for February 12, 2015

Based on the discussion in class, begin solidifying your project proposal, filling in details, defining clearly what you want your finished program to do. Once you know what you want it to do, you will need to determine what the program requires in terms of a) pre-made “footage” of audio, video, graphics, etc. and b) control input from the user (who might be you and/or might be an unknown user). The determination about functionality and input will help you determine the user interface—what the user will see onscreen, and how s/he will provide the needed information to the program. Once you have established those goals and needs, your next step should be to think about the global structure of the program (sketching the flow of information on paper can be a great way to brainstorm structure), break the task down into steps or subtasks, and then make specific plans regarding the steps you’ll need to take to accomplish each subtask, and set intermediate goals and deadlines for completing them.

Catch up on any past assignments you may not have completed.

Some useful Jitter attributes

Here are a few attributes of the jit.movie and jit.window objects that I find useful for initializing the objects to behave the way I want.

override default attribute settings

autostart / moviefile / adapt / dim / vol / unique
name / size / pos / fsmenubar / visible

autostart:
By default a jit.movie object’s ‘autostart’ attribute is set to 1, meaning that a movie (video file) will begin playing as soon as it’s loaded in. I usually prefer to have control of that myself, so I set the object’s ‘autostart’ attribute to 0 initially. That means I have to explicitly ‘start’ the movie when I want to view it. No problem. I use the 1 from the toggle object to trigger a ‘start’ message to the jit.movie object at the same time as I use it to turn on the qmetro. (If you don’t know what qmetro is, or why you should use it instead of metro, read about it in the example called “Simplest possible A-B video switcher” and in the article linked to on that page called “Event Priority in Max (Scheduler vs. Queue)”.)

moviefile:
Instead of reading a video file into jit.movie with a ‘read’ message, you can have it be read in automatically by specifying it with the ‘moviefile’ attribute. A couple of things to be aware of: 1) When you read a file in this way, jit.movie does not send out a ‘read’ message as described in the post “Detect when a movie has been read successfully“. So, if you’re relying on that message coming out to trigger other events in your patch, you need to read the movie in by sending a ‘read’ message to jit.movie (perhaps triggered by loadbang). 2) In Mac OS 10.8.5 or lower, there is a bug in jit.movie such that the ‘@autostart 0’ attribute setting described above will not work in conjunction with the ‘moviefile’ attribute unless it comes before the ‘moviefile’ attribute, as it does in this example patch. [I’ve reported the bug to Cycling ’74, so hopefully that second caveat will become obsolete soon.]

The next two attributes in the example show how you can force the matrix dimension of jit.movie to be something other than the size of the movie itself, if you want to. (For example, maybe the movie being read is higher-definition than you need, and you want to set a specific size of matrix to come out of jit.movie.) If you do that, the movie will be resized to fit the specified size of the object’s matrix. (Some pixels will be duplicated if the movie is being upsampled to fit in a larger matrix, and some pixels will be discarded if the movie is being downsampled to fit into a smaller matrix.)

adapt and dim:
The ‘adapt’ attribute determines whether the object’s matrix dimensions will be resized according to the dimensions of the video. By default, the ‘adapt’ attribute is on. If you want to enforce some other matrix size, you can set the ‘adapt’ attribute to 0 and use the ‘dim’ attribute to specify the width and height of the matrix.

vol:
In order to avoid any unwanted audio being played when the movie is read in, I like to have the movie’s audio volume (the ‘vol’ attribute) set to 0. You can then turn the audio up explicitly with a ‘vol’ message to jit.movie (not shown in this example). A ‘vol’ value of 1 is full volume, and values between 0 and 1 provide (logarithmically) scaled volume settings.

unique:
The ‘unique’ attribute, when turned on, means “Only send out a jit_matrix message if your matrix is different from the last time you sent it out.” If jit.movie gets a ‘bang’ message, but the content of its internal matrix is the same as the last time it got a ‘bang’, it won’t send anything out. Since jit.movie is constantly loading in new frames of video (assuming the video is running), if it’s getting a ‘bang’ message constantly it will report each new frame, but it won’t send out redundant messages. This is useful if the jit.movie will be receiving a lot of bangs but you only want it to send something out when it has some new content.

In this patch the qmetro will be sending out bangs constantly at its default interval of 5 ms, but because jit.movie‘s ‘unique’ attribute is turned on, it will only send out a ‘jit_matrix’ message each time it gets a unique frame of video. The result will be that the output of jit.movie (when the movie is running) will be at the frame rate, accurate to within 5 ms, which is accurate enough for our eyes. There will be quite a lot of unnecessary bangs sent to jit.movie, but it will ignore them if it has no new video content to send out.

That’s one way to handle the triggering of video frames, but it’s not the only way. Another way would be to query the frame rate of the movie with a ‘getfps’ message, which will cause jit.movie to send an ‘fps’ message out its right outlet reporting the frame rate of its video, and then use that fps value to calculate the desired interval for qmetro. With that method (1000./fps=interval), the qmetro would reliably send a bang at the frame rate of the video. If the playback rate of the video were to be changed with the ‘rate’ attribute, however, the qmetro would no longer be in sync with the rate at which new frames of video appear; in that case, the method shown in the example patch here might be more appropriate.

name:
The ‘name’ attribute of jit.window serves two purposes: 1) it shows in the title bar of the window, and 2) it’s the name that GL 3D animation objects in Jitter can refer to as their drawing location. For that second purpose, it’s most convenient for the name to be a single word; if you want a multi-word name, though, for the title bar of the window, you must put it in quotes so that Max will treat it as if it were a single word.

size and pos:
The ‘size’ and ‘pos’ attributes of jit.window set the dimensions of the window and its location on the screen. The two arguments of the ‘size’ attribute are the width and height of the window, in pixels. The two arguments of the ‘pos’ attribute are the horizontal and vertical offset of the top-left corner of the image from the top-left corner of the screen. So, in this patch, we’re specifying that we want the top-left corner of the image (the part of the window that does not include the title bar) to be located 600 pixels to the right and 300 pixels down from the top-left corner of the screen, and we want the image to be 640 pixels wide and 480 pixels high. The same result can be achieved with the ‘rect’ attribute, which lets you specify the left-top and bottom-right coordinates of the image onscreen; so in this example, the setting ‘@rect 600 300 1240 780’ would have the same effect.

fsmenubar:
The ‘fsmenubar’ attribute determines whether the menu bar should be shown when the window is put into ‘fullscreen’ mode. (Setting the ‘fsmenubar’ attribute to 1 means “Yes, I want the menu bar when I go to fullscreen,” and setting it to 0 means “No menubar when in fullscreen.”) Using the ‘fullscreen’ attribute to make the video fill the screen is not demonstrated in this patch, but is demonstrated well (and explained) in an example called “Using attributes to control video playback in Jitter” from the 2009 class. If I’m putting the window into ‘fullscreen’ mode, it’s usually because I want a nice presentation of video, so I usually don’t want the menubar to show then. But be careful; if you hide the menubar, how will you get out of fullscreen mode (with no menu commands available)? The 2009 example shows a good, standard way to solve that problem.

visible:
Using the ‘visible’ attribute of jit.window you can hide and show the window whenever you want. If there’s no reason for the user to see the window (e.g., if it’s just a blank screen) you might as well hide it, and then make it visible when you actually want to show video in it, as is done in this example.

Detect when a movie has been read successfully

Did you know that the jit.movie (or jit.qt.movie) object will report when it has completed a ‘read’ operation? You can show that report to the user as visual feedback, and/or you can use that report to trigger other events in your program, such as querying for information about the movie that is being read.

When jit.movie receives a ‘read’ message it opens the specified movie file and reads in the first frame of video (followed by successive frames if the ‘autostart’ attribute is on). It also sends out a ‘read’ message of its own out its right outlet, reporting the name of the file and a “flag” (a 1 or a 0) telling whether the read operation was successful. A typical output message might look like ‘read dishes.mov 1’. By looking for that success flag in the outgoing ‘read’ message (using a select 1 object), you can confirm that the operation was successful, and can trigger other things to happen.

report when movie is read

The route object in this patch looks for the selector ‘read’ and sends the rest of the message (the filename and the success flag) out its left outlet, the unpack object separates the symbol (the filename) from the integer (the flag), and the sel 1 object sends a ‘bang’ if the file opened successfully.

The example patches “Movie attributes” and “Attributes of jit.qt.movie” show how to use that ‘bang’ to query the jit.movie object for other useful information contained in the movie’s attributes, such as its duration, its frame rate, etc.

Assignment for February 10, 2015

1. Write a program that has both an audio/music component and a video component, and that exhibits some degree of synchronization between control of the audio and control of the video.

The music portion of the program may use either MIDI or MSP audio, and may be either performed in real time (by mouse, keyboard, MIDI controller, etc.) or automated. The video may be controlled by some characteristic of the audio, or by user actions, or by automation. The idea is to make evident a rhythmically coherent relationship between the two elements.

2. Make a dedicated post or page or category in your blog site for notes about your final project. Write some initial plans about what topic you hope to address in some depth in your final project. Graduate students should propose a solo project; the goal may be either an aesthetic project (i.e., a piece) or an experimental project (something that will explore and elucidate a research topic, but might not necessarily have a finished artistic product as its result). Undergraduate students may propose either of the above (artistic project, or experimental project) or an application that uses or generates audio-visual media; undergrad projects will be carried out in small groups of people with similar interests.

Assignment for February 5, 2015

To begin learning how to control video and animation in Max, please read the following essays and tutorials. (The links provided here are to online sources, but the same readings and tutorials, with tutorial Max patches, are available within the Max application documentation, under Jitter Tutorials.)

Readings:
What is a Matrix?
Attributes

Tutorials:
Tutorial 1: Playing a QuickTime Movie
Tutorial 4: Controlling Movie Playback

Examples:
Attributes of jit.qt.movie
Simplest possible A-B video switcher
A-B video switcher

Find or make some video files that you think would be interesting source material, and try reading them into jit.movie, playing them in a jit.window, and controlling the playback (starting, stopping, changing the rate, jumping to a specific frame, etc.).

Pseudo-random numbers appear random

Programming languages all provide some means of generating random numbers. Those numbers aren’t truly random, though. They’re what’s called pseudo-random. They’re actually generated by a known, deterministic process for generating a sequence of numbers, but that process generates a long series of apparently random numbers that doesn’t repeat for a very long time. Since we don’t know the process behind the generation of those numbers, and they’re evenly and quasi-randomly distributed, we accept it as a random sequence of numbers.

We accept as “random” any series of numbers that seems to have no explicable pattern or reason. The fact is, though, that the reason or pattern might in fact be completely non-random, but if we don’t know or understand the process by which the numbers were generated, we might find the sequence to be incomprehensible and thus just “noise” or randomness. It’s important to realize that something might be quite sensible to those who are privy to the “grammar”, the means by which information is encoded, and yet might be completely incomprehensible to those who don’t know the encoding.

In short, randomness may well be in the eye of the beholder, and the difference between sense and nonsense may also be at least partially dependent on the knowledge of the beholder.

two “random” lists

This patch is a simple demonstration of that idea. It shows two lists of twelve numbers, each apparently random. They were generated by two different methods, contained in the patcher subpatches. Can you guess how the numbers were generated? In fact, one of the lists is not random at all. Can you guess which one? You’ll need to look inside the subpatches.

Conversion between pitch and frequency

The objects mtof and ftom provide easy conversion between MIDI pitch numbers and their equivalent equal-tempered frequency values. The purpose of this patch is just to show the conversion formulae that those objects use.

pitch-to-frequency conversion

The number of semitones of pitch difference from the base pitch of A above middle C is divided by 12 and used as a power of 2 by which to multiply the base frequency of 440 Hz. Thus, each semitone up from A is an additional twelfth root of two multiplication of the base frequency; each semitone downward is a negative twelfth root of two factor.

The expr object allows you to type in any mathematical expression, including some math functions not be found in other objects—e.g., log(), atan(), etc.—using a syntax that’s very similar to C programming language.