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

Revision 399, 7.4 kB (checked in by pieterpalmers, 16 years ago)

- code cleanup
- introduce sync delay concept to fix latency issues due to intermediate ISO buffering
- made SytMonitor? use cycletimer.h functions

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 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
29 #include "libutil/Atomic.h"
30
31 #include "StreamProcessor.h"
32 #include "StreamProcessorManager.h"
33 #include "cycletimer.h"
34
35 #include <assert.h>
36
37 namespace FreebobStreaming {
38
39 IMPL_DEBUG_MODULE( StreamProcessor, StreamProcessor, DEBUG_LEVEL_VERBOSE );
40 IMPL_DEBUG_MODULE( ReceiveStreamProcessor, ReceiveStreamProcessor, DEBUG_LEVEL_VERBOSE );
41 IMPL_DEBUG_MODULE( TransmitStreamProcessor, TransmitStreamProcessor, DEBUG_LEVEL_VERBOSE );
42
43 StreamProcessor::StreamProcessor(enum IsoStream::EStreamType type, int port, int framerate)
44         : IsoStream(type, port)
45         , m_nb_buffers(0)
46         , m_period(0)
47         , m_xruns(0)
48         , m_framerate(framerate)
49         , m_manager(NULL)
50         , m_running(false)
51         , m_disabled(true)
52         , m_is_disabled(true)
53         , m_cycle_to_enable_at(0)
54         , m_SyncSource(NULL)
55         , m_ticks_per_frame(0)
56         , m_last_cycle(0)
57         , m_sync_delay(0)
58 {
59     // create the timestamped buffer and register ourselves as its client
60     m_data_buffer=new FreebobUtil::TimestampedBuffer(this);
61
62 }
63
64 StreamProcessor::~StreamProcessor() {
65     if (m_data_buffer) delete m_data_buffer;
66 }
67
68 void StreamProcessor::dumpInfo()
69 {
70     debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor information\n");
71     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Iso stream info:\n");
72    
73     IsoStream::dumpInfo();
74     debugOutputShort( DEBUG_LEVEL_NORMAL, "  StreamProcessor info:\n");
75     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011u\n",m_handler->getCycleTimerTicks());
76     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xruns                 : %d\n", m_xruns);
77     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Running               : %d\n", m_running);
78     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Enabled               : %s\n", m_disabled ? "No" : "Yes");
79     debugOutputShort( DEBUG_LEVEL_NORMAL, "   enable status        : %s\n", m_is_disabled ? "No" : "Yes");
80    
81     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Device framerate      : Sync: %f, Buffer %f\n",
82         24576000.0*m_SyncSource->m_data_buffer->getRate(),
83         24576000.0*m_data_buffer->getRate()
84         );
85    
86     m_data_buffer->dumpInfo();
87    
88 //     m_PeriodStat.dumpInfo();
89 //     m_PacketStat.dumpInfo();
90 //     m_WakeupStat.dumpInfo();
91
92 }
93
94 bool StreamProcessor::init()
95 {
96     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n");
97    
98     m_data_buffer->init();
99    
100     return IsoStream::init();
101 }
102
103 /**
104  * Resets the frame counter, the xrun counter, the ports and the iso stream.
105  * @return true if reset succeeded
106  */
107 bool StreamProcessor::reset() {
108
109     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
110
111     // reset the event buffer, discard all content
112     if (!m_data_buffer->reset()) {
113         debugFatal("Could not reset data buffer\n");
114         return false;
115     }
116    
117     resetXrunCounter();
118
119     // loop over the ports to reset them
120     if (!PortManager::resetPorts()) {
121         debugFatal("Could not reset ports\n");
122         return false;
123     }
124
125     // reset the iso stream
126     if (!IsoStream::reset()) {
127         debugFatal("Could not reset isostream\n");
128         return false;
129     }
130     return true;
131        
132 }
133
134 bool StreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
135     debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForEnable for (%p)\n",this);
136     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011u\n",m_handler->getCycleTimerTicks());
137     debugOutput(DEBUG_LEVEL_VERBOSE,"  Enable at             : %011u\n",time_to_enable_at);
138     m_data_buffer->dumpInfo();
139     return true;
140 }
141
142 bool StreamProcessor::prepareForDisable() {
143     debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForDisable for (%p)\n",this);
144     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011u\n",m_handler->getCycleTimerTicks());
145     m_data_buffer->dumpInfo();
146     return true;
147 }
148
149 bool StreamProcessor::prepare() {
150
151         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
152        
153         // init the ports
154        
155         if(!m_manager) {
156                 debugFatal("Not attached to a manager!\n");
157                 return -1;
158         }
159
160         m_nb_buffers=m_manager->getNbBuffers();
161         debugOutput( DEBUG_LEVEL_VERBOSE, "Setting m_nb_buffers  : %d\n", m_nb_buffers);
162
163         m_period=m_manager->getPeriodSize();
164         debugOutput( DEBUG_LEVEL_VERBOSE, "Setting m_period      : %d\n", m_period);
165
166         // loop over the ports to reset them
167         PortManager::preparePorts();
168
169         // reset the iso stream
170         IsoStream::prepare();
171        
172         return true;
173
174 }
175
176 int StreamProcessor::getBufferFill() {
177 //     return m_data_buffer->getFrameCounter();
178     return m_data_buffer->getBufferFill();
179 }
180
181 uint64_t StreamProcessor::getTimeNow() {
182     return m_handler->getCycleTimerTicks();
183 }
184
185
186 bool StreamProcessor::isRunning() {
187         return m_running;
188 }
189
190 bool StreamProcessor::enable(uint64_t time_to_enable_at)  {
191     // FIXME: time_to_enable_at will be in 'time' not cycles
192     m_cycle_to_enable_at=time_to_enable_at;
193    
194     if(!m_running) {
195             debugWarning("The StreamProcessor is not running yet, enable() might not be a good idea.\n");
196     }
197
198 #ifdef DEBUG
199     uint64_t now_cycles=TICKS_TO_CYCLES(m_handler->getCycleTimerTicks());
200     const int64_t max=(int64_t)(TICKS_PER_SECOND/2);
201    
202     int64_t diff=(int64_t)m_cycle_to_enable_at-(int64_t)now_cycles;
203    
204     if (diff > max) {
205         diff-=TICKS_PER_SECOND;
206     } else if (diff < -max) {
207         diff+=TICKS_PER_SECOND;
208     }
209    
210     if (diff<0) {
211         debugWarning("Request to enable streamprocessor %lld cycles ago (now=%llu, cy=%llu).\n",
212             diff,now_cycles,time_to_enable_at);
213     }
214 #endif
215
216     m_disabled=false;
217    
218     return true;
219 }
220
221 bool StreamProcessor::disable()  {
222    
223     m_disabled=true;
224
225     return true;
226
227 }
228
229 bool StreamProcessor::setSyncSource(StreamProcessor *s) {
230     m_SyncSource=s;
231     return true;
232 }
233
234 /**
235  * Resets the xrun counter, in a atomic way. This
236  * is thread safe.
237  */
238 void StreamProcessor::resetXrunCounter() {
239         ZERO_ATOMIC((SInt32 *)&m_xruns);
240 }
241
242 void StreamProcessor::setVerboseLevel(int l) {
243         setDebugLevel(l);
244         IsoStream::setVerboseLevel(l);
245         PortManager::setVerboseLevel(l);
246
247 }
248
249 ReceiveStreamProcessor::ReceiveStreamProcessor(int port, int framerate)
250         : StreamProcessor(IsoStream::EST_Receive, port, framerate) {
251
252 }
253
254 ReceiveStreamProcessor::~ReceiveStreamProcessor() {
255
256 }
257
258 void ReceiveStreamProcessor::setVerboseLevel(int l) {
259         setDebugLevel(l);
260         StreamProcessor::setVerboseLevel(l);
261
262 }
263
264
265 TransmitStreamProcessor::TransmitStreamProcessor( int port, int framerate)
266         : StreamProcessor(IsoStream::EST_Transmit, port, framerate) {
267
268 }
269
270 TransmitStreamProcessor::~TransmitStreamProcessor() {
271
272 }
273
274 void TransmitStreamProcessor::setVerboseLevel(int l) {
275         setDebugLevel(l);
276         StreamProcessor::setVerboseLevel(l);
277
278 }
279
280 }
Note: See TracBrowser for help on using the browser.