Close

TDBitwig Example File

TDBitwig Example Fileedit

This document provides details about a TouchDesigner example environment that connects to a Bitwig file using the TDBitwig system. The environment consists of two files: a TouchDesigner file and a Bitwig file.

This example was originally constructed for a Node Institute presentation which can be found here.

TouchDesigner Roundtable XXV - YouTube - scan to the 2:00 (2 Hour) mark.

While the file has changed since then, the general setup remains the same. The actual file used for the presentation will also be provided for reference. Please watch the video first, as this document assumes you have an understanding of the topics covered in the video presentation.

Getting Startededit

You can find the files in the TouchDesigner Samples folder.

Help > Browse Samples > TDBitwig

There are two folders with the same files but of different versions. NodeInstitutePresentationFile is the file used for the Node Institute Presentation. TDBitwigDemo is the file that will be used for this documentation. Copy the folders to a working directory before opening.

Make sure you using Bitwig Studio 5.0.11 or greater. As well make sure you are using an Official build of TouchDesigner 2022.35280 or greater. The version of the Bitwig Controller Extension should be Version 1.1.12.

Overviewedit

The basic structure of the file is the same but there are now 5 main tracks rather than 7. As well, each track serves a more distinct purpose and has its own unique instrument assigned. The first 4 tracks are assigned to a synthesizer while the 5th track is a drum machine. Each synthesizer is stripped down to the default settings and most are custom Grid Synthesizers that are simple enough to discuss in this document. We have a Bass synth on the “GridBass” track, 2 lead/pad type synthesizers named “Polymer” and “Grid Synth”, a string instrument on the “GridStrings” track and finally a drum machine on the “Drums” track. These are the 5 instrument tracks. As well there are two FX sends and finally the Master track. These 8 tracks are received into TouchDesigner in this expressed order as Track 1 through 8.

For the purpose of this document, the view of the Tracks will be discussed from left to right, in the Mix view of Bitwig. Track1 is the GridBass track while Track8 is the far right side Master track.

As with the presentation video, the main track of focus is in this document is Track3 also known as the Grid Synth Track.

Alternative text
TDBitwig Example UI

Mapping a Custom User Interface Using Widgetsedit

An example custom user interface was created using widgets to demonstrate a workflow for building a performance user interface. Each Widget has its Value parameter bound up to a custom parameter on the /project1/ui component.

The UI Component is located in the top left of the /project1 network, as shown in this screen capture.

Alternative text
TDBitwig Example UI

The UI component holds the user interface. The Widget interface is bound to the UI Component’s top level parameters. The parameters of the UI component are bound to their respective TDBitwig component parameters.

Standard Binding of TDBitwig Parameters to Widgetsedit

On the first page of the UI component there are two parameters that are bound to the TDBitwig Play State and Stop parameters. This bind relationship was achieved by dragging the bitwigSong parameters from bitwigSong component to the UI component. When the dragged parameter is dropped, the drop menu option for “Bind” is selected.

Alternative text
TDBitwig Song Component Parameters

To see the bind expressions you may need to click the parameter name to open the parameter’s extra information mode. A bound parameter’s text color is violet and bound parameter quad state shows a solid violet square next to the bound expression.

Alternative text
Exposed Bind Parameters

By following this workflow, where the TDBitwig component mappings are centralized in a flat network at the top of the project, simple bind expression mappings like the ones shown here can be achieved.

op('bitwigSong').par.Playstate
op('bitwigSong').par.Stop

The actual Widget user interface is secondary to the process of mapping the TDBitwig component parameters to the centralized UI component parameters. The functionality of controlling TDBitwig from a centralized parameter box is the primary purpose of this workflow and has already been achieved before building the Widget UI when following this process.

Its worth mentioning now that the UI component has been given a parent shortcut called “UI”. The UI component parameters for Play State and Stop are bound to the buttonPlay and buttonStop Widgets located inside the UI component.

Alternative text
Bound Widget Button Components

The Widget’s Value parameter is bound to the parent UI component parameter.

Alternative text
Bound Widget Value Parameter

