2
* Copyright (C) 2005-2008, 2011 by Jonathan Woithe
3
* Copyright (C) 2005-2008 by Pieter Palmers
5
* This file is part of FFADO
6
* FFADO = Free Firewire (pro-)audio drivers for linux
8
* FFADO is based upon FreeBoB.
10
* This program is free software: you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation, either version 2 of the License, or
13
* (at your option) version 3 of the License.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program. If not, see <http://www.gnu.org/licenses/>.
26
#include "libutil/float_cast.h"
28
#include "DigidesignReceiveStreamProcessor.h"
29
#include "DigidesignPort.h"
30
#include "../StreamProcessorManager.h"
31
#include "devicemanager.h"
33
#include "libieee1394/ieee1394service.h"
34
#include "libieee1394/IsoHandlerManager.h"
35
#include "libieee1394/cycletimer.h"
37
#include "libutil/ByteSwap.h"
46
DigidesignReceiveStreamProcessor::DigidesignReceiveStreamProcessor(FFADODevice &parent, unsigned int event_size)
47
: StreamProcessor(parent, ePT_Receive)
48
, m_event_size( event_size )
50
// Add whatever else needs to be initialised.
54
DigidesignReceiveStreamProcessor::getMaxPacketSize() {
56
// Frame rate is accessible with something like this:
57
// int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate();
59
// What's returned here is the maximum packet size seen at the current
60
// frame rate. This depends both on the device and its configuration,
61
// and is futher complicated by the IN/OUT channel asymmetry in some
62
// devices. To avoid most of these complications, just return the
63
// largest packet sizes seen by any supported Digidesign device.
65
// Fill in the requsite details.
70
DigidesignReceiveStreamProcessor::getNominalFramesPerPacket() {
71
// Return the number of frames per firewire iso packet. A "frame" here is a collection
72
// of a single audio sample from all active audio channels. If this depends on the
73
// sample rate, that can be obtained using something like this:
74
// int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate();
79
DigidesignReceiveStreamProcessor::prepareChild() {
80
debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this);
82
// If the receive stream processor requires that things be set up which
83
// could not be done in the constructor, here is where they should be
84
// done. Return true on success, or false if the setup failed for some
85
// reason. In most cases, this method will do nothing.
90
enum StreamProcessor::eChildReturnValue
91
DigidesignReceiveStreamProcessor::processPacketHeader(unsigned char *data, unsigned int length,
92
unsigned char tag, unsigned char sy,
95
// This function will be called once for each incoming packet. It
96
// should check to ensure the packet contains valid data and (if it is)
97
// extract a timestamp from it. "data" points to the iso packet's
98
// contents - no assumption is made about what constitutes a "header"
99
// because each device's protocol is different. Note that the firewire
100
// ISO header is not included in "data".
102
// The return value should be one of the eCRV_* constants. The two
103
// most commonly used here are:
104
// eCRV_Invalid = unrecognised packet. No further processing needed.
105
// eCRV_OK = packet contains audio data and requires processing.
107
// The decision as to what constitutes a valid data packet depends on
108
// the format of the iso packets sent by the Digidesign hardware.
110
// Other parameters to this function contain selected information from
111
// the firewire ISO header which came with this packet:
112
// - length = length in bytes of the content pointed to by "data".
113
// - tag = the iso packet header's "tag" field.
114
// - sy = the sy field from the iso packet header.
115
// - pkt_ctr = the value of the iso timer at the time the packet was
116
// received by the PC.
118
// If a valid packet has been received from the Digidesign device,
119
// this method should set the object's m_last_timestamp field to the
120
// timestamp of the last frame in the packet. Determining this is
121
// device specific. Some devices embed this in the stream, while
122
// others require that it be synthesised. FFADO uses this timestamp
123
// to keep the transmit stream in sync with the receive stream.
125
// An example implementation:
127
// if (packet is valid) {
128
// m_last_timestamp = something useful
131
// return eCRV_Invalid;
137
enum StreamProcessor::eChildReturnValue
138
DigidesignReceiveStreamProcessor::processPacketData(unsigned char *data, unsigned int length) {
140
// This method is called once per ISO packet which has been flagged as
141
// valid by processPacketHeader(). "data" points to "length" bytes
142
// of data. "data" will in general have the same content as was
143
// presented to processPacketHeader().
145
// Conceptually this method is quite simple. Once you know the number
146
// of "events" (aka frames) in the packet - either through prior
147
// knowledge or by calculation based on the packet length - one simply
148
// calls the associated data buffer's writeFrames() method to get the
149
// data from the iso packet and into the internal buffer. The details
150
// as to how this is done are encapsulated in later methods.
152
// First we either calculate or obtain the number of events in the packet.
153
unsigned int n_events = 0;
155
// Call writeFrames() to process the data. m_last_timestamp should have
156
// been set up by processPacketHeader(). The pointer passed to
157
// writeFrames (data in this case) should for convenience be the pointer
158
// to the start of the first frame's data. If for example the packet
159
// starts with its own 8-byte packet header (as opposed to the standard
160
// iso packet header which is stripped off before this method is
161
// called), (data+8) would be supplied instead.
162
if(m_data_buffer->writeFrames(n_events, (char *)(data), m_last_timestamp)) {
169
/***********************************************
170
* Encoding/Decoding API *
171
***********************************************/
173
* \brief write received events to the port ringbuffers.
175
bool DigidesignReceiveStreamProcessor::processReadBlock(char *data,
176
unsigned int nevents, unsigned int offset)
178
// This function is called by the Encoding/Decoding engine encapsulated
179
// by the call to writeFrames(). It should extract data from the "data"
180
// array into the device's port ringbuffers. A "port" in this context
181
// is analogous to a jack port - one has one port for each audio channel
182
// provided by the device.
184
// Each "port" is processed in turn. The decodeDigidesign*() methods
185
// are called to do the actual work.
187
// "offset" is an offset (in frames) from the start of the ring buffer
188
// where the incoming data should be copied to. "nevents" is the
189
// number of events (aka frames) which need to be processed for each
192
bool no_problem=true;
194
for ( PortVectorIterator it = m_Ports.begin();
197
if((*it)->isDisabled()) {continue;};
201
switch(port->getPortType()) {
204
if(decodeDigidesignEventsToPort(static_cast<DigidesignAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
205
debugWarning("Could not decode packet data to port %s\n",(*it)->getName().c_str());
210
if(decodeDigidesignMidiEventsToPort(static_cast<DigidesignMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) {
211
debugWarning("Could not decode packet midi data to port %s\n",(*it)->getName().c_str());
223
signed int DigidesignReceiveStreamProcessor::decodeDigidesignEventsToPort(DigidesignAudioPort *p,
224
quadlet_t *data, unsigned int offset, unsigned int nevents)
227
// Decode "nevents" samples corresponding to the audio port "p" from the
228
// device datastream "data" into each port's ringbuffer at an offset of
229
// "offset" samples from the ringbuffer's origin. Return value should
232
// In theory the type of data handled by the ringbuffers can be
233
// any one of the eADT_* settings. This can be determined by calling
234
// m_StreamProcessorManager.getAudioDataType().
235
// For use with JACK (the most common use case of FFADO) this will
236
// always be StreamProcessorManager::eADT_Float, but one should at
237
// least allow for the possibility of others, even if one chooses not
238
// to support them yet.
240
// The getPosition() port method returns the "position" field of the
241
// port. This is used to describe where in the frame the channel's data
242
// is to be found. Other fields can be added to DigidesignAudioPort to
243
// store other details which might be required to decode the data
244
// packets. In general "position" is about the only one normally
245
// needed. Whether "position" is in bytes, frames, or something else is
246
// really determined by the contents of this method. Choose whatever
251
// The following is an example implementation showing the general idea.
252
// It will need to be changed to suit the protocol of the Digidesign
253
// devices. It assumes that data is supplied by the device in packed
254
// 24-bit integers in big endian format, and that the port's "position"
255
// is in bytes. Note that the m_event_size object member is assumed to
256
// have been set up previous to be the event size in bytes. If for a
257
// given implementation it is more convenient to use a "signed int *"
258
// for src_data one could have m_event_size measured in quadlets (32-bit
259
// integers). Again, it doesn't really matter so long as you're
262
// Use char here since a port's source address won't necessarily be
263
// aligned; use of an unaligned quadlet_t may cause issues on
264
// certain architectures.
265
unsigned char *src_data;
266
src_data = (unsigned char *)data + p->getPosition();
268
switch(m_StreamProcessorManager.getAudioDataType()) {
269
case StreamProcessorManager::eADT_Float:
271
const float multiplier = 1.0f / (float)(0x7FFFFF);
272
float *buffer=(float *)(p->getBufferAddress());
274
assert(nevents + offset <= p->getBufferSize());
278
for (j = 0; j < nevents; j += 1) { // decode max nsamples
280
signed int v = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
281
/* Sign-extend highest bit of incoming 24-bit integer */
282
if (*src_data & 0x80)
284
*buffer = v * multiplier;
286
src_data += m_event_size;
291
case StreamProcessorManager::eADT_Int24:
293
quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
295
assert(nevents + offset <= p->getBufferSize());
297
// Offset is in frames, but each port is only a single
298
// channel, so the number of frames is the same as the
299
// number of quadlets to offset (assuming the port buffer
300
// uses one quadlet per sample, which is the case currently).
303
for(j = 0; j < nevents; j += 1) { // Decode nsamples
304
*buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
305
// Sign-extend highest bit of 24-bit int.
306
// This isn't strictly needed since E_Int24 is a 24-bit,
307
// but doing so shouldn't break anything and makes the data
308
// easier to deal with during debugging.
309
if (*src_data & 0x80)
310
*buffer |= 0xff000000;
313
src_data+=m_event_size;
327
DigidesignReceiveStreamProcessor::decodeDigidesignMidiEventsToPort(
328
DigidesignMidiPort *p, quadlet_t *data,
329
unsigned int offset, unsigned int nevents)
331
// As for decodeDigidesignEventsToPort() except this method
332
// deals with MIDI streams. Depending on how MIDI is sent by
333
// the device, this method may be structured similarly to
334
// decodeDigidesignEventsToPort() or it may be completely
335
// different (as it is for MOTU devices for example). Return
336
// value should be zero.
341
} // end of namespace Streaming