Comments (7)
Hi,
Thanks for using the library!
In fact, DryWetMIDI has MIDI clock class (MidiClock) but it's internal and used by playback API. Before I make it public, I'll say how it's supposed to be used.
Clock based on high resolution timer which raises event when specified period is elapsed (1 ms is the smallest possible interval), so CurrentTime
property is of TimeSpan
type since millisecond is a "native" unit for timer. So you need to convert it manually to ticks with TimeConverter.ConvertFrom((MetricTimeSpan)CurrentTime, tempoMap)
.
Tick
event is raised on ms elapsed, not on single MIDI tick, since one tick require submillisecond timer resolution in general, which is not possible. (By the way, Sanford library doesn't raise event on every tick, it just throws multiple tick values at one time on ms elapsed.)
In order to convert to ticks you need TempoMap
instance holding time division, tempo and time signature changes since in general MIDI file (and DAW) can has different tempo and time signature at different points in time. Time division allows you to specify ticks (pulses) per quarter note which is constant for MIDI file (or DAW project).
Started/Stopped event are missing at now but it's not a problem to add them.
Please let me know if you need more details or clarification on things above. Also information about how you will use clock would be very useful.
from drywetmidi.
Thanks for your quick and extremely helpful response! Now that I understand how the MidiClock class works, I like it – it does just what it is supposed to do and nothing more, which makes it a nice building block!
I’ve spent the day experimenting with the MidiClock class, and have managed to build a custom clock that does what I initially wanted – which is to control the playback functionality of the DAW Cakewalk from within my application. All my clock really does so far is converting the MidiClock ticks to midi pulses like you explained how to do, sending out a TimingClockEvent every 24th pulse, and controlling playback by sending Start, Stop, Continue and SongPositionPointer events. But I’ve run into a quirk* with Cakewalk that makes me consider trying to implement a MTC clock instead. At first glance it seems easy enough to do, the only thing I’m feeling a bit unsure about is how to send full time code messages, as it doesn’t seem to be implemented as a separate event in DryWetMidi. But I’m guessing it should as simple as creating a NormalSysExEvent and putting in the right bytes?
*Footnote: Moving back and forth in time using the SongPositionPointerEvent feels kind of hacky in Cakewalk: It does not work while playback is ongoing, but will work if you place it between a Stop and Continue event, but only if there is some time delay between these events (not sure how much is needed). When using this method I also have to keep sending TimingClock events while playback is stopped, otherwise resuming playback is janky and does not always work.
from drywetmidi.
According to link you've provided, Full Time Code is just a system exclusive message. So yes, you just need to send NormalSysExEvent
:
new NormalSysExEvent(new byte[] { 0x7F, 0x7F, 0x01, 0x01, hh, mm, ss, ff, 0xF7 })
where instead of hh, mm, ss, ff you should provide desired values for hours, minutes, seconds and frames. Starting 0xF0
byte must not be specified since it will be used automatically.
from drywetmidi.
Also I suppose it's OK that you must stop playback before jumping to new time. Changing current time without stopping can lead to errors and race conditions in internal DAW clock.
My library has Playback
class which provides methods to change current time. But I also stop playback before changing clock's time and then start it again if needed. Since changing time in general involve some set of operations, this process can take time. During this amount of time your playback can go crazy, for example, wrong events can be sent to device or some MIDI events can be dropped because of clock's time is being changed.
Maybe there is information about how to automate Sonar by external MIDI commands so you can determine when DAW is ready to change song position?
from drywetmidi.
That makes sense. I did some research about automating Cakewalk with midi, and although I’ve yet to find a good way to determine if it is ready to change song position, I did discover lots of other things that can be controlled through midi that I had no idea about, so thanks for the suggestion!
Anyway, all of my issues relating to DryWetMidi has now been resolved, so I think this thread can be closed. Although I do think it would be a good idea to make the MidiClock class public, as it was useful to me, and I think it could be useful to other people as well – so maybe leave it open until that is done?
from drywetmidi.
Yes, I'm going to make changes within this issue :)
from drywetmidi.
MidiClock
is now public. So I'm closing the issue.
@bent95, feel free to open new issues if you have any problems with the library and thanks for sharing your experience.
from drywetmidi.
Related Issues (20)
- Remove all notes example from the README not working HOT 9
- Using wetdrymidi in C# project causes error CS0009
- InputDevice event listening crash HOT 2
- Crash when running in Unity on M2 MacBook HOT 3
- MidiDeviceException Internal error HOT 9
- Android Support
- Unity cannot exit after use HOT 10
- MidiClock sync problem HOT 6
- MIDI Tempo changes count returns 1 but the song has 6 tempo changes. HOT 1
- add il2cpp mode HOT 5
- CustomChunk no mididata throw error HOT 4
- CSharp Code Error HOT 2
- MIDI File returns error: InvalidMetaEventParameterValueException HOT 1
- Unable to send Note-On event to device HOT 8
- Cannot get track name to change HOT 10
- How to use DryWetMidi in Visual Basic (VS 2022) ? HOT 20
- Plans for MIDI 2.0 Support? HOT 2
- Skipping notes HOT 5
- Playback Loop=True skips empty steps in the end of a Pattern HOT 2
- Syncing multiple Playbacks HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from drywetmidi.