Because we used a parent shortcut, the Widget value parameters are bound with a simple bind expressions as follows here. These expressions will work as long as the Widget component remains inside the UI component. This permits easier UI layout refactoring etc.

parent.UI.par.Playstate
parent.UI.par.Stop

This section outlines a complete workflow for creating a customizable user interface to remotely control TDBitwig parameters. The UI component includes two Widget buttons: Play and Stop. These buttons are bound to the custom parameters of the UI parent component, which in turn are bound to the parameters of the TDBitwig component. The rest of the Widgets are bound to other TDBitwig components in an identical manner.

Alternative text
Bound Widget Value Parameter

Creating Dynamic UI Mappings with Bind Expressionsedit

A more dynamic interface may be desired for TDBitwig Remotes. Because Bitwig remote pages always come in groups of 8, its possible to use a single set of 8 Widgets (Knob widgets in this case) to map to N pages of Bitwig Remotes. This can be achieved in numerous ways but the following example outlines a general technique that can be expanded upon depending on your use case.

The process of mapping a bind from a TDBitwig component parameter to the UI component and subsequently to the Widget component remains the same. However a menu can be used to switch the context of the “op” function to dynamically fetch the parameters from different TDBitwig remote components.

The Project Remotes page of the UI component features a dropdown menu called “Macros Page” with three items: Macros1, Macros2, and Macros3.

Alternative text
Bound Widget Value Parameter

Noice the bind expressions for each remote slider parameter is bound with an expression as depicted here. The menu names are actually irrelevant as menuIndex is used in the expression.

op(f"projectRemotesMacros{me.par.Projectpages.menuIndex+1}").par.Remotecontrol0

We use python “fstring” syntax to combine the current menu index of the Macros Page dropmenu with the operator name prefix to dynamically switch the bind reference expressions when the menu index changes. The 3 TDBitwig Project Remote components are located in the Globals annotation area as shown here.

Alternative text
Bound Widget Value Parameter

The 3 TDBitwig Remote components were named projectRemotesMacros[1-3]. The fstring syntax breaks down as follows.

#Dynamic op bind expression
op(f"projectRemotesMacros{me.par.Projectpages.menuIndex+1}")

#Yeilds an index that is either 1, 2 or 3
me.par.Projectpages.menuIndex+1

#Therefore we provide operator name strings as follow here  
projectRemotesMacros1
projectRemotesMacros2
projectRemotesMacros3

#So the evaluated bind expression should be familiar.
op('projectRemotesMacros1').par.Remotecontrol0

The important lesson here is that TDBitwig components should be the bind Master. If the TDBitwig component parameters are the bind Master then bound user interface systems or for that matter any bound parameter in TouchDesigner will always update to the values of the Master. This means TouchDesigner parameters will always update to Bitwig’s values. Even when the focus of a bound Widget interface change focus from one TDBitwig component to another, the updated values are received by the custom UI. This bind workflow will permit the Bitwig Remote controls to continue operating in the correct bidirectional manner. Furthermore, everything in TouchDesigner will follow the standard Bitwig automation, modulation and controller mapping workflow for external MIDI devices.

This is a simple example of a dynamic binding workflow. In this particular case, the purpose of the Widget knobs is to provide easy access to 3 Project Remote Pages that are permanently connected to TouchDesigner. You could easily modify this to work with a single TDBitwig Project Remotes component that binds to the TDBitwig Remotes Page menu which would permit accessing any of N pages in Bitwig while only having to manage a single TDBitwig component a single set of 8 custom parameters and their respective widgets. There are innumerable approaches that can be advanced using similar techniques.

TDBitwig Modulation and Bindingedit

The project pages are set up with Macro-4 modulators which are groups of 4 remotes per modulator. Assigning a few pages of these as a generic set of macro pages might be useful because macro modulated parameters can be assigned to more than one Bitwig parameter per macro remote parameter.

The main way to pass modulation from Bitwig to TouchDesigner is through the modulation of Bitwig Remote parameters as depicted below. For example the Project Remotes page called Macros3 is being modulated by a simple LFO modulator. User interaction of parameters is maintained even when parameters are modulated. The user interaction of the knob simply offsets the modulated value.

