Closed bmcfee closed 8 years ago
Some ideas:
Annotation.to_namespace(target_namespace)
jams.ns
.(ns_from, ns_to)
, where ns_from
is a regexp to match the input annotation namespace, and ns_to
is the target_namespace
When the dust settles, an example converter might look like:
@converter('tag_.*', 'tag_open')
def to_tag_open(annotation):
annotation.namespace = 'tag_open'
return tag_open
The converter
decorator handles the following:
Another idea for #16:
For instance jams.eval.chord()
only operates on chord_harte
annotations. Currently, if an annotation is not of the right namespace, it fails with an exception. However, we can instead try:
R = ref_annotation.to_namespace('chord_harte')
E = est_annotation.to_namespace('chord_harte')
and proceed as normal.
@bmcfee do we have any existing converters I could have a look at? Looking to implement the pitch_hz
<->pitch_midi
converter asap.
Nope, I haven't gotten around to it yet, mainly because I haven't had a need yet.
However, having it in place might simplify some of the sonification logic, and I think the decorator syntax makes sense.
There are still some API/implementation issues to sort out: should conversion be a method of Annotation? or a stand-alone function? How should we store the routing logic (maybe a global dict)?
Well, it would be cool if based on the namespace of an Annotation it would make the relevant conversion functions available. For example, a pitch_hz
annotation would have to_pitch_midi
, and vice versa. That said, I don't have a strong opinion about this, and I'd be happy to have something a la jams.convert(my_ann, 'pitch_midi')
. I just need it now, so feel free to make an executive call on this.
As for routing logic, not sure I know what you're referring to :walking:
Well, it would be cool if based on the namespace of an Annotation it would make the relevant conversion functions available. For example, a pitch_hz annotation would have to_pitch_midi, and vice versa.
Yeah, but you can't do it piecemeal because namespaces are set dynamically.
That said, I don't have a strong opinion about this, and I'd be happy to have something a la jams.convert(my_ann, 'pitch_midi'). I just need it now, so feel free to make an executive call on this.
This would be my preferred way to do it.
As for routing logic, not sure I know what you're referring too
Exactly what you're describing: the function that figures out the target namespace, the source namespace, and the appropriate conversion function (if one exists). It's probably a dict of dict, so you'd have something like:
mappers = {}
mappers['pitch_hz'] = dict('pitch_midi'=convert_pitch_midi_to_hz, 'pitch_class'=convert_pitch_class_to_hz)
mappers['tag_open'] = dict('tag_.*'=convert_tag_all_to_open)
Then the routing logic would just be:
def convert_namespace(annotation, ns_target):
if ns_target in mappers:
for source in mappers[ns_target]:
if annotation.search(namespace=source):
return mappers[ns_target][source](annotation)
raise NamespaceError('Could not convert {} to {}'.format(annotation.namespace, target))
Looks good to me! Wanna add this into a new branch/PR that I can work off, or shall I?
i'll hack it in a little bit
Excellent, thanks. Once the basic structure is in place I'll add the two converters for pitch_hz
<-> pitch_midi
. Guess I'll go stare at the MIDI->JAMS converter in jams-data
for now :)
Wherever it makes sense, we should have converter scripts to move between namespaces.
This could get pretty messy.
From the current set, the following seem feasible:
beat_position
->beat
tag_*
->tag_open
segment_*
->segment_label_open
pitch_hz
<->pitch_midi
pitch_class
->pitch_midi
,pitch_hz
chord_roman
->chord_harte
(?)(I'm not sure about that last one; is it possible?)
There are some issues to hammer out with regards to additional parameters of the conversion. For instance,
pitch_class_to_midi
would probably require an octave indicator, unless we just make everything start at C4 or something.Of course, all of this is up for discussion.