Daqarta
Data AcQuisition And Real-Time Analysis
Scope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
The following is from the Daqarta Help system:

Features:

Oscilloscope

Spectrum Analyzer

8-Channel
Signal Generator

(Absolutely FREE!)

Spectrogram

Pitch Tracker

Pitch-to-MIDI

DaqMusiq Generator
(Free Music... Forever!)

Engine Simulator

LCR Meter

Remote Operation

DC Measurements

True RMS Voltmeter

Sound Level Meter

Frequency Counter
    Period
    Event
    Spectral Event

    Temperature
    Pressure
    MHz Frequencies

Data Logger

Waveform Averager

Histogram

Post-Stimulus Time
Histogram (PSTH)

THD Meter

IMD Meter

Precision Phase Meter

Pulse Meter

Macro System

Multi-Trace Arrays

Trigger Controls

Auto-Calibration

Spectral Peak Track

Spectrum Limit Testing

Direct-to-Disk Recording

Accessibility

Applications:

Frequency response

Distortion measurement

Speech and music

Microphone calibration

Loudspeaker test

Auditory phenomena

Musical instrument tuning

Animal sound

Evoked potentials

Rotating machinery

Automotive

Product test

Contact us about
your application!

MIDI Buffer Array Direct Access


Changes: Bbvb.i0, Bwvb.i0, Bdvb.i0, BmN.i0

MIDI Input Buffer Access:

The Direct Entry command allows a MIDI Changes script to use MIDI note input buffers as general-purpose integer arrays. They are particularly useful for holding lists of arbitrary values for random selection.

Although each buffer normally holds up to 256 note values in the range of 0-127, you can choose to store arbitrary 8-bit values there, which can be treated as signed or unsigned.

Alternatively, you can choose to store up to 128 16-bit values or up to 64 32-bit values.

There is no option to store fixed-point real values in MIDI buffers, but you can access macro array buffers from MIDI scripts. See Macro Buffer Access, below.

Use Bbvb.i0=n to store an arbitrary 8-bit (byte) value n at index i0 in buffer b of voice v. Note that this direct access method is not allowed with Voice Patterns (Velocity, Note, or Chord), which have their own access commands.

Index i0 may range from 0-255. It may be an immediate constant or any valid expression. Voice and buffer numbers are normally single-digit constants, but if you want to control them via Changes scripts you can replace them with expressions surrounded by carets like <UA+UB>. (You may also need to surround i0 with carets when reading a direct access value... see below.)

The n data value can also be an immediate constant or any valid expression. If it is larger than 255 (or, if signed, outside the range of -128 to +127), only the low 8 bits are stored and any higher bits are ignored. Most MIDI values are unsigned, in the 0-127 range. +/-Note and Pan position are signed, in the range of -64 to +63. Thus, a single byte will hold most values.

For data values in the 0-127 range, this command would appear to be eqivalent to the single-value Buffer Fill command BFvb.i0=n. However, since that command is designed for note pattern entry, it also keeps track of the start and end position pointers, extending the played region as needed. The Direct Array Access commands don't affect the pointers since they assume other uses.

Similarly, use Bwvb.i0=n to store an arbitrary 16-bit (word) value at index i0, which may range from 0-127. Signed values for n must be in the range of -32768 to +32767, while unsigned values may range from 0-65535. The most likely use for 16-bit data arrays is to store 12-bit Scales (1-4095).

Likewise, use Bdvb.i0=n to store an arbitrary 32-bit (double-word) value at index i0, which may range from 0-63. You would need 32-bit data to store random value seeds for forcing certain "repeatable random" operations. But you can also use this to extend the number of general-purpose signed integer User Variables beyond UA to UZ.


Reading MIDI Buffer Values:

To read the data from the arrays, use the same general formats as above, but on the right side. For example, to set UA with the 3rd word from voice 1, buffer 2, you would use:

UA=Bw12.3

The lowercase 'w' indicates that the word will be read as an unsigned 16-bit (word) integer in the range 0-65535. Alternatively, you could read the same location as a signed integer in the range -31768 to +32767 using an uppercase 'W':