Alternative text

Its important to distinguish between the orange and blue level indictor on a Bitwig remote parameter. The orange level indicates the pre-modulated value while the blue is the modulated value. In TouchDesigner, the TDBitwig remote parameters do not update with Bitwig modulated values. Instead, the parameter in TouchDesigner matches the pre-modulated value of the remote parameter in Bitwig. The actual modulated value of Bitwig parameters is received when the Read Modulated Values parameter is turned On. This mode is active by default.

Alternative text

TDBitwig remote parameters support all 4 modes of TouchDesigner parameters with some minor caveats. The four Parameter Modes of TouchDesigner are Constant, Expression, Override (CHOP Exporting) and Bind.

  • TDBitwig remote parameters are in constant mode by default.

  • Constant mode supports bidirectional interaction with the pre-modulated value in Bitwig.

    Alternative text

    TDBitwig Remote parameter in constant mode.

  • Expression mode will lock out changes to the pre-modulated value in Bitwig. The modulated value from Bitwig will continue to pass in as the modVal channel. This means the pre-modulated remote parameter value in Bitwig can be modified on the Bitwig side, but the TDBitwig remote parameter in TouchDesigner will not update. The expression mode in TouchDesigner is maintained until expression mode is manually deactivated.

    Alternative text
  • A TDBitwig parameter that is in CHOP override mode will be overridden non-destructively. The CHOP override mode will be maintained unless there is a user interaction. If the Remote parameter is moved by mouse interaction in Bitwig or TouchDesigner, the CHOP override will deactivate and the parameter will continue to run interactively in constant value mode. This is consistent with the standard CHOP export behavior in TouchDesigner. To re-instate the CHOP export, toggle the export flag on/off for the CHOP that is exporting the override value.

    • An example of this can be viewed by toggling on the export flag of the “exportRemoteMacroPage3M1” CHOP. This channel will be exported to the “M1” parameter of the exportRemoteMacroPage1
    Alternative text
  • Exporting channel data using a Bind CHOP will harden the exported connection, meaning the override will be maintained even when the pre-modulated value changes through user interaction in Bitwig. However this connection can cause fighting between user interaction in Bitwig and CHOP exporting from TouchDesigner because CHOP overrides work with pre-modulated values in Bitwig. This mode is for advanced use cases where the Bind CHOP callback mechanism is required.

  • A Bitwig remote parameter can be modulated by Bitwig modulators and TouchDesigner CHOPs at the same time. The TouchDesigner CHOP export will override the pre-modulated Bitwig value while the Bitwig modulator works on the added modulated value which is received in the TDBitwig Remote component as a modVal channel.

Launching Scenesedit

Scenes in Bitwig are accessed using the first column in the arranger of the Mix layout mode. The Song component has the ability to launch a scene which effectively means it will launch any clips in all the clipSlots of the selected scene’s row.

[[File:Screenshot_2023-10-21_at_10.15.12_AM.png |center|thumb|alt=Alternative text| ]]

A Scene selection parameter can be found at the bottom section of the TDBitwig Song component. The Scene menu maintains a persistent list of scene names that can be selected from the menu and subsequently launched using the Launch Scene pulse button.

Alternative text

|center|thumb|alt=Alternative text| ]] Screenshot 2023-10-21 at 10.25.31 AM.png]]

A widget user interface for controlling the scene is located in the Widget example UI below the Remote parameters section.

Alternative text

The custom parameter called Scenes is bound to the TDBitwig Song parameter called Scene.

Alternative text

The menu items for this bound menu are maintained by adding a Menu Source parameter attribute using the Component Editor. The menuSource parameter is underlined in the screen capture below.

Alternative text

Custom parameter menu items can be synchronized with other menus by using the following Python syntax.

#The function tdu.ParMenu can be used to provide a ParMenu object that can 
#be consumed by the parameter menuSource parameter.

tdu.ParMenu(list)

#In this example the Bitwig Song component's Scene menu is used to reference
#the persistent Scene names of TDBitwig.

op('bitwigSong').par.Scene.menuNames

#The following expression converts the list of menuNames from the
#TDBitwig scene component into a TouchDesigner ParMenu object.

