Re: [linux-audio-dev] MIDI sync issues; mmc, mtc, ...

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] MIDI sync issues; mmc, mtc, ...
From: Dan Mills (dmills_AT_spamblock.demon.co.uk)
Date: Thu Dec 21 2000 - 20:04:46 EET


On Thu, 21 Dec 2000, Kai Vehmanen wrote:
>
> Just the thing I meant bring up next. Now even if its doable to implement
> a steady, outgoing MTC stream from a userspace app, it still seems
> difficult to combine it to an existing audio app. If we generate the
> MTC-bytes in the audio loop, MTC accuracy depends on the used buffersize
> (1024 samples frames at 44100kHz -> 23ms per iteration). Also, writing
> directly to midi-devices from the audio thread, we risk blocking the audio
> operations. So it would look like we need to do the midi i/o from
> another thread - either put a ringbuffer between the audio and midi
> threads or have the midi thread generate the MTC-bytes itself.

Hi, All.
I am a newbie around here, but:

  When I needed a timecode transmitter for a project I did it as follows
There was a midi transmitter thread which could block on transmit, which
was supplied with data from a linked list of midi messages.
The trick is that when adding a message to the list the audio thread
would prepare a structure:

struct midi_msg {
        int length; /* number of bytes to send */
        struct midimsg *next;
        char *data;
};

which could then be added to the end of the linked list of messages to
send, as adding this block requires updating a single pointer (I maintain
a pointer to the tail of the list (but that is NOT used by the midi
thread)) this operation is atomic and there is no need for anyone to block.
Then I wake the midi thread if it is waiting on data being available.
Obviously if the midi bus is heavily loaded then some messages may be
in the transmit queue, but that is seldom a problem in practice.

Now this obviously does not solve the problem of who generates the data,
and I do not know the Ardour architecture (I dont know C++), but you
could provide a fairly general event trigger system by maintaining
a sorted list of

struct time_event {
        int time; /* in samples */
        void (*timer_cb)(void *data);
        struct time_list *next;
};
Then before processing an audio data block, you check if it contains
a time in the list (easy because it is sorted)..., this really has to
be handled at he lowest possible level, and will be a pig to get right.
Obvoiusly the same mechanisim could be used within the main loop
for automation events (The difference is that an automation event can
have blocksize latency without it being much of a problem (most of the
time)).

> Another thing (probably ecasound-specific problem) is what time to
> actually use when generating MTC. For a wall-clock sync, it's reasonable
> to use the "engine-time", ie. how many samples have passed the main engine
> loop. But this won't do if we want to use MTC for syncing audio. Then we
> need to use soundcard's current pointer to calculate the current time...

Humm, you should probably have a user adjustable 'slip' control so that
you can accurately align the timecode with the audio. This would be so
much easier under QNX or OS9.....

Syncing to external MTC is another area which gets 'exciting', I ran a
softwre PLL to de jitter the incomming timecode and to convert from
24/25/30/29.97 FPS into a sample number, then you have to somehow
adjust the exact playout speed (soundcard sample rate), to bring the
two clocks into alignment. I did this by simply repeating or dropping
samples as needed, ugly but it worked. If your soundcard gives you
control of the sample rate at the sub Hz level, then this becomes
easier.

Regards, Dan.

-- 
The email address **IS** valid (You do **NOT** need to remove spamblock).
And on the evening of the first day the lord said.....
..... LX 1, GO!! and there was light!


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Thu Dec 21 2000 - 21:15:36 EET