* How to tell how many frames gone to PCM
@ 2005-04-26 20:18 Steve deRosier
2005-04-26 20:16 ` Lee Revell
[not found] ` <ad2655cb0504270201165f9859@mail.gmail.com>
0 siblings, 2 replies; 13+ messages in thread
From: Steve deRosier @ 2005-04-26 20:18 UTC (permalink / raw)
To: Alsa-Devel
All,
I'm having issues w/ synchronizing MIDI and audio data I output via Alsa. I'm working through my program trying to confirm data flow and I need some help.
Is there a particular function (or other method) I can use to tell me the number of frames I have sent to alsa via snd_pcm_writei()?
Either type would be good:
---
open pcm
write all data
get # frames written
close pcm
--- or
open pcm
get current frame count
write all data
get new frame count
print new - old counts
close pcm
---
Any help you could give would be appreciated.
Thanks,
- Steve
-------------------------------------------------------
SF.Net email is sponsored by: Tell us your software development plans!
Take this survey and enter to win a one-year sub to SourceForge.net
Plus IDC's 2005 look-ahead and a copy of this survey
Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: How to tell how many frames gone to PCM 2005-04-26 20:18 How to tell how many frames gone to PCM Steve deRosier @ 2005-04-26 20:16 ` Lee Revell 2005-04-26 21:07 ` Steve deRosier [not found] ` <ad2655cb0504270201165f9859@mail.gmail.com> 1 sibling, 1 reply; 13+ messages in thread From: Lee Revell @ 2005-04-26 20:16 UTC (permalink / raw) To: Steve deRosier; +Cc: Alsa-Devel On Tue, 2005-04-26 at 13:18 -0700, Steve deRosier wrote: > All, > > I'm having issues w/ synchronizing MIDI and audio data I output via Alsa. I'm working through my program trying to confirm data flow and I need some help. > > Is there a particular function (or other method) I can use to tell me the number of frames I have sent to alsa via snd_pcm_writei()? Just keep track of it yourself. snd_pcm_writei() returns the number of frames written on each call, so keep a running total. Lee ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-26 20:16 ` Lee Revell @ 2005-04-26 21:07 ` Steve deRosier 2005-04-26 21:17 ` Lee Revell 0 siblings, 1 reply; 13+ messages in thread From: Steve deRosier @ 2005-04-26 21:07 UTC (permalink / raw) To: Lee Revell; +Cc: Alsa-Devel Yeah, already doing that. I was hoping there was something else I could use to confirm the numbers I'm getting. Here's the problem... In order to get my MIDI and audio to sync up, I found about 1.5 years ago I had to add +4 to my sample count per PERIOD_SIZE number of samples I sent to the PCM. I calculate my midi out time via the number of samples I've sent to the PCM. I never could account for the discrepancy, and eventually settled for the hack (with a big fat comment in the code and a bug note in our bugzilla) in order to get our first software version shipped. As you might imagine, this has come back to haunt me periodically as we continue to maintain the software. It could be I NEED to do what I do in the hack do to something I'm not realizing, but it bothers me when I've got to do something I don't understand and is not supported by the assumptions in the system. It could be something I'm doing weird (say an off by one bug in the code), or that I'm not using alsa right, but I've not been able to find it. Now I'm against the wall and I've got to solve the problem (or at least understand why I have to do what I'm doing). Using the return value seems to report the expected number of frames as what I sent. Frankly I was hoping that I'm not sending the expected number of frames to the PCM, figuring that it would give me a string to pull on. Any more ideas would be great. Thanks, - Steve Lee Revell wrote: > On Tue, 2005-04-26 at 13:18 -0700, Steve deRosier wrote: > >> All, >> >> I'm having issues w/ synchronizing MIDI and audio data I output via >> Alsa. I'm working through my program trying to confirm data flow >> and I need some help. >> >> Is there a particular function (or other method) I can use to tell >> me the number of frames I have sent to alsa via snd_pcm_writei()? >> > > > Just keep track of it yourself. snd_pcm_writei() returns the number > of frames written on each call, so keep a running total. > > Lee > ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-26 21:07 ` Steve deRosier @ 2005-04-26 21:17 ` Lee Revell 2005-04-26 21:45 ` Steve deRosier 0 siblings, 1 reply; 13+ messages in thread From: Lee Revell @ 2005-04-26 21:17 UTC (permalink / raw) To: Steve deRosier; +Cc: Alsa-Devel On Tue, 2005-04-26 at 14:07 -0700, Steve deRosier wrote: > Any more ideas would be great. > One possibility is that you are hitting an ALSA bug. Some fixes have been merged since ALSA 1.0.8 for bugs that could account for the strange behavior. The first thing to do is verify the problem does not appear with a newer ALSA. Another idea, by default the MIDI timing will be driven by the system timer, while the PCM will be driven by the soundcard timer, even if your MIDI port is on the same board as your audio. Although I would expect the drift to be very small. As a last resort, you could hack the low level driver to keep track of the frames written to the hardware. Add a counter to the chip structure and increment it in the interrupt handler. Lee ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-26 21:17 ` Lee Revell @ 2005-04-26 21:45 ` Steve deRosier 2005-04-27 14:36 ` Clemens Ladisch 0 siblings, 1 reply; 13+ messages in thread From: Steve deRosier @ 2005-04-26 21:45 UTC (permalink / raw) To: Lee Revell; +Cc: Alsa-Devel > > One possibility is that you are hitting an ALSA bug. Some fixes have > been merged since ALSA 1.0.8 for bugs that could account for the strange > behavior. The first thing to do is verify the problem does not appear > with a newer ALSA. > I'll have to try that. I think we're running 1.0.4 at the moment. We hesitate to update at this point due to most things just working (mine is the only alsa using program in the system experiencing this problem) and we have a headache every time we upgrade, but maybe it won't be so hard this time around since the API has solidified more than in earlier upgrade tries. > Another idea, by default the MIDI timing will be driven by the system > timer, while the PCM will be driven by the soundcard timer, even if your > MIDI port is on the same board as your audio. Although I would expect > the drift to be very small. > I should (if I did it right) have the pcm and midi timers linked. I use two different classes for output, one for the PCM (called CDSP) and one for the MIDI (called CMIDIPort). Usually this makes things simple, but linking the clocks requires pasing info back and forth between the two. My thread does this: --- mPCMInfo = mDSP.GetInfo(); if( !mPCMInfo ) return false; if( !mMIDIPort.LinkPCMTimer( mPCMInfo ) ) return false; return true; --- calling CDSP::GetInfo(): --- snd_pcm_info_t * CDSP::GetInfo( void ) { snd_pcm_info_t * PCMInfo; snd_pcm_info_malloc( &PCMInfo ); int err = snd_pcm_info( hPCM, PCMInfo ); if( err < 0 ) { FreeInfo( PCMInfo ); return NULL; } return PCMInfo; } --- And to actually link the timers: --- bool CMIDIPort::LinkPCMTimer( const snd_pcm_info_t * PCMInfo ) { if( !PCMInfo ) return false; snd_seq_queue_timer_t * QueueTimer; snd_timer_id_t * QTID; // get the info we need int Card = snd_pcm_info_get_card( PCMInfo ); unsigned int Device = snd_pcm_info_get_device( PCMInfo ); unsigned int SDevice = snd_pcm_info_get_subdevice( PCMInfo ); SDevice = SDevice << 1; // check for bad return if( ( Card < 0 ) ) return false; // build our timers snd_seq_queue_timer_alloca( &QueueTimer ); snd_timer_id_alloca( &QTID ); if( snd_seq_get_queue_timer( hSeq, mQueue, QueueTimer ) < 0 ) return false; // setup the data that links us to the PCM snd_timer_id_set_class( QTID, SND_TIMER_CLASS_PCM ); snd_timer_id_set_sclass( QTID, SND_TIMER_SCLASS_NONE ); snd_timer_id_set_card( QTID, Card ); snd_timer_id_set_device( QTID, Device ); snd_timer_id_set_subdevice( QTID, SDevice ); // setup the actual timer snd_seq_queue_timer_set_type( QueueTimer, SND_SEQ_TIMER_ALSA ); snd_seq_queue_timer_set_id( QueueTimer, QTID ); snd_seq_set_queue_timer( hSeq, mQueue, QueueTimer ); return true; } --- Is that done right? Is there something I'm forgetting to do? > As a last resort, you could hack the low level driver to keep track of > the frames written to the hardware. Add a counter to the chip structure > and increment it in the interrupt handler. > Ick. Last resort definately. Though I have hacked some of the drivers before, I'd just rather not; you know what I mean? ;) Thanks, - Steve ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-26 21:45 ` Steve deRosier @ 2005-04-27 14:36 ` Clemens Ladisch 2005-04-27 16:56 ` Steve deRosier 0 siblings, 1 reply; 13+ messages in thread From: Clemens Ladisch @ 2005-04-27 14:36 UTC (permalink / raw) To: Steve deRosier; +Cc: Lee Revell, Alsa-Devel Steve deRosier wrote: > > Another idea, by default the MIDI timing will be driven by the system > > timer, while the PCM will be driven by the soundcard timer, even if your > > MIDI port is on the same board as your audio. Although I would expect > > the drift to be very small. Oh, you really expect the (potentially overclocked) system clock and the cheapo sound card crystal to be accurate? ;-) > I should (if I did it right) have the pcm and midi timers linked. > > // setup the data that links us to the PCM > snd_timer_id_set_class( QTID, SND_TIMER_CLASS_PCM ); > snd_timer_id_set_sclass( QTID, SND_TIMER_SCLASS_NONE ); > snd_timer_id_set_card( QTID, Card ); > snd_timer_id_set_device( QTID, Device ); > snd_timer_id_set_subdevice( QTID, SDevice ); > > // setup the actual timer > snd_seq_queue_timer_set_type( QueueTimer, SND_SEQ_TIMER_ALSA ); > snd_seq_queue_timer_set_id( QueueTimer, QTID ); > snd_seq_set_queue_timer( hSeq, mQueue, QueueTimer ); > > Is that done right? Is there something I'm forgetting to do? You should check the error code, but otherwise this looks OK. Are the inaccuracies you're seeing consistent, and/or dependent on some specific hardware? Regards, Clemens ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-27 14:36 ` Clemens Ladisch @ 2005-04-27 16:56 ` Steve deRosier 2005-04-27 17:22 ` Clemens Ladisch 0 siblings, 1 reply; 13+ messages in thread From: Steve deRosier @ 2005-04-27 16:56 UTC (permalink / raw) To: Clemens Ladisch; +Cc: Lee Revell, Alsa-Devel Clemens Ladisch wrote: > Steve deRosier wrote: > >>>Another idea, by default the MIDI timing will be driven by the system >>>timer, while the PCM will be driven by the soundcard timer, even if your >>>MIDI port is on the same board as your audio. Although I would expect >>>the drift to be very small. > > > Oh, you really expect the (potentially overclocked) system clock and > the cheapo sound card crystal to be accurate? ;-) > Nope. Though, in our case not overclocked but with other issues, see below... > >>I should (if I did it right) have the pcm and midi timers linked. >> >> // setup the data that links us to the PCM >> snd_timer_id_set_class( QTID, SND_TIMER_CLASS_PCM ); >> snd_timer_id_set_sclass( QTID, SND_TIMER_SCLASS_NONE ); >> snd_timer_id_set_card( QTID, Card ); >> snd_timer_id_set_device( QTID, Device ); >> snd_timer_id_set_subdevice( QTID, SDevice ); >> >> // setup the actual timer >> snd_seq_queue_timer_set_type( QueueTimer, SND_SEQ_TIMER_ALSA ); >> snd_seq_queue_timer_set_id( QueueTimer, QTID ); >> snd_seq_set_queue_timer( hSeq, mQueue, QueueTimer ); >> >>Is that done right? Is there something I'm forgetting to do? > > > You should check the error code, but otherwise this looks OK. > Error code for which function? It's been a long time since I wrote the code and frankly I'm not 100% sure I understand it anyway. > Are the inaccuracies you're seeing consistent, and/or dependent on > some specific hardware? Doubtful. And not dependent uppon a particular Alsa version either (though I'm in the process of upgrading my Alsa to 1.0.9rc2 in order to get current and eliminate that concern). See, we've got another player on the system (let's call it a "file player") that plays in sync just fine, but my program ("CD player" if you will) won't. Now, since mine came second, much of the Alsa functionality was modeled off the "file player" so they are very similar in Alsa specifics (though hugely different in structure, purpose, and archetecture). Here's a question... I'd like to get the current time from both the PCM and the MIDI device in order to confirm they've got the clock linked. Is there a meaningful way to test that? Thanks, - Steve ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-27 16:56 ` Steve deRosier @ 2005-04-27 17:22 ` Clemens Ladisch 2005-04-27 20:31 ` Steve deRosier 0 siblings, 1 reply; 13+ messages in thread From: Clemens Ladisch @ 2005-04-27 17:22 UTC (permalink / raw) To: Steve deRosier; +Cc: Alsa-Devel Steve deRosier wrote: > Clemens Ladisch wrote: > > You should check the error code, but otherwise this looks OK. > > Error code for which function? snd_seq_set_queue_timer (it's the only nontrivial function, the others just set parameters for this one) As a rule, every error code should be checked. > Here's a question... I'd like to get the current time from both > the PCM and the MIDI device in order to confirm they've got the > clock linked. Is there a meaningful way to test that? There is no PCM time per se, you have to use the frame count as time. A MIDI queue doesn't have its own "real time" either; whenever you use a "real time" timestamp you end up using the system clock. Only the tick counter is synchronized to the timer interrupt. (And no, this isn't documented anywhere.) And I guess this is your problem -- it should go away if you schedule the MIDI events using ticks instead of real time. The nice thing about using ticks is that you can set them up to be any quantity you want (in this case probably the same as one PCM frame or period). HTH Clemens ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-27 17:22 ` Clemens Ladisch @ 2005-04-27 20:31 ` Steve deRosier 2005-04-28 8:25 ` Clemens Ladisch 0 siblings, 1 reply; 13+ messages in thread From: Steve deRosier @ 2005-04-27 20:31 UTC (permalink / raw) To: Clemens Ladisch; +Cc: Alsa-Devel Clemens Ladisch wrote: > Steve deRosier wrote: > >>Clemens Ladisch wrote: >> >>>You should check the error code, but otherwise this looks OK. >> >>Error code for which function? > > > snd_seq_set_queue_timer (it's the only nontrivial function, the others > just set parameters for this one) > > As a rule, every error code should be checked. Agreed. Must have missed that one; fixed, thanks. >>Here's a question... I'd like to get the current time from both >>the PCM and the MIDI device in order to confirm they've got the >>clock linked. Is there a meaningful way to test that? > > > There is no PCM time per se, you have to use the frame count as time. > > A MIDI queue doesn't have its own "real time" either; whenever you use > a "real time" timestamp you end up using the system clock. Only the > tick counter is synchronized to the timer interrupt. (And no, this > isn't documented anywhere.) > > And I guess this is your problem -- it should go away if you schedule > the MIDI events using ticks instead of real time. > > The nice thing about using ticks is that you can set them up to be any > quantity you want (in this case probably the same as one PCM frame or > period). > Interesting! Thats a real clue for once. Looking back over our other Alsa players, I'm noticing they're all using ticks, not real time scheduling. Forgeting the +4/PERIOD_SIZE hack I've got in there for a moment (I must have a culmative off-by-one error somewhere), this player always seemed sloppy, where as the other player was real crisp. Would I be guessing right that if several real-time scheduled events were supposed to go out, but built up till the tick happened, all of those would be sent out and then more events would buffer till the next tick? Ok, I'm changing to tick-based timing. How do I setup my tick timing? Is the sample code in the docs what I'm looking for?: void set_tempo(snd_seq_t *handle) { snd_seq_queue_tempo_t *tempo; snd_seq_queue_tempo_alloca(&tempo); snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ snd_seq_set_queue_tempo(handle, tempo); } Ideas of the PPQ and BPM I should use to match 1 tick to 1 frame? Thanks, - Steve ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-27 20:31 ` Steve deRosier @ 2005-04-28 8:25 ` Clemens Ladisch 2005-05-02 18:04 ` Steve deRosier 0 siblings, 1 reply; 13+ messages in thread From: Clemens Ladisch @ 2005-04-28 8:25 UTC (permalink / raw) To: Steve deRosier; +Cc: Alsa-Devel Steve deRosier wrote: > Forgeting the +4/PERIOD_SIZE hack I've got in there for a moment > (I must have a culmative off-by-one error somewhere), No, the events are usiong the wrong clock. Real-time scheduling uses the system clock instead of the timer source you've set for the queue. That is, at every timer interrupt, ALSA checks whether the system time has reached the scheduled event time. OTOH, MIDI ticks are calculated using the timer interrupt frequency. > this player always seemed sloppy, where as the other player was > real crisp. Would I be guessing right that if several real-time > scheduled events were supposed to go out, but built up till the > tick happened, all of those would be sent out and then more events > would buffer till the next tick? Yes. Events are sent out at every timer interrupt. This is true for both real-time and tick scheduled events > Clemens Ladisch wrote: > > The nice thing about using ticks is that you can set them up to be any > > quantity you want (in this case probably the same as one PCM frame or > > period). > > Ok, I'm changing to tick-based timing. How do I setup my tick > timing? Is the sample code in the docs what I'm looking for?: Yes. > Ideas of the PPQ and BPM I should use to match 1 tick to 1 frame? I'd use one quarter note per second (tempo = 1000000 microseconds per quarter note) so that the sampling frequency can be used directly as PPQ (ticks per quarter note). HTH Clemens ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-04-28 8:25 ` Clemens Ladisch @ 2005-05-02 18:04 ` Steve deRosier 2005-05-03 8:05 ` Clemens Ladisch 0 siblings, 1 reply; 13+ messages in thread From: Steve deRosier @ 2005-05-02 18:04 UTC (permalink / raw) To: Clemens Ladisch; +Cc: Alsa-Devel [-- Attachment #1: Type: text/plain, Size: 1862 bytes --] Clemens Ladisch wrote: > Steve deRosier wrote: > >>Forgeting the +4/PERIOD_SIZE hack I've got in there for a moment >>(I must have a culmative off-by-one error somewhere), > > > No, the events are usiong the wrong clock. Real-time scheduling uses > the system clock instead of the timer source you've set for the queue. > That is, at every timer interrupt, ALSA checks whether the system time > has reached the scheduled event time. OTOH, MIDI ticks are calculated > using the timer interrupt frequency. > So, even though I tied the MIDI timer source to the pcm timer, if I use real-time events, those events will use the system clock? I figured the MIDI timer would just be used and the time just calculated via whatever the MIDI timer was doing. > >>Ideas of the PPQ and BPM I should use to match 1 tick to 1 frame? > > > I'd use one quarter note per second (tempo = 1000000 microseconds per > quarter note) so that the sampling frequency can be used directly as > PPQ (ticks per quarter note). While waiting for your answer, I decided to keep the tempo the "same" as what I was using, tempo = 500000 so that tempo changes wouldn't need to adjuct the PPQ, so came up with a PPQ = 22050. This should be equivelent as tempo = 1000000; PPQ = 44100 (which I tried with the same results). All is fine in my calculation as near as I can tell (PCM data is standard CD of 44100 samples/sec). BUT... The MIDI plays WAY too slow. I don't get it. I can speed it up clearly by using a larger PPQ or smaller tempo, but I can't seem to do it in any manner that will get my MIDI to line up with my audio. I notice in /proc/asound/card0/pcm0p/sub0/hw_params gives a tick_time of 1000. Would that affect anything since I'm triggering the queue time off the pcm? Including lots of proc data incase there's a clue there I don't know about. Thanks, - Steve [-- Attachment #2: opus_alsa.txt --] [-- Type: text/plain, Size: 8035 bytes --] # cat pcm 00-00: VIA 82C686A/B rev50 : VIA 82C686A/B rev50 : playback 1 : capture 1 # cd card0 # ls codec97#0 id midi0 pcm0c pcm0p via82xx # cd pcm0p # ls info sub0 # cat info card: 0 device: 0 subdevice: 0 stream: PLAYBACK id: VIA 82C686A/B rev50 name: VIA 82C686A/B rev50 subname: subdevice #0 class: 0 subclass: 0 subdevices_count: 1 subdevices_avail: 0 # cd sub0 # ls hw_params info prealloc status sw_params # cat info card: 0 device: 0 subdevice: 0 stream: PLAYBACK id: VIA 82C686A/B rev50 name: VIA 82C686A/B rev50 subname: subdevice #0 class: 0 subclass: 0 subdevices_count: 1 subdevices_avail: 0 # cat hw_params access: RW_INTERLEAVED format: S16_LE subformat: STD channels: 2 rate: 44100 (44100/1) period_size: 2048 buffer_size: 16384 tick_time: 1000 # cat prealloc 64 # cat status state: RUNNING trigger_time: 1115052640.065836000 tstamp : 1115052699.379423000 delay : 15388 avail : 996 avail_max : 8562 ----- hw_ptr : 2616292 appl_ptr : 2631680 # cat sw_params tstamp_mode: NONE period_step: 1 sleep_min: 0 avail_min: 2048 xfer_align: 1 start_threshold: 8192 stop_threshold: 32768 silence_threshold: 0 silence_size: 0 boundary: 1073741824 # cd .. # cd .. # ls codec97#0 id midi0 pcm0c pcm0p via82xx # cd .. # ls Opus7 card0 card1 cards devices pcm rev50 seq timers version # cd card1 # ls id midi0 # cat id Opus7 # cat midi0 uart16550 MIDI #0 Output 0 Tx bytes : 130751 Mode : native Buffer size : 4096 Avail : 4096 Output 1 Tx bytes : 0 Output 2 Tx bytes : 37961 Mode : native Buffer size : 4096 Avail : 4096 Input 0 Rx bytes : 2688 Buffer size : 4096 Avail : 0 Overruns : 0 Input 1 Rx bytes : 0 Buffer size : 4096 Avail : 0 Overruns : 0 Input 2 Rx bytes : 1751 Buffer size : 4096 Avail : 0 Overruns : 0 # cat midi0 uart16550 MIDI #0 Output 0 Tx bytes : 130795 Mode : native Buffer size : 4096 Avail : 4096 Output 1 Tx bytes : 0 Output 2 Tx bytes : 37961 Mode : native Buffer size : 4096 Avail : 4096 Input 0 Rx bytes : 2688 Buffer size : 4096 Avail : 0 Overruns : 0 Input 1 Rx bytes : 0 Buffer size : 4096 Avail : 0 Overruns : 0 Input 2 Rx bytes : 1751 Buffer size : 4096 Avail : 0 Overruns : 0 # cat midi0 uart16550 MIDI #0 Output 0 Tx bytes : 131098 Mode : native Buffer size : 4096 Avail : 4096 Output 1 Tx bytes : 0 Output 2 Tx bytes : 37961 Mode : native Buffer size : 4096 Avail : 4096 Input 0 Rx bytes : 2688 Buffer size : 4096 Avail : 0 Overruns : 0 Input 1 Rx bytes : 0 Buffer size : 4096 Avail : 0 Overruns : 0 Input 2 Rx bytes : 1751 Buffer size : 4096 Avail : 0 Overruns : 0 # ls id midi0 # cd .. # ls Opus7 card0 card1 cards devices pcm rev50 seq timers version # ls -l lrwxrwxrwx 1 root root 5 May 2 09:53 Opus7 -> card1 dr-xr-xr-x 5 root root 0 May 2 09:53 card0 dr-xr-xr-x 2 root root 0 May 2 09:53 card1 -r--r--r-- 1 root root 0 May 2 09:53 cards -r--r--r-- 1 root root 0 May 2 09:53 devices -r--r--r-- 1 root root 0 May 2 09:53 pcm lrwxrwxrwx 1 root root 5 May 2 09:53 rev50 -> card0 dr-xr-xr-x 2 root root 0 May 2 09:53 seq -r--r--r-- 1 root root 0 May 2 09:53 timers -r--r--r-- 1 root root 0 May 2 09:53 version # cd seq # ls clients drivers queues timer # cat timer Timer for queue 0 : RTC timer Period time : 0.000976562 Skew : 65536 / 65536 Timer for queue 1 : RTC timer Period time : 0.000976562 Skew : 65536 / 65536 Timer for queue 2 : RTC timer Period time : 0.000976562 Skew : 65536 / 65536 Timer for queue 3 : RTC timer Period time : 0.000976562 Skew : 65536 / 65536 Timer for queue 4 : PCM playback 0-0-0 Period time : 0.046545454 Skew : 65536 / 65536 # cat queues queue 0: [Queue-0] owned by client : 128 lock status : Locked queued time events : 0 queued tick events : 0 timer state : Running timer PPQ : 480 current tempo : 500000 current BPM : 120 current time : 319196.794578970 s current tick : 306429118 queue 1: [Queue-1] owned by client : 129 lock status : Locked queued time events : 0 queued tick events : 0 timer state : Running timer PPQ : 480 current tempo : 500000 current BPM : 120 current time : 319196.793602408 s current tick : 306429117 queue 2: [Queue-2] owned by client : 130 lock status : Locked queued time events : 0 queued tick events : 0 timer state : Running timer PPQ : 480 current tempo : 500000 current BPM : 120 current time : 319196.793602408 s current tick : 306429117 queue 3: [Queue-3] owned by client : 131 lock status : Locked queued time events : 0 queued tick events : 0 timer state : Running timer PPQ : 480 current tempo : 500000 current BPM : 120 current time : 319196.792625846 s current tick : 306429117 queue 4: [Queue-4] owned by client : 132 lock status : Locked queued time events : 0 queued tick events : 14 timer state : Running timer PPQ : 44100 current tempo : 1000000 current BPM : 60 current time : 2.141090884 s current tick : 94425 # ls clients drivers queues timer # cat drivers snd-seq-midi,loaded,2 # cat clients Client info cur clients : 9 peak clients : 12 max clients : 192 Client 0 : "System" [Kernel] Port 0 : "Timer" (Rwe-) Port 1 : "Announce" (R-e-) Client 62 : "Midi Through" [Kernel] Port 0 : "Midi Through Port-0" (RWe-) Client 64 : "VIA 82C686A/B rev50 MIDI - Rawmidi 0" [Kernel] Port 0 : "VIA 82C686A/B rev50 MIDI" (RWeX) Client 72 : "uart16550 MIDI #0 - Rawmidi 1" [Kernel] Port 0 : "uart16550 MIDI #0-0" (RWeX) Connecting To: 129:0[t:1] Connected From: 131:0 Port 1 : "uart16550 MIDI #0-1" (RWeX) Connecting To: 128:0[r:0] Port 2 : "uart16550 MIDI #0-2" (RWeX) Connecting To: 129:0 Connected From: 130:0 Client 128 : "Client-128" [User] Port 0 : "In" (-We-) Connected From: 72:1[r:0], 132:0 Output pool : Pool size : 500 Cells in use : 0 Peak cells in use : 0 Alloc success : 0 Alloc failures : 0 Input pool : Pool size : 200 Cells in use : 0 Peak cells in use : 4 Alloc success : 1380 Alloc failures : 0 Client 129 : "Client-129" [User] Port 0 : "In" (-We-) Connected From: 72:0[t:1], 72:2 Output pool : Pool size : 500 Cells in use : 0 Peak cells in use : 0 Alloc success : 0 Alloc failures : 0 Input pool : Pool size : 200 Cells in use : 0 Peak cells in use : 2 Alloc success : 23 Alloc failures : 0 Client 130 : "Client-130" [User] Port 0 : "Out" (R-e-) Connecting To: 72:2 Output pool : Pool size : 500 Cells in use : 0 Peak cells in use : 32 Alloc success : 64 Alloc failures : 0 Client 131 : "Client-131" [User] Port 0 : "Out" (R-e-) Connecting To: 72:0 Output pool : Pool size : 500 Cells in use : 0 Peak cells in use : 4 Alloc success : 1373 Alloc failures : 0 Client 132 : "Client-132" [User] Port 0 : "Out" (R-e-) Connecting To: 128:0 Output pool : Pool size : 500 Cells in use : 66 Peak cells in use : 66 Alloc success : 128 Alloc failures : 0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to tell how many frames gone to PCM 2005-05-02 18:04 ` Steve deRosier @ 2005-05-03 8:05 ` Clemens Ladisch 0 siblings, 0 replies; 13+ messages in thread From: Clemens Ladisch @ 2005-05-03 8:05 UTC (permalink / raw) To: Steve deRosier; +Cc: Alsa-Devel Steve deRosier wrote: > So, even though I tied the MIDI timer source to the pcm timer, if > I use real-time events, those events will use the system clock? > I figured the MIDI timer would just be used and the time just > calculated via whatever the MIDI timer was doing. Only the 'tick' time is calculated based on timer ticks. The 'real' time uses the system clock. > I notice in /proc/asound/card0/pcm0p/sub0/hw_params gives a > tick_time of 1000. Would that affect anything since I'm > triggering the queue time off the pcm? No, this is not related to the PCM timer. Interrupts happen at every period boundary ... > # cat hw_params > rate: 44100 (44100/1) > period_size: 2048 ... at about 21.5 Hz (44100/2048). You might want to use smaller periods to reduce the MIDI jitter. > The MIDI plays WAY too slow. I don't get it. I can speed it up > clearly by using a larger PPQ or smaller tempo, but I can't seem > to do it in any manner that will get my MIDI to line up with my > audio. > > queue 4: [Queue-4] > timer PPQ : 44100 > current tempo : 1000000 > current BPM : 60 > current time : 2.141090884 s > current tick : 94425 If we assume that the system clock and the PCM clocks are almost in sync, the theoretical tick time should be 2.141090884 * 44100 = 94422. The value above looks OK. There will be some (more or less constant) delay between the MIDI events and the corresponding PCM samples, depending of the delays in both devices, but I cannot see how MIDI events could have the wrong tempo. Regards, Clemens ------------------------------------------------------- This SF.Net email is sponsored by: NEC IT Guy Games. Get your fingers limbered up and give it your best shot. 4 great events, 4 opportunities to win big! Highest score wins.NEC IT Guy Games. Play to win an NEC 61 plasma display. Visit http://www.necitguy.com/?r=20 ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <ad2655cb0504270201165f9859@mail.gmail.com>]
* Re: How to tell how many frames gone to PCM [not found] ` <ad2655cb0504270201165f9859@mail.gmail.com> @ 2005-04-27 16:43 ` Steve deRosier 0 siblings, 0 replies; 13+ messages in thread From: Steve deRosier @ 2005-04-27 16:43 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Alsa-Devel > > You might want the "snd_pcm_delay()" function. > This will return a count of frames in the buffer that have not yet > reached the ADC. > E.g. > snd_pcm_write() <- Write 1024 frames to the buffer. > snd_pcm_delay() <- If this returns 500, it means that 525 frames have > already been played out of the speakers. > > The snd_pcm_delay() function was introduced into alsa to help > audio/video application do lip sync. We could therefore calculate that > if we write a frame to the buffer now, it will reach the speakers in > exactly snd_pcm_delay() frames time. > > Does this help you? I've got it implemented in my system, but actually it doesn't solve the problem (and actually exasperates it). See, we calculate the midi times based on the "sample" time that the midi msg arrives at. So, for example: Our AlsaSender task receives a right and left audio sample (the two together I suppose is called a frame), and the last MIDI byte of a message. It keeps a counter of how many audio frames are received at this point. It sends the audio frame to alsa (actually the CDSP function buffers up PERIOD_SIZE number of samples before it does the ..._writei() in order to not cause excessive function call overhead). It calculates the MIDI timestamp based on the number of samples it has sent off: snd_seq_real_time_t time; unsigned long long int iTime = (((mPlayedSampleCount*10*P_MILLION)/441); time.tv_sec = iTime/P_BILLION; time.tv_nsec = iTime%P_BILLION; snd_seq_ev_set_source(&event, mPort); snd_seq_ev_set_subs(&event); snd_seq_ev_schedule_real(&event, mQueue, 0, &time); snd_seq_event_output(hSeq, &event); snd_seq_drain_output(hSeq); Our audio source is CD, so 44100 is the correct speed for the calculation (non-significant zeros canceled off in the calculation). Anything obviously wrong with my approach? Thanks, - Steve ------------------------------------------------------- SF.Net email is sponsored by: Tell us your software development plans! Take this survey and enter to win a one-year sub to SourceForge.net Plus IDC's 2005 look-ahead and a copy of this survey Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2005-05-03 8:05 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-26 20:18 How to tell how many frames gone to PCM Steve deRosier
2005-04-26 20:16 ` Lee Revell
2005-04-26 21:07 ` Steve deRosier
2005-04-26 21:17 ` Lee Revell
2005-04-26 21:45 ` Steve deRosier
2005-04-27 14:36 ` Clemens Ladisch
2005-04-27 16:56 ` Steve deRosier
2005-04-27 17:22 ` Clemens Ladisch
2005-04-27 20:31 ` Steve deRosier
2005-04-28 8:25 ` Clemens Ladisch
2005-05-02 18:04 ` Steve deRosier
2005-05-03 8:05 ` Clemens Ladisch
[not found] ` <ad2655cb0504270201165f9859@mail.gmail.com>
2005-04-27 16:43 ` Steve deRosier
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.