root/branches/streaming-rework/src/libstreaming/AmdtpSlaveStreamProcessor.cpp

Revision 435, 18.4 kB (checked in by pieterpalmers, 15 years ago)

src/devicemanager:
- start OSC server for the device manager

src/devicemanager,
src/iavdevice,
src/libieee1394/configrom:
- inherit from OscNode? to become Osc'able

src/bounce,
src/libstreaming/AmdtpStreamProcessor,
src/libstreaming/AmdtpSlaveStreamProcessor:
- fixed bounce device implementation, now working

src/bebob:
- fixed midi bug

General:
- removed 'intermediate XML'
- removed obsolete tests
- removed obsolete files
- removed obsolete API calls

Line 
1 /* $Id$ */
2
3 /*
4  *   FreeBob Streaming API
5  *   FreeBob = Firewire (pro-)audio for linux
6  *
7  *   http://freebob.sf.net
8  *
9  *   Copyright (C) 2005,2006,2007 Pieter Palmers <pieterpalmers@users.sourceforge.net>
10  *
11  *   This program is free software {} you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation {} either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY {} without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with this program {} if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  *
26  *
27  */
28 #include "AmdtpSlaveStreamProcessor.h"
29
30 #include "cycletimer.h"
31
32 #include <netinet/in.h>
33 #include <assert.h>
34
35 // in ticks
36 #define TRANSMIT_TRANSFER_DELAY 9000U
37 // the number of cycles to send a packet in advance of it's timestamp
38 #define TRANSMIT_ADVANCE_CYCLES 1U
39
40 namespace Streaming {
41
42 /* transmit */
43 AmdtpSlaveTransmitStreamProcessor::AmdtpSlaveTransmitStreamProcessor(int port, int framerate, int dimension)
44         : AmdtpTransmitStreamProcessor(port, framerate, dimension)
45 {
46
47 }
48
49 AmdtpSlaveTransmitStreamProcessor::~AmdtpSlaveTransmitStreamProcessor() {
50
51 }
52
53 enum raw1394_iso_disposition
54 AmdtpSlaveTransmitStreamProcessor::getPacket(unsigned char *data, unsigned int *length,
55                       unsigned char *tag, unsigned char *sy,
56                       int cycle, unsigned int dropped, unsigned int max_length) {
57    
58     struct iec61883_packet *packet = (struct iec61883_packet *) data;
59     if (cycle<0) return RAW1394_ISO_OK;
60    
61     m_last_cycle=cycle;
62    
63     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Xmit handler for cycle %d, (running=%d, enabled=%d,%d)\n",
64         cycle, m_running, m_disabled, m_is_disabled);
65    
66 #ifdef DEBUG
67     if(dropped>0) {
68         debugWarning("Dropped %d packets on cycle %d\n",dropped, cycle);
69     }
70 #endif
71    
72     // calculate & preset common values
73    
74     /* Our node ID can change after a bus reset, so it is best to fetch
75      * our node ID for each packet. */
76     packet->sid = getNodeId() & 0x3f;
77
78     packet->dbs = m_dimension;
79     packet->fn = 0;
80     packet->qpc = 0;
81     packet->sph = 0;
82     packet->reserved = 0;
83     packet->dbc = m_dbc;
84     packet->eoh1 = 2;
85     packet->fmt = IEC61883_FMT_AMDTP;
86    
87     *tag = IEC61883_TAG_WITH_CIP;
88     *sy = 0;
89    
90     // determine if we want to send a packet or not
91     // note that we can't use getCycleTimer directly here,
92     // because packets are queued in advance. This means that
93     // we the packet we are constructing will be sent out
94     // on 'cycle', not 'now'.
95     unsigned int ctr=m_handler->getCycleTimer();
96     int now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr);
97    
98     // the difference between the cycle this
99     // packet is intended for and 'now'
100     int cycle_diff = diffCycles(cycle, now_cycles);
101    
102 #ifdef DEBUG
103     if(m_running && (cycle_diff < 0)) {
104         debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n",
105             cycle, now_cycles);
106     }
107 #endif
108
109     // as long as the cycle parameter is not in sync with
110     // the current time, the stream is considered not
111     // to be 'running'
112     // NOTE: this works only at startup
113     if (!m_running && cycle_diff >= 0 && cycle >= 0) {
114         debugOutput(DEBUG_LEVEL_VERBOSE, "Xmit StreamProcessor %p started running at cycle %d\n",this, cycle);
115         m_running=true;
116        
117         uint32_t ticks_to_advance = TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES;
118        
119         // if cycle lies cycle_diff cycles in the future, the
120         // timestamp for it corresponds to
121         // now+cycle_diff * TICKS_PER_CYCLE
122         ticks_to_advance += cycle_diff * TICKS_PER_CYCLE;
123    
124         // determine the 'now' time in ticks
125         uint32_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr);
126        
127         cycle_timer = addTicks(cycle_timer, ticks_to_advance);
128         m_data_buffer->setBufferHeadTimestamp(cycle_timer);
129     }
130    
131     uint64_t ts_head, fc;
132     if (!m_disabled && m_is_disabled) { // this means that we are trying to enable
133         // check if we are on or past the enable point
134         int cycles_past_enable=diffCycles(cycle, m_cycle_to_enable_at);
135        
136         if (cycles_past_enable >= 0) {
137             m_is_disabled=false;
138            
139             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %u\n", this, cycle);
140            
141             // initialize the buffer head & tail
142             m_SyncSource->m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe
143            
144             // the number of cycles the sync source lags (> 0)
145             // or leads (< 0)
146             int sync_lag_cycles=diffCycles(cycle, m_SyncSource->getLastCycle());
147            
148             // account for the cycle lag between sync SP and this SP
149             // the last update of the sync source's timestamps was sync_lag_cycles
150             // cycles before the cycle we are calculating the timestamp for.
151             // if we were to use one-frame buffers, you would expect the
152             // frame that is sent on cycle CT to have a timestamp T1.
153             // ts_head however is for cycle CT-sync_lag_cycles, and lies
154             // therefore sync_lag_cycles * TICKS_PER_CYCLE earlier than
155             // T1.
156             ts_head = addTicks(ts_head, (sync_lag_cycles) * TICKS_PER_CYCLE);
157            
158             ts_head = substractTicks(ts_head, TICKS_PER_CYCLE);
159            
160             // account for the number of cycles we are too late to enable
161             ts_head = addTicks(ts_head, cycles_past_enable * TICKS_PER_CYCLE);
162            
163             // account for one extra packet of frames
164             ts_head = substractTicks(ts_head,
165                         (uint32_t)((float)m_syt_interval * m_SyncSource->m_data_buffer->getRate()));
166
167             m_data_buffer->setBufferHeadTimestamp(ts_head);
168
169             #ifdef DEBUG
170             if ((unsigned int)m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()) {
171                 debugWarning("m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()\n");
172             }
173             #endif
174             debugOutput(DEBUG_LEVEL_VERBOSE,"XMIT TS SET: TS=%10llu, LAG=%03d, FC=%4d\n",
175                             ts_head, sync_lag_cycles, m_data_buffer->getFrameCounter());
176         } else {
177             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
178                         "will enable StreamProcessor %p at %u, now is %d\n",
179                         this, m_cycle_to_enable_at, cycle);
180         }
181     } else if (m_disabled && !m_is_disabled) {
182         // trying to disable
183         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n",
184                     this, cycle);
185         m_is_disabled=true;
186     }
187    
188     // the base timestamp is the one of the next sample in the buffer
189     m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe
190
191     // we send a packet some cycles in advance, to avoid the
192     // following situation:
193     // suppose we are only a few ticks away from
194     // the moment to send this packet. therefore we decide
195     // not to send the packet, but send it in the next cycle.
196     // This means that the next time point will be 3072 ticks
197     // later, making that the timestamp will be expired when the
198     // packet is sent, unless TRANSFER_DELAY > 3072.
199     // this means that we need at least one cycle of extra buffering.
200     uint32_t ticks_to_advance = TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES;
201    
202     // if cycle lies cycle_diff cycles in the future, we should
203     // queue this packet cycle_diff * TICKS_PER_CYCLE earlier than
204     // we would if it were to be sent immediately.
205     ticks_to_advance += cycle_diff * TICKS_PER_CYCLE;
206
207     // determine the 'now' time in ticks
208     uint32_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr);
209    
210     cycle_timer = addTicks(cycle_timer, ticks_to_advance);
211    
212     // time until the packet is to be sent (if > 0: send packet)
213     int32_t until_next=diffTicks(ts_head, cycle_timer);
214
215     // if until_next < 0 we should send a filled packet
216     // otherwise we should send a NO-DATA packet
217     if((until_next<0) && (m_running)) {
218         // add the transmit transfer delay to construct the playout time (=SYT timestamp)
219         uint32_t ts_packet=addTicks(ts_head, TRANSMIT_TRANSFER_DELAY);
220    
221         // if we are disabled, send a silent packet
222         // and advance the buffer head timestamp
223         if(m_is_disabled) {
224            
225             transmitSilenceBlock((char *)(data+8), m_syt_interval, 0);
226             m_dbc += fillDataPacketHeader(packet, length, ts_packet);
227            
228             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT SYNC: CY=%04u TSH=%011llu TSP=%011lu\n",
229                 cycle, ts_head, ts_packet);
230
231             // update the base timestamp
232             uint32_t ts_step=(uint32_t)((float)(m_syt_interval)
233                              *m_SyncSource->m_data_buffer->getRate());
234            
235             // the next buffer head timestamp
236             ts_head=addTicks(ts_head,ts_step);
237             m_data_buffer->setBufferHeadTimestamp(ts_head);
238            
239             // defer to make sure we get to be enabled asap
240             return RAW1394_ISO_DEFER;
241            
242         } else { // enabled & packet due, read from the buffer
243             if (m_data_buffer->readFrames(m_syt_interval, (char *)(data + 8))) {
244                 m_dbc += fillDataPacketHeader(packet, length, ts_packet);
245                
246                 // process all ports that should be handled on a per-packet base
247                 // this is MIDI for AMDTP (due to the need of DBC)
248                 if (!encodePacketPorts((quadlet_t *)(data+8), m_syt_interval, packet->dbc)) {
249                     debugWarning("Problem encoding Packet Ports\n");
250                 }
251                
252                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: CY=%04u TSH=%011llu TSP=%011lu\n",
253                     cycle, ts_head, ts_packet);
254                
255                 return RAW1394_ISO_OK;
256                
257             } else if (now_cycles<cycle) {
258                 // we can still postpone the queueing of the packets
259                 // because the ISO transmit packet buffer is not empty yet
260                 return RAW1394_ISO_AGAIN;
261                
262             } else { // there is no more data in the ringbuffer
263                 // compose a silent packet, we should always
264                 // send a valid packet
265                 transmitSilenceBlock((char *)(data+8), m_syt_interval, 0);
266                 m_dbc += fillDataPacketHeader(packet, length, ts_packet);
267            
268                 debugWarning("Transmit buffer underrun (now %d, queue %d, target %d)\n",
269                         now_cycles, cycle, TICKS_TO_CYCLES(ts_packet));
270                 // signal underrun
271                 m_xruns++;
272                 // disable the processing, will be re-enabled when
273                 // the xrun is handled
274                 m_disabled=true;
275                 m_is_disabled=true;
276                
277                 return RAW1394_ISO_DEFER;
278             }
279         }
280        
281     } else { // no packet due, send no-data packet
282         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT NONE: CY=%04u TSH=%011llu\n",
283                 cycle, ts_head);
284                
285         m_dbc += fillNoDataPacketHeader(packet, length);
286         return RAW1394_ISO_DEFER;
287     }
288    
289     // we shouldn't get here
290     return RAW1394_ISO_ERROR;
291
292 }
293
294 /* --------------------- RECEIVE ----------------------- */
295
296 AmdtpSlaveReceiveStreamProcessor::AmdtpSlaveReceiveStreamProcessor(int port, int framerate, int dimension)
297     : AmdtpReceiveStreamProcessor(port, framerate, dimension)
298 {}
299
300 AmdtpSlaveReceiveStreamProcessor::~AmdtpSlaveReceiveStreamProcessor()
301 {}
302
303 enum raw1394_iso_disposition
304 AmdtpSlaveReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
305                   unsigned char channel, unsigned char tag, unsigned char sy,
306                   unsigned int cycle, unsigned int dropped) {
307    
308     enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
309     m_last_cycle=cycle;
310    
311     struct iec61883_packet *packet = (struct iec61883_packet *) data;
312     assert(packet);
313
314 #ifdef DEBUG
315     if(dropped>0) {
316         debugWarning("Dropped %d packets on cycle %d\n",dropped, cycle);
317     }
318
319     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"ch%2u: CY=%4u, SYT=%08X (%4ucy + %04uticks) (running=%d, disabled=%d,%d)\n",
320         channel, cycle,ntohs(packet->syt), 
321         CYCLE_TIMER_GET_CYCLES(ntohs(packet->syt)), CYCLE_TIMER_GET_OFFSET(ntohs(packet->syt)),
322         m_running,m_disabled,m_is_disabled);
323
324     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
325         "RCV: CH = %d, FDF = %X. SYT = %6d, DBS = %3d, DBC = %3d, FMT = %3d, LEN = %4d\n",
326         channel, packet->fdf,
327         packet->syt,
328         packet->dbs,
329         packet->dbc,
330         packet->fmt,
331         length);
332
333 #endif
334     // check our enable status
335     if (!m_disabled && m_is_disabled) { // this means that we are trying to enable
336         // check if we are on or past the enable point
337         int cycles_past_enable=diffCycles(cycle, m_cycle_to_enable_at);
338        
339         if (cycles_past_enable >= 0) {
340             m_is_disabled=false;
341             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %d (SYT=%04X)\n",
342                 this, cycle, ntohs(packet->syt));
343             // the previous timestamp is the one we need to start with
344             // because we're going to update the buffer again this loop
345             // using writeframes
346             m_data_buffer->setBufferTailTimestamp(m_last_timestamp);
347
348         } else {
349             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
350                 "will enable StreamProcessor %p at %u, now is %d\n",
351                     this, m_cycle_to_enable_at, cycle);
352         }
353     } else if (m_disabled && !m_is_disabled) {
354         // trying to disable
355         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n", this, cycle);
356         m_is_disabled=true;
357     }
358
359     // check if this is a valid packet
360     if((packet->syt != 0xFFFF)
361        && (packet->fdf != 0xFF)
362        && (packet->fmt == 0x10)
363        && (packet->dbs>0)
364        && (length>=2*sizeof(quadlet_t))) {
365        
366         unsigned int nevents=((length / sizeof (quadlet_t)) - 2)/packet->dbs;
367
368         //=> store the previous timestamp
369         m_last_timestamp2=m_last_timestamp;
370
371         //=> convert the SYT to a full timestamp in ticks
372         m_last_timestamp=sytRecvToFullTicks((uint32_t)ntohs(packet->syt),
373                                         cycle, m_handler->getCycleTimer());
374
375         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n",
376                 cycle, m_last_timestamp);
377        
378         // we have to keep in mind that there are also
379         // some packets buffered by the ISO layer,
380         // at most x=m_handler->getWakeupInterval()
381         // these contain at most x*syt_interval
382         // frames, meaning that we might receive
383         // this packet x*syt_interval*ticks_per_frame
384         // later than expected (the real receive time)
385         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"STMP: %lluticks | buff=%d, syt_interval=%d, tpf=%f\n",
386             m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,m_ticks_per_frame);
387        
388         //=> signal that we're running (if we are)
389         if(!m_running && nevents && m_last_timestamp2 && m_last_timestamp) {
390             debugOutput(DEBUG_LEVEL_VERBOSE,"Receive StreamProcessor %p started running at %d\n", this, cycle);
391             m_running=true;
392         }
393
394         //=> don't process the stream samples when it is not enabled.
395         if(m_is_disabled) {
396
397             // we keep track of the timestamp here
398             // this makes sure that we will have a somewhat accurate
399             // estimate as to when a period might be ready. i.e. it will not
400             // be ready earlier than this timestamp + period time
401            
402             // the next (possible) sample is not this one, but lies
403             // SYT_INTERVAL * rate later
404             uint64_t ts=addTicks(m_last_timestamp,
405                                  (uint64_t)((float)m_syt_interval * m_ticks_per_frame));
406
407             // set the timestamp as if there will be a sample put into
408             // the buffer by the next packet.
409             m_data_buffer->setBufferTailTimestamp(ts);
410            
411             return RAW1394_ISO_DEFER;
412         }
413        
414         #ifdef DEBUG_OFF
415         if((cycle % 1000) == 0)
416         {
417             uint32_t syt = (uint32_t)ntohs(packet->syt);
418             uint32_t now=m_handler->getCycleTimer();
419             uint32_t now_ticks=CYCLE_TIMER_TO_TICKS(now);
420            
421             uint32_t test_ts=sytRecvToFullTicks(syt, cycle, now);
422
423             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: SYT=%08X,            CY=%02d OFF=%04d\n",
424                 cycle, syt, CYCLE_TIMER_GET_CYCLES(syt), CYCLE_TIMER_GET_OFFSET(syt)
425                 );
426             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: NOW=%011lu, SEC=%03u CY=%02u OFF=%04u\n",
427                 cycle, now_ticks, CYCLE_TIMER_GET_SECS(now), CYCLE_TIMER_GET_CYCLES(now), CYCLE_TIMER_GET_OFFSET(now)
428                 );
429             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: TSS=%011lu, SEC=%03u CY=%02u OFF=%04u\n",
430                 cycle, test_ts, TICKS_TO_SECS(test_ts), TICKS_TO_CYCLES(test_ts), TICKS_TO_OFFSET(test_ts)
431                 );
432         }
433         #endif
434        
435         //=> process the packet
436         // add the data payload to the ringbuffer
437         if(m_data_buffer->writeFrames(nevents, (char *)(data+8), m_last_timestamp)) {
438             retval=RAW1394_ISO_OK;
439            
440             // process all ports that should be handled on a per-packet base
441             // this is MIDI for AMDTP (due to the need of DBC)
442             if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
443                 debugWarning("Problem decoding Packet Ports\n");
444                 retval=RAW1394_ISO_DEFER;
445             }
446            
447         } else {
448        
449             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
450                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount());
451            
452             m_xruns++;
453            
454             // disable the processing, will be re-enabled when
455             // the xrun is handled
456             m_disabled=true;
457             m_is_disabled=true;
458
459             retval=RAW1394_ISO_DEFER;
460         }
461     }
462
463     return retval;
464 }
465
466 } // end of namespace Streaming
Note: See TracBrowser for help on using the browser.