tdu.ParMenu(op('bitwigSong').par.Scene.menuNames)

Following Clip Attributes (Beta Functionality)edit

This section covers a custom user interface for controlling clips in a similar way to scenes. The desired behavior is a menu to select the desired clip, a button to launch the selected clip, which in turn will provide the currently playing clip to access name and color attributes for visual display.

Alternative text

In the screen capture above, we can see the Menu widget is linked to the custom parameter “Slots” in the top-level UI component. By selecting a new clip slot, you can use the Launch pulse button to launch the selected clip. This user interface demonstrates the Bitwig Controller API utilizes clip slots for launching clips. Instead of directly launching clips, you trigger the launch from the clip slot, which plays the clip if there is one assigned to it.

Alternative text

This parameter uses a Python expression to reference the bitwigClipFollower/bitwigClipSlot/out1 CHOP.

Alternative text

The following expression can be used to access the currently playing clip slot from the “out1” CHOP of the bitwigClipSlot component.

#The TDBitwig ClipSlot component contains an out1 CHOP that holds 
#the channel for playingSlotIndex.

#The playingSlotInex channel is referenced and then evaluated to a numeric
#value using the eval member function.

op('bitwigClipFollower3/bitwigClipSlot/out1')['playingSlotIndex'].eval()

The reference is pointing to the bitwigClipSlot component’s “out1” operation which is found in the component depicted below.

Alternative text

The Clip Follower Component Trickedit

We aim to enhance this crucial functionality. However, let’s begin by explaining the technique used to extract information from a Bitwig clip that is currently playing.

The Bitwig Controller API does not provide a persistent notion of the current playing clip. Instead we have a persistent notion of the currently playing clip slot using the bitwitClipSlot component. However, the clip slot index is only provided through the bitwigClipSlot component’s output channels.

The “playingSlotIndex” output channel of the bitwigClipSlot component will have a value of -1 if no clip is currently playing. If the value is greater than -1, we can utilize the bitwigClipSlot callback to select the clip in Bitwig, similar to manually selecting a clip using the Bitwig interface. This clip selection action can be achieved by using the “onPlayingClipChanged()” callback within the bitwigClipLauncherCallback callback DAT of the bitwigClipSlot component. The TDBitwig ClipSlot component includes a member function called “SelectClip” that can simulate the same user interaction in Bitwig.

def onPlayingClipChanged(info):
    """
    A new clip has started playing
    info:
        'clipIndex': scene index,
        'clipName': scene name,
    """
    #clipSlotComp = info['']
    ownerComp = info['ownerComp']
    playingIndex = info['index']
    if playingIndex >= 0:
        ownerComp.SelectClip(playingIndex)

AAs we can see, this is a trick and does not involve a persistent interaction with a state in the Bitwig Controller API. We are only temporarily selecting the clip. If you manually select another clip on the Bitwig user interface, the selection will change to the newly selected clip, which may not be the currently playing clip.

To better understand this trick, notice that the bitwigClip component is actively pinned to the GridSync track, as shown in the following screen capture.

Alternative text

However, the Clip Navigation is not pinned. Therefore, it will continue to follow user interactions with clips, but only on this track.

Alternative text

The clipFollower component is an example of utilizing the exposed features to achieve functionality that is not directly supported by the Bitwig API. This example effectively demonstrates how to employ Callbacks and Python to choreograph specific behavior in Bitwig. However, it is desirable for future versions of TDBitwig to have the ability to access persistent information about the currently playing and cued clips.

Track Solo and Mute Interactionedit

The states of the Track Solo and Mute buttons alone are not sufficient to accurately represent the mixing bus state for the audio signal. When a track is in Solo mode, the Mute toggle is overridden. To address this, a simple CHOP network is utilized to determine the actual mute/solo bus state. These channels are provided to visually mute/solo objects or layers in TouchDesigner.

Alternative text

Bitwig Automationedit

Any parameter in Bitwig can be automated over time using a time based keyframe editor. To receive automation in TouchDesigner the Bitwig parameter has to be promoted to a Remotes Page at any of the three levels, Project, Track or Device.

