DixShtix

com.dixshtix.niff
Class DataSection

java.lang.Object
  |
  +--com.dixshtix.niff.DataSection

public class DataSection
extends java.lang.Object

The part of a NIFF file that contains the music symbols and layout information.

Hierarchy

The music symbols in the DataSection are stored in page-ordered format. The format has a hierarchical structure, where pages contain systems, systems contain staves, and staves contain time-slices and individual musical symbols. Within each level, data are supplied generally in a left-to-right, top-to-bottom order, except as indicated. Text and graphics can be included at any level of the hierarchy, according to the type of object to which they logically belong.

RIFF file LISTs and Chunks

Pages, systems, and staves are all represented by RIFF-style LISTs, composed of a header chunk followed by other component chunks that belong at that same hierarchal level. To save space, in the RIFF-representation, the time-slice has not been been defined as aa LIST chunk. Instead the time-slice chunks act as a header to a group of symbol chunks which follow it. (c.f. the usage of the <P> in lazy HTML has no close tag.) Every symbol within a staff LIST, except for text or graphics immediately following the StaffHeader Chunk is logically associated with the Time-Slice chunk that most closely precedes it.

A Staff list may contain music symbols belonging to more than one part. When more than one part is present one the staff, the part must be uniquely identified for every symbol. When only one part is present in a particular Staff LIST, its Part ID is identified in the Staff Header chunk instead of on the individual symbols.

Simulated Part Ordering, and Spacing by Part

A special case of the page-ordered data structure is known as "simulated part ordering." In this structure, there is only one system on one "very wide" page that extends from the start to the end of the score, which each part appearing on its own staff or staves. This special type of file contains a single Page LIST whose ChunkLengthTable.PageHeader Chunk has zero Width and Height tags.

The simulated part ordering structure is designed to accommodate non-page-oriented programs and programs which offer the user to strip page layout data when writing NIFF files. The music symbols of a one-staff part would all be stored contiguously on a single Staff LIST. Multiple-staff parts, such as piano or organ, would be split apart into two or more Staff LISTs.

Another special type of file structure is "spacing by part." In this scheme, used by some notation programs, the symbols of each part are assigned horizontal placement values independently of the other parts, as though the the file contained a set of part scores instead of one ensemble score. This could be used in a file with page ordering or simulated part ordering. A file recorded with this scheme is identified by the presence of the SpacingByPart tag on the NIFF Information Chunk in the SetupSection. Reading programs unable to make use of the this spacing should ignore all horizontal placement values, using its own spacing defaults instead.

Notes and Stems

A musical note is normally composed of at least two chunks, a Stem Chunk and a Notehead Chunk. A single note is a degenerate case of a chord. A full chord is represented by a Stem Chunk and several Notehead Chunks, each of which represents a single notehead. In the spirit of NIFF's philosophy of "no illegal files," there is no requirement than a Stem be followed by any noteheads.

Reference points.

Every symbol has a default reference point used in interpreting the logical and absolute placement values. For a symbol such as an accidental or clef sign which has a natural "hot spot," the chunk definition specifies the hot spot as the default reference point. The default reference point of a Time-slice is the intersection of the time-slice at the staff's top line. If not otherwise specified, the default reference point of a symbol is the center of its bounding box.

When an absolute placement value is supplied for a dependent symbol, the meaning of its value is "the offset of the dependent symbol's reference point from the anchor symbol's reference point." Note that the NIFF reference point is not the same as the default placement. In other words, an absolute offset of (0,0) on a symbol does not mean "place the symbol exactly at its default horizontal and vertical position." Instead, it means "place the reference point of the symbol (often its center) exactly on top of the reference point of its anchor (often the anchor's center)."

The Reference Point Override tag can be used to temporarily change the reference point of either the anchor or the dependent symbol, or both. Descriptions of non-default reference points include codes such as "left of symbol's bounding box", "top of symbol's bounding box", or "vertical center of symbol's bounding box." When present, this tag is always specified on the dependent symbol for a particular dependent/anchor relationship.

