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

Revision 397, 8.5 kB (checked in by pieterpalmers, 16 years ago)

- make timestampedbuffer use floats instead of doubles
- change iso receive back to the efficient case

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 {
57     // create the timestamped buffer and register ourselves as its client
58     m_data_buffer=new FreebobUtil::TimestampedBuffer(this);
59
60 }
61
62 StreamProcessor::~StreamProcessor() {
63     if (m_data_buffer) delete m_data_buffer;
64 }
65
66 void StreamProcessor::dumpInfo()
67 {
68     debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor information\n");
69     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Iso stream info:\n");
70    
71     IsoStream::dumpInfo();
72     debugOutputShort( DEBUG_LEVEL_NORMAL, "  StreamProcessor info:\n");
73     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011u\n",m_handler->getCycleTimerTicks());
74     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xruns                 : %d\n", m_xruns);
75     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Running               : %d\n", m_running);
76     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Enabled               : %s\n", m_disabled ? "No" : "Yes");
77     debugOutputShort( DEBUG_LEVEL_NORMAL, "   enable status        : %s\n", m_is_disabled ? "No" : "Yes");
78    
79     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Device framerate      : Sync: %f, Buffer %f\n",
80         24576000.0*m_SyncSource->m_data_buffer->getRate(),
81         24576000.0*m_data_buffer->getRate()
82         );
83    
84     m_data_buffer->dumpInfo();
85    
86 //     m_PeriodStat.dumpInfo();
87 //     m_PacketStat.dumpInfo();
88 //     m_WakeupStat.dumpInfo();
89
90 }
91
92 bool StreamProcessor::init()
93 {
94     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n");
95    
96     m_data_buffer->init();
97    
98     return IsoStream::init();
99 }
100
101 /**
102  * Resets the frame counter, the xrun counter, the ports and the iso stream.
103  * @return true if reset succeeded
104  */
105 bool StreamProcessor::reset() {
106
107     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
108
109     // reset the event buffer, discard all content
110     if (!m_data_buffer->reset()) {
111         debugFatal("Could not reset data buffer\n");
112         return false;
113     }
114    
115     resetXrunCounter();
116
117     // loop over the ports to reset them
118     if (!PortManager::resetPorts()) {
119         debugFatal("Could not reset ports\n");
120         return false;
121     }
122
123     // reset the iso stream
124     if (!IsoStream::reset()) {
125         debugFatal("Could not reset isostream\n");
126         return false;
127     }
128     return true;
129        
130 }
131
132 bool StreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
133     debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForEnable for (%p)\n",this);
134     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011u\n",m_handler->getCycleTimerTicks());
135     debugOutput(DEBUG_LEVEL_VERBOSE,"  Enable at             : %011u\n",time_to_enable_at);
136     m_data_buffer->dumpInfo();
137     return true;
138 }
139
140 bool StreamProcessor::prepareForDisable() {
141     debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForDisable for (%p)\n",this);
142     debugOutput(DEBUG_LEVEL_VERBOSE,"  Now                   : %011u\n",m_handler->getCycleTimerTicks());
143     m_data_buffer->dumpInfo();
144     return true;
145 }
146
147 bool StreamProcessor::prepare() {
148
149         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
150        
151         // init the ports
152        
153         if(!m_manager) {
154                 debugFatal("Not attached to a manager!\n");
155                 return -1;
156         }
157
158         m_nb_buffers=m_manager->getNbBuffers();
159         debugOutput( DEBUG_LEVEL_VERBOSE, "Setting m_nb_buffers  : %d\n", m_nb_buffers);
160
161         m_period=m_manager->getPeriodSize();
162         debugOutput( DEBUG_LEVEL_VERBOSE, "Setting m_period      : %d\n", m_period);
163
164         // loop over the ports to reset them
165         PortManager::preparePorts();
166
167         // reset the iso stream
168         IsoStream::prepare();
169        
170         return true;
171
172 }
173
174 // /**
175 //  * @brief Notify the StreamProcessor that frames were written
176 //  *
177 //  * This notifies the StreamProcessor of the fact that frames were written to the internal
178 //  * buffer. This is for framecounter & timestamp bookkeeping.
179 //  *
180 //  * @param nbframes the number of frames that are written to the internal buffers
181 //  * @param ts the new timestamp of the 'tail' of the buffer, i.e. the last sample
182 //  *           present in the buffer.
183 //  * @return true if successful
184 //  */
185 // bool StreamProcessor::putFrames(unsigned int nbframes, int64_t ts) {
186 //
187 //      debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Putting %d frames for %llu into frame buffer...\n", nbframes,ts);
188 // //         m_data_buffer->incrementFrameCounter(nbframes, ts);
189 //      return true;
190 // }
191
192 // /**
193 // * @brief Notify the StreamProcessor that frames were read
194 // *
195 // * This notifies the StreamProcessor of the fact that frames were read from the internal
196 // * buffer. This is for framecounter & timestamp bookkeeping.
197 // *
198 // * @param nbframes the number of frames that are read from the internal buffers
199 // * @return true if successful
200 // */
201 // bool StreamProcessor::getFrames(unsigned int nbframes) {
202 //
203 //      debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Getting %d frames from frame buffer...\n", nbframes);
204 // //         m_data_buffer->decrementFrameCounter(nbframes);
205 //      return true;
206 // }
207
208 uint64_t StreamProcessor::getTimeNow() {
209     return m_handler->getCycleTimerTicks();
210 }
211
212
213 bool StreamProcessor::isRunning() {
214         return m_running;
215 }
216
217 bool StreamProcessor::enable(uint64_t time_to_enable_at)  {
218     // FIXME: time_to_enable_at will be in 'time' not cycles
219     m_cycle_to_enable_at=time_to_enable_at;
220    
221     if(!m_running) {
222             debugWarning("The StreamProcessor is not running yet, enable() might not be a good idea.\n");
223     }
224
225 #ifdef DEBUG
226     uint64_t now_cycles=TICKS_TO_CYCLES(m_handler->getCycleTimerTicks());
227     const int64_t max=(int64_t)(TICKS_PER_SECOND/2);
228    
229     int64_t diff=(int64_t)m_cycle_to_enable_at-(int64_t)now_cycles;
230    
231     if (diff > max) {
232         diff-=TICKS_PER_SECOND;
233     } else if (diff < -max) {
234         diff+=TICKS_PER_SECOND;
235     }
236    
237     if (diff<0) {
238         debugWarning("Request to enable streamprocessor %lld cycles ago (now=%llu, cy=%llu).\n",
239             diff,now_cycles,time_to_enable_at);
240     }
241 #endif
242
243     m_disabled=false;
244    
245     return true;
246 }
247
248 bool StreamProcessor::disable()  {
249    
250     m_disabled=true;
251
252     return true;
253
254 }
255
256 bool StreamProcessor::setSyncSource(StreamProcessor *s) {
257     m_SyncSource=s;
258     return true;
259 }
260
261 /**
262  * Resets the xrun counter, in a atomic way. This
263  * is thread safe.
264  */
265 void StreamProcessor::resetXrunCounter() {
266         ZERO_ATOMIC((SInt32 *)&m_xruns);
267 }
268
269 void StreamProcessor::setVerboseLevel(int l) {
270         setDebugLevel(l);
271         IsoStream::setVerboseLevel(l);
272         PortManager::setVerboseLevel(l);
273
274 }
275
276 ReceiveStreamProcessor::ReceiveStreamProcessor(int port, int framerate)
277         : StreamProcessor(IsoStream::EST_Receive, port, framerate) {
278
279 }
280
281 ReceiveStreamProcessor::~ReceiveStreamProcessor() {
282
283 }
284
285 void ReceiveStreamProcessor::setVerboseLevel(int l) {
286         setDebugLevel(l);
287         StreamProcessor::setVerboseLevel(l);
288
289 }
290
291
292 TransmitStreamProcessor::TransmitStreamProcessor( int port, int framerate)
293         : StreamProcessor(IsoStream::EST_Transmit, port, framerate) {
294
295 }
296
297 TransmitStreamProcessor::~TransmitStreamProcessor() {
298
299 }
300
301 void TransmitStreamProcessor::setVerboseLevel(int l) {
302         setDebugLevel(l);
303         StreamProcessor::setVerboseLevel(l);
304
305 }
306
307 }
Note: See TracBrowser for help on using the browser.