This example file demonstrates the workflow by promoting an instrument level parameter for each of the 5 synthesizer tracks. This level parameter provides a pre-master volume control so we can create a fade in effect that travels with the Note clips.

A small circle appears to the top right side of automated parameters. This is a seperate Bitwig parameter state from modulation which is depicted by a small circle at the top right of each Remote parameter.

Alternative text

A TDBitwig Project Remotes component is used to provide access to the automated levels of each Synth.

Alternative text

The automation indicator for Bitwig Remote parameters has 3 states. A blue circle indicates that automation is actively updating the parameter. A white circle indicates that there is an automation lane assigned for that parameter, but the automation is not active, most likely because there is no clip information available. This can occur, for example, if the clip is not playing. A green circle indicates that there is an automation lane active but a user interaction with the parameter has bypassed the automation.

Alternative text

An automated parameter in Bitwig that is in the Green bypassed state will remain in that state until the user switches it back into active automation state. This can be accomplished by right clicking the remote parameter and selecting “Restore Automation Control” from the pop menu.

Alternative text

Alternatively, this same action can happen globally where all parameters that have by passed automation can be restored by clicking the global Restore Automation button located on the global transport controls. If any automated parameters have bypassed automation the button appears green.

Alternative text

All the clips in this example file include an automation lane for the level parameter of their respective instrument. To see the automation lanes select a track on Track3 (GridSynth). Selecting a clip will activate the Bitwig Detail Editor.

https://www.bitwig.com/userguide/latest/working_with_note_events/

The detail editor provides access to automation channels by switching into automation mode.

Alternative text

With the automation editor open, selecting each clip in the Track3 column will show different automation levels for the Output level of the instrument. The SynthClear clip holds automation for the output always being at 0 - which effectively turns off the output of each instrument.

The “In Synth” clip demonstrates holds a clip that slowly fades in over 4 bars, then continuously loops a 2 bar section of the clip that has the output level at its desired active level.

Alternative text

The “Synth Line” clip holds automation that is constantly at the maximum desired level.

Alternative text

The “Out Synth” clip holds automation that fades the output level of the instrument back down to 0 and then loops a small empty loop section with the level set to 0 providing a fade out clip to silence.

Alternative text

Triggering each scene row, if done in order and with the correct timing will yield fade in and fade out of instruments in a coherent manner. In TouchDesigner this automation is received on the pre-modulated parameters values.

Alternative text

Unlike modulated values, where the value from Bitwig is a post-modulated value offset received via the modVal CHOP channels, automation actually modifies the TDBitwig Remote parameter values. Automation in Bitwig can be thought of as a simulator for user interaction. This interaction is communicated to TouchDesigner in the same way as modifying the value in Bitwig interactively.

When you interactively modify a parameter in Bitwig that has automation assigned, the automated parameter’s automation will deactivate, and the indicator for that parameter will turn green. The same applies in TouchDesigner. If you modify a Bitwig Remote parameter in TouchDesigner, the incoming parameter change to the respective Bitwig remote parameter will be interpreted as a user interaction, and the automation state will be deactivated for that parameter. To restore automation in Bitwig, simply click the master transport’s “Restore Automation” button.

Alternatively, TDBitwig Remote Components have a “Restore Automation Control” pulse button that can be used to restore automation from TouchDesigner.

Alternative text

Managing Note Informationedit

Note information is passed to the TDBitwig Note device as the playhead in Bitwig passes through note event changes. It is passed before the note effects device pathway. If you need note information from a note effect, such as an arpeggiator, you can create a new instrument channel and route the output of the note chain from the desired track’s device.

TouchDesigner receives note information over the OSC network port, just like all TDBitwig events. There is no MIDI involved in the TDBitwig communication pipeline.

In this example file, note event data is being sent to TouchDesigner from each of the 5 tracks. The bitwigNote components receive and process the note information.

Alternative text

The note information is consumed by a note visualizer component called vizAllNotes.

Alternative text

This note visualization depicts the scale of notes as a 3D spiral. The note position of the 12 semitones completes one cycle of the 3D spiral. The spiral continues for 10 complete cycles of the entire 128 step MIDI scale, ending at G of the final octave.