UA=BW12.3

To set UA to a signed 32-bit double-word from randomly-selected positions 0-31 in the same buffer, you could use:

UA=BD12.?(0,31)

You can also read unsigned 32-bit values using a lowercase 'd', but signed integer MIDI user variables like UA only hold positive values up to 2^31-1, and unsigned reals like Ua only hold positive integers up to 65535. But random seeds can accept any 32-bit value, so you could use:

?s=Bd12.?(0,31)

For an 8-bit (byte) unsigned integer in the same index range, you could use:

UA=Bb12.?(0,31)

For an 8-bit signed integer you could use:

UA=BB12.?(0,31)

Alternatively, if you know the data is all in the 0-127 range you could omit the 'b' or 'B' and use:

UA=B12.?(0,31)

Note: Any of the above examples can use an expression for the index, but you will need to distinguish it from the use of the the indexed buffer value as part of the expression. For example, consider

UA=Bb12.196*UB+UC

As written, 196*UB+UC will be used as the index. If you want to use just 196 as the index, and use the buffer value at that index in the rest of the expression, you should enclose the index with carets:

UA=Bb12.<196>*UB+UC


Data Size Considerations:

A MIDI buffer doesn't "remember" what data sizes were stored into it; that's up to you. If you store (say) 16 double-words at index 0 to 15, they take up the first 64 bytes of the buffer (16 elements times 4 bytes per element). If you attempt to read 16 words from the same index range, you'll be getting low and high pieces of the first 8 double-words. Word 0 will be the low word of double-word 0, while word 1 will be the high word.

If you read 16 bytes you'll be getting byte-sized pieces of the first 4 double-words, least-significant byte first.

If you pay careful attention to indexing, you can mix different data sizes in the same buffer. For example, if you need to store 16 bytes, 16 words, and 16 double-words, you can store the bytes at indices 0-15. Storing words next, they would start at byte 16, but since word index values are twice as big that would be equivalent to word 8, so the word indices would run from 8-23. The next word index would be 24 (byte 48), which is equivalent to double-word 12, so those would run from index 12 to 27.

However, the above trickery is best saved for a last resort. With 32 buffers available (4 for each of 8 voices) you can usually find plenty of free space.


Macro Buffer Access:

Daqarta's macro system includes 8 arrays (buffers Buf0-Buf7), each holding up to 1024 fixed-point real numbers with 32-bit integer and 32-bit fraction portions. These buffers are normally written and manipulated by macros, but MIDI scripts can load them from text files, and can read and write individual values by referring to the buffer number N (0-7) and index i0 (0-1023) via:

BmN.i0

For example, to set the value of UA into Buf0 at index 321, use:

Bm0.321=UA

To read the value of Buf0 at that index and set it to UA, use:

UA=Bm0.321

The buffer number N is normally given as an immediate digit 0-7, as in the above example. You can use a variable or expression instead by surrounding it with carets. The effective buffer number will be automatically limited to the 0-7 range. Example:

UA=Bm<UB+3>.321

The i0 index can also be replaced with an expression, which will automatically be limited to 0-1023. Examples:

Bm0.UC*2=UA

UA=Bm0.?(0,31)

However, note that in the latter case of reading a buffer value, the expression for the index may need to be distinguished from the use of the indexed buffer value as part of an overall expression. Consider

UA=Bm0.196*UB+UC

As written, 196*UB+UC will be used as the index. If you want to use just 196 as the index, and use the buffer value at that index in the rest of the expression, you should enclose the index with carets:

UA=Bm0.<196>*UB+UC

Note that unlike MIDI buffers, there are no data size considerations when using macro buffers with MIDI scripts: Macro buffer elements can hold any MIDI variable of any width, signed or unsigned.

Also unlike MIDI buffers, since macro buffers hold fixed-point values you can use them to set unsigned fractional-value variables like oscillator (LFO) frequencies, or user variables Ua through Uz.

Note that Daqarta's fixed-point MIDI variables only support values from 0 to 65535.99999, but script expression evaluation maintains the same 64-bit resolution as the macro buffers during calculations, until the final assignment.