Reference points on the anchor and dependent symbols are only to be considered when explicit placement information is supplied. Otherwise, the reading program should use its own defaults to determine the placement of a dependent symbol relative to its anchor.

Chapter 2 - Symbol Relationships

The meaning of a music notation symbol often depends on its relationships with other music symbols. Storing enough information in the NIFF file to relate music symbols to one another introduces complex programming issues. NIFF has been carefully designed in an attempt to allow programs to indicate symbol relationships with logical rigor, flexibility and efficiency. A balance has been sought between the sometimes conflicting efficiency goals of minimizing processing time, programming effort, memory usage and disk space.

Dependent symbols and their anchors.

In NIFF, a music symbol whose placement depends on one or more other symbols is called a "dependent" symbol, and the symbol or other chunk type on which its placement depends is called its "anchor." For each symbol chunk type, a default anchor chunk type is defined. For example, for the Fingering chunk, the Notehead is the default anchor, and for the Articulation chunk, the Stem is the default anchor.

The Anchor Override tag can be used on a dependent symbol chunk to indicate a non-default anchor type. For example, a Slur's default anchor type is a Stem, but an anchor override could be applied to a particular slur endpoint to anchor it to a Notehead or Fingering chunk instead. The Time-Slice is the default anchor for some symbols, and is a valid override anchor as well.

The dependent/anchor relationship between symbols plays a major role in both file syntax and symbol placement.

File Syntax rules.

There are two rules defined for the syntactic order of dependent and anchor symbols:

  1. The dependent symbol physically appears in the file as soon as possible after its anchor.

    "As soon as possible" means that the only symbols that can be stored between a dependent symbol and its anchor are other symbols dependent on the same anchor, and nested symbols dependent on those.

  2. When more than one symbol is dependent on the same anchor, the dependent symbols should be placed in the file in order of graphical proximity to the anchor, from nearest to farthest. For symbols that are the same distance from the anchor, or when distance doesn't matter, any order will do.

A detailed example demonstrating these rules is given below.

Stems and Notes.

The relationship between the Stem chunk and Notehead chunk is a little different from other symbol relationships. In terms of syntax, the Notehead is dependent on the Stem (i.e. Noteheads appear in the file after their associated Stem). However, for symbol placement, both the Notehead and Stem are dependent on the Time-Slice. This is discussed below in "Reference points on Noteheads and Stems."

Noteheads and Stems bypass syntax rule 2. Notehead chunks always follow the Stem chunk in order from highest to lowest pitch.

Complex dependencies - some examples.

The file syntax and use of the Anchor Override tag allow complex dependencies to be represented in NIFF. For example, consider a slur between two fingering numbers related to a single notehead, parentheses surrounding the staccatos over a series of notes, or a small sharp sign above a trill ornament over a note. The anchor of each symbol is the chunk of the appropriate type (either default or explicit) which most closely precedes the dependent symbol in the file.

Here are two examples in NIFF pseudo-code. In Example A1 there is a small sharp sign over a trill ornament anchored to one note of a chord; a fingering number is anchored to another note of the chord. In Example A2 parentheses surround the staccatos over three notes.

Diagram A1

Example A1:

Stem
    Notehead, staff step=3, duration=1/4
        Fingering, shape=1
    Notehead, staff step=7, duration=1/4
        Ornament, shape=short trill
            Accidental, shape=sharp, Small Size, Anchor Override=Ornament, Logical Placement=above [discussed later]

Diagram A2

Example A2:

Time-Slice, type=event,start time=0/4
    Stem
        Notehead, staff step=5, duration=1/4
        Articulation, shape=staccato
            Parenthesis, shape = "(", Anchor Override=Articulation,Logical Placement = left, ID=1, Number of Nodes=2 [multi-node, discussed below]
Time-slice, type=event, start-time=1/4
    Stem
        Notehead, staff step=5, duration=1/4
        Articulation, shape=staccato