Alternative text

The geometry for the spiral is constructed in the viz/chromaSpiral object.

Note events from TDBitwig are visualized in 3D inside each viz/track component. The other track components are clones of Track3.

Each Track component uses the Mute and Solo combination channels to visually Mute and Solo the rendering of the note information.

Alternative text
#The isActive CHOP at the top level of this project is used to access the bus 
#mute and solo combination state.

parent.BWDemo.op('isActive')[me.name].eval()

Receiving Audio from Bitwig Gridedit

Audio and CV streams can only be exchanged between Bitwig and TouchDesigner using audio device drivers. In other words, TDBitwig does not support the transmission of audio data between Bitwig and TouchDesigner. The Bitwig Controller Script API only supports OSC data transmission.

On MacOS, there is a standard workflow known as an audio loopback that can be followed to send audio from Bitwig to TouchDesigner on the same computer. However, setting up an audio loopback on Windows is not as straightforward. This document discusses the issues related to setting up an audio loopback on Windows.

If you are using a Windows PC and you want to send audio from Bitwig to TouchDesigner on the same computer you will need a professional audio card from either RML or Universal Audio.

The ideal setup for Bitwig to TouchDesigner audio sharing on the same computer is to use a Mac and install the Blackhole audio loopback device. More details follow.

The ideal setup for audio sharing between two computers, where you have Bitwig running on a computer dedicated to audio, and you have TouchDesigner running on a computer dedciated to TouchDesigner things, then the anything can be used from professional audio interfaces, to network based audio like Dante.

Audio Sample Ratesedit

Ensure all sample rates of all devices that involved in transmission match. Also make sure the sample rate of the TouchDesigner AudioDeviceIn CHOP also matches. All sample rates must match.

  • TouchDesigner will push out its sample rate to the device which means if you select a device that is configured correctly with a particular sample rate, and TouchDesigner’s AudioDeviceIn CHOP is set to the wrong sample rate, then TouchDesigner will push that incorrect sample rate onto the device which can cause major problems with any connected audio devices (For example this can break a Dante network)
  • It is recommended that you figure out what sample rate you working with in advanced. Then make sure all TouchDesigner AudioDevice CHOPs are hardcoded to that same rate.

Audio Between Bitwig and TD on MacOS (Same Computer)edit

A high-quality loopback driver for Apple is available for purchase at the following location for $10: https://existential.audio/blackhole/

After installing the loopback driver, which comes in both a 16-channel and 64-channel version, you can aggregate it with other audio devices. Learn more about aggregating an audio device here.

A suggested workflow for using the Audio MIDI device aggregation dialog is as follows:

  1. Check (add) the Blackhole Loopback driver first.
  2. Select the listening audio device second.

The order in which you check the devices determines the order in which they are added to the aggregate set. To ensure that the indices match for the output from Bitwig to the input of the audio in CHOP of TouchDesigner, it is recommended to add Blackhole to the aggregate device first.

Alternative text

The orders will match in TouchDesigner because you have only selected the Blackhole device. As a result, TouchDesigner will receive all 16 Blackhole channels in their generic order (1-16), even if not all 16 channels were mapped in Bitwig. In other words, if you maintain the sequence of the Blackhole device starting at 1 and proceed in order in the mapping in Bitwig, you will get the same order in TouchDesigner.

Alternative text

Notice in the above screen capture, the Output Device is BlackHole + Mac Speakers. In this case the Blackhole device is the 16 channel device. This means the aggregate device has 16 channels + 2 Stereo channnels for the Mac Speakers.

  • Out1-8: Mono Out channels are assigned to Blackhole outs: 1-8 of the aggregate

  • Copy LR: Stereo Out channels are assigned to Blackhole outs: 9-10 of the aggregate

  • Speakers: Stereo Out channels are assigned to Mac Speakers: 17-18 of the aggregate

    • The Mac Speaker device is the second device in the aggregate set. As a result, the left and right speakers are assigned to channels 17 and 18 on the aggregate device. This is because they directly after the 16 channels of the Blackhole device.
  • Also take notice in the screen capture below. The “Blackhole 16ch” device is selected in TouchDesigner. This is the singular device on its own and not the aggregate device. The aggregate device is used by Bitwig only.

    Alternative text