One place a large buffer holding large values is very useful is for randomly selecting a Scale from a list of preferred scales. Suppose you have (say) 300 scales in your list, loaded to macro Buf0. You can select one at random and set all voices to use it via:

S9=Bm0.?(0,299)

By comparison, a MIDI buffer only holds 256 bytes. Since Scale values are 0-4095 you'd need to use 16-bit word access, which would limit the buffer to 128 values.

Another application for a large list of large values would be to store seed values for a DaqMusiq performance like GlossyFish, GlossyFishSticks, or GlossyTracks, or for the Music_from_Anything macro mini-app when using the Random Seed Source mode. The starting seed controls the entire performance, so if you save the seeds of favorite performances to a file, you can easily modify the script to load the file and randomly select from the list to produce a "shuffle" that plays only your favorites.

Unlike MIDI buffers and User Variables, macro buffers are not automatically cleared at the start of each MIDI performance. This enables a macro to pass much more information to a MIDI script than is supported by the m0 to m9 special variables intended for that purpose.


Macro String Array Access:

Daqarta's macro system includes 8 String Arrays Str0-Str7, each holding up to 2048 bytes. Though typically used as ASCII text characters, they can be used by MIDI as unsigned integers in the 0-255 range.

Although these string arrays cannot be loaded from files the way macro buffers Buf0-Buf7 can, they can be used by MIDI scripts as extra storage space, and they can be filled by a setup macro before it invokes the MIDI script that will use the values. The Music_from_Anything macro mini-app makes extensive use of Str7 this way.

You can read and write these string arrays from a MIDI script by referring to the array number N (0-7) and index i0 (0-2047) via:

BsN.i0

For example, to enable and set Arpeggio timing for Voice 1, the relevant line in Music_from_Anything is:

Str7[140]="00000000" ;Arpeggio enable/count bitmap

The _MusicData.DQM MIDI script invoked by Music_from_Anything uses the following:

A1=Bs7.<147>-"0"

Here A1 refers to Arpeggio for Voice 1, Bs7 is Str7, and <147> is byte 147 in the array. The Music_from_Anything default line is a substring of 8 "0" characters which runs from Str7[140] through [147]. This is treated like a "bitmap" such that the right-most character (at Str7[147]) applies to Voice 1. Bs7.<147> alone would return the ASCII character "0", which is encoded as 48 decimal or 30 hexadecimal. By subtracting "0" from that value we get a true zero result, which disables the Arpeggio.

Had the user changed the string character to, say, "4", then subtracting "0" would result in an interval of 4 trace updates (typically 10 msec each) between the notes of any chord in Voice 1.

Note the use of <> around the string index; without that (Bs7.147-"0") the index would have included the -"0" to become effectively Str7[147-48], or Str7[99].

_MusicData.DQM also uses Str7 and Str0 bytes as collections of working values. For example Bs7.1981=X1 stores X1, the current on-off state of Voice 1, in Str7[1981] at the end of each voice cycle and tests it before the start of the next; if the user has manually toggled the voice off then it will stay off until manually toggled back on.

The Percussion voice of _MusicData.DQM uses Str0 bytes 101 through 108 to store the initial volume of each tonal Voice 1 through Voice 8 during the fade-out at the end of the performance. At each beat, L1=Bs0.<101>*Qe/UF reads the initial volume and scales it by the fraction Qe/UF, the current number fade beats Qe divided by the preset total fade beats UF. This scaled initial volume is then used to set the new current volume L1 for the voice.


See also Buffer File Load, Changes Script Buffer Operations, Changes Script Overview, Changes Script Editor, MIDI Voice Setup Dialogs, Pitch-to-MIDI dialog, Pitch Track Toolbox - Overview

GO:

Questions? Comments? Contact us!

We respond to ALL inquiries, typically within 24 hrs.
INTERSTELLAR RESEARCH:
Over 35 Years of Innovative Instrumentation
© Copyright 2007 - 2023 by Interstellar Research
All rights reserved