Time-slice, type=event, start-time=2/4
    Stem
        Notehead, staff step=5, duration=1/4
        Articulation, shape=staccato
            Parenthesis, shape = ")", Anchor Override=Articulation,Logical Placement = right, ID=1

Multi-node symbols.

Beams, Slurs, Ties and Hairpins are examples of symbols which are normally dependent on more than one anchor. The interpretation of syntax rule 1 would be ambiguous in the case of a dependent symbol with a one-to-many relationship with its anchors. For example, consider a beam connecting three stems. Should the beam appear after the first, second or third stem? To allow syntax rule 1 to be applied consistently, one-to-many relationships have been decomposed in NIFF into one-to-one relationships by subdividing the "one" dependent symbol into several node chunks of a "multi-node symbol", each one corresponding to one of the "many" anchor chunks. Syntax rule 1 can then be followed: each dependent symbol node chunk physically appears in the file immediately after its corresponding anchor chunk.

For example, the beam is decomposed into nodes, each one corresponding to a stem. Each node supplies information about the beam at that point, i.e. the number of beam parts to the left and to the right of that stem, including partial (fractional) beams.

Every node of a multi-node symbol must contain an ID tag. The same ID is used on all nodes of a multi-node symbol, so the nodes can be recognized as belonging to the same symbol. As a convention, ID numbers should be assigned sequentially within a chunk type starting with zero.

The first node of a multi-node symbol (the one appearing physically first in the file) has some special properties. Any information which applies to the symbol as a whole appears here, such as the Fanned Beam tag on Beams. Tags which are independently associated with each node, such as Bezier Incoming/Outgoing and the Anchor Override tag can appear on any node.

The first node also contains the Number of Nodes tag indicating how many nodes are present in the file for the multi-node symbol with this ID. This allows the reading program if desired to allocate the appropriate amount of storage when it finds the first beam node, and to release the storage when it has found and handled the last beam node. The Number of Nodes tag and ID tag together identify a symbol as multi-node. In the rare case of a one-node symbol of a type which is normally multi-node, such as a beam when it is anchored to only one stem, the one beam chunk need not contain the Number of Nodes or ID tags.

In a cross-staff beam which starts on a stem in the lower staff and ends on a stem in the upper staff of a piano grand staff, the first beam node to appear in the file may be the one corresponding to the rightmost stem in the beam structure (the last one in time-slice order), or perhaps even to a stem in the middle of the beam structure. The reading program may not be able to reconstruct the complete beam until the last beam node has been read.

Here is an example in NIFF pseudo-code, showing a cross-staff beam connecting three eighth notes in ascending order.

Diagram B

Example:

(Staff 1)
Time-slice, type=event, start time=1/8
    Stem
        Beam, ID=1, Number of Nodes=3,parts to left=1, parts to right=1
        Notehead, staff step= 2, duration=1/8
Time-slice, type=event, start time=2/8
    Stem
        Beam, ID=1, part to left=1, parts to right=0
        Notehead, staff step=5, duration=1/8

(Staff 2)
Time-slice, type=event, start-time=0/8
    Stem
        Beam, ID=1,parts to left=0, parts to right=1
        Notehead, staff step= 6, duration=1/8

NameTypeContainerID
Data Section ListLIST ChunkNIFF formdata
ContentsRequiredIn Any OrderDescription
PageListNO, any numberNOZZZZ


Field Summary
static FourByteConstant listType
           
 
Constructor Summary
DataSection(boolean simulatedPartOrdering, float defaultPageWidth, float defaultPageHeight)
           
 
Methods inherited from class java.lang.Object
, clone, equals, finalize, getClass, hashCode, notify, notifyAll, registerNatives, toString, wait, wait, wait
 

Field Detail

listType

public static final FourByteConstant listType
Constructor Detail

DataSection

public DataSection(boolean simulatedPartOrdering,
                   float defaultPageWidth,
                   float defaultPageHeight)

DixShtix