Skip to main content

Library

Struct Library 

Source
pub struct Library<'a> {
    pub header: Header,
    /* private fields */
}
Expand description

A piano library parsed: the prefix, and every stroke with its audio.

Strokes borrow their audio from the Piano they were parsed from, so a transform that drops strokes copies nothing. The fields the container derives — the stroke count, the per-root counts and every audio offset — are not stored in the model at all; Library::to_body computes them from the stroke list, which is what makes an unmodified library rebuild to the bytes it was read from.

Fields§

§header: Header

The container header, carried so a transform yields a whole file.

Implementations§

Source§

impl<'a> Library<'a>

Source

pub fn borrow(file: &'a [u8]) -> Result<Library<'a>, Error>

A whole .npno file parsed over a borrowed slice: the body is taken as a subslice, so every stroke’s audio points into file rather than a copy of it.

The container’s checksum is not verified here — the caller has inspected the container.

Source

pub fn stream_version(&self) -> u16

Source

pub fn channels(&self) -> u16

Source

pub fn block_bytes(&self) -> usize

Bytes in one encoded block, 1022 × channels.

Source

pub fn strokes(&self) -> &[Stroke<'a>]

Source

pub fn without_audio(&self) -> Library<'static>

This library’s prefix and stroke records with no audio behind them: what a encode::Donor::Template reads, and nothing Library::to_body can lay out.

Source

pub fn set_trim(&mut self, index: usize, decibels: u16) -> Result<(), Error>

Retrim the index-th stroke, in the decibels Stroke::trim reads.

Source

pub fn name(&self) -> (String, String)

The (name, variant) pair, from the same field Piano::name reads.

Source

pub fn key_map(&self) -> &[u8]

The 128-entry key map: the root note that plays each key, or UNCOVERED.

Source

pub fn roots(&self) -> BTreeSet<u8>

The root notes the directory records, ascending.

Source

pub fn key_root(&self, key: u8) -> Result<Option<u8>, Error>

The root note whose strokes play key, or None where the map leaves the key uncovered.

Source

pub fn keys_for(&self, root: u8) -> Vec<u8>

The keys the map routes to root, ascending. A root the map never names — including one outside the MIDI range — has no keys.

Source

pub fn fine_tune(&self, key: u8) -> Result<i8, Error>

The per-key fine tune at 0x18c + key, in units worth FINE_TUNE_CENTS_PER_UNIT each. Confirmed on hardware.

Source

pub fn set_fine_tune(&mut self, key: u8, units: i8) -> Result<(), Error>

Retune one key, in the units Library::fine_tune reads.

The unit’s size and direction: Confirmed on hardware. That rewriting the byte retunes the key: Inferred from specimens; not confirmed on hardware.

Source

pub fn gain(&self) -> i8

The gain over the whole library at 0x40c, in tenths of a decibel.

Source

pub fn set_gain(&mut self, tenths: i8)

Source

pub fn damper_top(&self) -> u8

The highest key the instrument damps at note-off, at 0x40d.

Source

pub fn set_damper_top(&mut self, key: u8) -> Result<(), Error>

Move the damper limit. encode::ALL_KEYS_DAMPED leaves no key ringing; a key past the last MIDI note is refused.

Source

pub fn kind_code(&self) -> u8

The instrument kind the library states at 0x18; encode::Kind::from_code names it.

Source

pub fn set_kind(&mut self, kind: Kind)

File the library under another kind of instrument.

The byte changes nothing a library sounds like. Confirmed on hardware.

Source

pub fn long_name(&self) -> Option<String>

The long name at 0x3c and the voicing at 0x5c, which only [VERSION_SPLIT_NAME] streams carry. Both are None on the older stream.

They are their own fields, not a split of the Name#Variant one: a library can spell the long name differently from the name before the #, and the voicing holds neither the padding nor the size suffix the variant does. Inferred from specimens; not confirmed on hardware.

Source

pub fn voicing(&self) -> Option<String>

Source

pub fn set_name(&mut self, name: &str) -> Result<(), Error>

Rename the library, leaving the variant alone.

A name holding NAME_SEPARATOR, or text the field would not read back, is refused; so is one too long for the field it shares with the variant. Nothing is written unless every field the rename touches accepts its text.

On a stream that carries one, the long name is set to the same text: both are the library’s name, and a rename that moved only one would leave the old name showing wherever the instrument reads the other. Which of the two it reads: Inferred from specimens; not confirmed on hardware. That is why both move.

Source

pub fn set_variant(&mut self, variant: &str) -> Result<(), Error>

Replace the variant — the text after NAME_SEPARATOR, where the vendor records the voicing and the library’s size — leaving both names alone. A variant holding the separator itself is refused.

Source

pub fn set_voicing(&mut self, voicing: &str) -> Result<(), Error>

Replace the voicing at 0x5c. Refused on a stream with no such field.

Source

pub fn set_key_root(&mut self, key: u8, root: Option<u8>) -> Result<(), Error>

Route key to root, or to nothing when root is None.

A root the directory does not record is refused: the instrument would have no stroke to play.

That the instrument follows a rewritten map — a key routed to another root, or to nothing: Inferred from specimens; not confirmed on hardware.

Source

pub fn drop_bank(&mut self, bank: Bank) -> Change

Drop every stroke of one bank — the resonance set turns a large library into a small one, the release set silences the note-off sample.

For Bank::Release, the instrument damps the note at note-off where the library it came from plays a release tail. Confirmed on hardware.

Source

pub fn keep_layers(&mut self, keep: &Layers) -> Change

Keep only the layers keep selects, per root and bank.

Confirmed on hardware. A library with its softest layers dropped plays the softest one left at the velocities they had, and is unchanged at loud ones.

Source

pub fn retain_strokes( &mut self, keep: impl FnMut(&Stroke<'a>) -> bool, ) -> Change

Keep the strokes keep accepts and drop the rest, then uncover the keys whose root has gone.

The selection every other transform here is a named case of, for a caller whose own is none of them — one layer on one root, say. A stroke carries its own predictor seeds and its blocks overlap only each other, so whichever subset is left re-lays into a library the writer can lay out.

Inferred from specimens; not confirmed on hardware. Library::drop_bank and Library::keep_layers are the two selections a hardware read covers.

Source

pub fn cut_range(&mut self, range: RangeInclusive<u8>) -> Result<Change, Error>

Uncover every key outside range, then drop the roots nothing plays any more. Keys inside the range keep the roots they had.

That an uncovered key falls silent rather than reaching for a neighbouring root: Inferred from specimens; not confirmed on hardware.

Source

pub fn split_at(&self, key: u8) -> Result<(Library<'a>, Library<'a>), Error>

Two libraries, one covering the keys below key and one covering key and above, each cut the way Library::cut_range cuts.

A root whose keys straddle key lands in both halves — each half has to be playable on its own — so the two together hold more strokes than the one they came from. Each half carries Library::cut_range’s provenance.

Source

pub fn body_len(&self) -> Result<usize, Error>

Bytes the body would occupy.

Source

pub fn to_body(&self) -> Result<Vec<u8>, Error>

Lay the body out: the prefix with its counts rewritten, the directory with every audio offset recomputed, the zero gap, then the audio spans in directory order.

Confirmed on hardware. A body laid out here, with a directory the transforms shortened and every span moved, is accepted by the instrument and plays at the level the library it came from plays at.

Source

pub fn to_piano(&self) -> Result<Piano, Error>

The library as a file, ready to write. The container recomputes its own checksum.

The u32 at body 0x06 is unique per file and is not a checksum, a size or a hash of anything in it; with nothing to recompute it from, an edit carries it over rather than inventing a value. The hardware evidence reaches no further than this: a library carrying its source’s word loads and plays. Confirmed on hardware. What the word means is open.

Trait Implementations§

Source§

impl<'a> Clone for Library<'a>

Source§

fn clone(&self) -> Library<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Library<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Library<'a>

§

impl<'a> RefUnwindSafe for Library<'a>

§

impl<'a> Send for Library<'a>

§

impl<'a> Sync for Library<'a>

§

impl<'a> Unpin for Library<'a>

§

impl<'a> UnsafeUnpin for Library<'a>

§

impl<'a> UnwindSafe for Library<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.