[erlang-questions] Best choice for complex data structure

zxq9 <>
Thu Jan 24 13:50:40 CET 2019


On 2019年1月24日木曜日 6時37分03秒 JST you wrote:
> I'm trying to figure out how to shape the (musical) data.  In everyday 
> language, a musical idea has an architecture of formal nested units and 
> gestures made up of one or more events which have sounds and silences.  
> In Rust, the latter part of the above would yield a statement like:
> 
> scoreIdea.gesture[iGesture-1].event[iEvent-1].sounds +=1
> 
> which is manageable.  But when I think about accessing data nested many 
> levels deep in Erlang, I'm kinda flummoxed. Instinctively, I don't think 
> transliterating something like this to records (or even maps?) is the 
> way to go?
> 
> All suggestions greatly appreciated.

This kind of context is extremely useful to know.

We have some canonical examples of musical data and quite a lot of it is not nested, but rather heavily attributed (includes a lot of meta, but the data itself is flat).

But that is how notations work for musical players (MIDI being a common example).
If you want to capture musical architecture, though, that is something a bit different...
I don't think we've done very well coming up with notations for musical structure in writing, much less computer data.

Overlays and segments for mixes is the best I can think of -- where you store a MIDI sequence along with some meta that identifies it by a useful set of categories (sort of like "tags" on blog posts) and whatever other sort of data might be useful, and then pick from a library of MIDI overlays or segments to insert into an ongoing composition ("flourish X overlays the melody here, segment Y provides a bridge there", etc.).

For maintaining a library of selectable inserts and references you could use simple lists of tuples as the canonical store, and then build reference indexes on them as maps.

CanonicalData :: [{segment, Title :: string(), Authors :: [string()], Date :: date(), Tags :: [string()], MIDI_Data :: binary()}]

TagIndex :: #{Tag := [Title]}

AuthorIndex :: #{Author := [Title]}

etc.

Keeping in mind, of course, that some data element (or combination) will have to constitute a unique key for the data.

I suppose the key question here would be whether you expect this data to be useful for rendering the music in a player, displaying visually in a composition explorer (which could possibly export combined snippets in a flatter, playable format), or interfacing with an existing music tool (Casio/Yamaha/Roland/etc. MIDI interfaces, sheet music PDF renderers, etc.). Any idea on that?

Scores can themselves be compositions of these elements, actually:

Score :: [{InsertTime, Title, SegmentStart, SegmentStop, MIDI_Data, RepeatMeta}]

So that you can move the pieces around in chunks and use the InsertTime as the offset from 0 (in partial beats, milliseconds, whatever meter you want to use) to determine when it first occurs in the piece, the Title to reference which MIDI data should be pulled from the library to include, the SegmentStart as the start of the segment within the MIDI you want to use, and the SegmentStop as the final part of the MIDI you want to use, and RepeatMeta as an optional value (usually something like RepeatMeta :: none | {forever | Count, BreakDelay | BeatIndex}) that can indicate whether a particular segment repeats, how much the delay between occurrences should be (or what beat index within the next opening measure after prior completion it should recur, etc.).

Blah blah...

Anyway, this all depends on what you want the tool to do. Musical scoring in software can get pretty complicated (or sometimes be really simple) depending on what you hope to get out of it.

Hopefully the wandering blather above gives you some ideas.

-Craig


More information about the erlang-questions mailing list