Audio Between Bitwig and TD on Windows (Same Computer)edit

Windows does not support a reliable method to aggregate a loopback driver with an audio device. Moreover, Bitwig only supports a single audio device for output, so on Windows you are forced to use a professional audio device that supports loopback if you want to share audio and cv on the same computer between Bitwig and TouchDesigner. The professional devices mentioned below support the sharing of the ASIO driver between applications, and they provide loopback or virtual audio channels that allow you to pass audio from one application to another.

The following device manufacturers support audio loopback through their proprietary audio routing software.

Loopback Technologies for Windows (Not Recommended but May Work)edit

We do not recommend the following technologies that allegedly support a pathway to acheive aggregation of audio devices or loopback on Windows.

You will know your channels are configured correctly when you play scene6 in Bitwig and trail CHOP looks like the following screen capture below.

Trail CHOP Check

Visual Examplesedit

Viz All Notesedit

NoteViz

In this example, the TDBitwig note information received from each track is processed and visualized using a specialized component. The component organizes and displays each note based on its pitch value along a spiral. Each 12 steps represent one octave, completing a full cycle of the spiral. Additionally, the component assigns colors to the note values, mapping the sound spectrum to the color spectrum.

Moreover, the visualization incorporates the concept of note duration by indicating the height at which each note travels. The longer a note is held, the higher it travels on the spiral, visually representing the note’s duration. This visual representation allows for a quick and intuitive understanding of the length of each note in the composition.

Overall, this visualization offers an example for organizing note information received from Bitwig. It combines both pitch and duration aspects of the notes, providing a holistic view of the musical composition in 3D.

Viz Envelopeedit

VizEnvelope

In the component called Viz Envelope, the CV trigger envelope from GridSynth’s AD Trigger is reformated into a concertric circle ramp that shows the decay envelope over a window of time.

Viz Waveform (Osciloscope)edit

VizWaveform

In this component, called vizEnvelope, two audio channels are sent from the Grid to TouchDesigner using the hardware out module of Bitwig Grid. Audio channels are received by the standard TouchDesigner AudioIn CHOP located the Audio In component. A CV signal is sent directly from the AD (Attack Decay) operator of Grid and received by TouchDesigner at audio rate. As well the oscillator is also sent to generate an example of an oscilloscope type visualization in TouchDesigner. Of particular note is a process for resampling and converting the audio sample data to geometry.

Viz Audio Spectrumedit

VizSpectrum

This example also uses a direct feed of audio data from the Grid. In this case the audio is converted into an audio spectrum and subsequently mapped to a visual color spectrum for display as a 2D image.

Scene Changer Setupedit

SceneChanger

The Scene Changer setup demonstrates how to use a ClipSlot callback to drive the standard SceneChanger system from the Palette. Notice the bitwigClipSlot component is pinned to the Master track.

This names of the clips on the Master Track match those of the components found in the scenes component of the Scene Changer example.

SceneChangeTrack

The callback DAT bitwigClipLauncherCallbacks1 shows the code for running the sceneChanger based on Clip Change events from Bitwig. The info dictionary object is received by the callback function which is then used to extract the name of the clip which is used to the trigger the component of the same name using the SceneChange method of the scenerChanger component.

def onPlayingClipChanged(info):
    """
    A new clip has started playing
    
    info:
        'index': scene index,
        'name': scene name,
        'ownerComp' : the component reporting this callback
        'callbackName' : the name of this callback method
    """
    
    fadeTimes = {'Black':1,
        'Scene1':10,
    }
    sceneName = info['name']

    if sceneName in fadeTimes:
        fadeTime = fadeTimes[sceneName]
    else:
        fadeTime = 3

    op('sceneChanger').SceneChange(sceneName, fadeTime=fadeTime)

The Scene Change example also work in Arrange mode and uses the bitwigSong component’s callback for onCuePassed to do the same thing a the clipSlot component above.

Video Playeredit

Use the VideoEngine Custom COMP from Palette