Changeset 312
- Timestamp:
- 10/02/06 16:41:21 (17 years ago)
- Files:
-
- branches/libfreebob-2.0/src/libstreaming/MotuPort.h (modified) (1 diff)
- branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.cpp (modified) (14 diffs)
- branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.h (modified) (2 diffs)
- branches/libfreebob-2.0/src/libstreaming/StreamProcessor.h (modified) (1 diff)
- branches/libfreebob-2.0/src/libstreaming/StreamProcessorManager.cpp (modified) (2 diffs)
- branches/libfreebob-2.0/src/motu/motu_avdevice.cpp (modified) (3 diffs)
- branches/libfreebob-2.0/support/jack/freebob_driver.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/libfreebob-2.0/src/libstreaming/MotuPort.h
r267 r312 79 79 int position) 80 80 : MidiPort(name, direction), 81 MotuPortInfo(name, position, 2) // TODO: add more port information parameters here if nescessary81 MotuPortInfo(name, position, 0) // TODO: add more port information parameters here if nescessary 82 82 {}; 83 83 branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.cpp
r310 r312 71 71 return false; 72 72 } 73 m_next_cycle = -1;74 m_closedown_count = -1;75 m_streaming_active = 0;76 m_cycle_count = -1;77 m_cycle_ofs = 0.0;78 73 79 74 return true; … … 115 110 // Similarly, initialise the "next cycle". This can be done 116 111 // whenever iso data is seen - it doesn't have to wait until 117 // the stream is initialised.112 // the stream is enabled. 118 113 if (m_next_cycle < 0) 119 114 m_next_cycle = cycle; … … 138 133 139 134 // Detect a missed cycle and attempt to "catch up". 140 if (!m_disabled && m_next_cycle>=0 && cycle!=m_next_cycle) { 135 if (cycle != m_next_cycle) { 136 debugOutput(DEBUG_LEVEL_VERBOSE, "tx cycle miss: %d requested, %d expected\n",cycle,m_next_cycle); 137 } 138 // Attempt to catch up any missed cycles but only if we're enabled. 139 if (!m_disabled && cycle!=m_next_cycle) { 141 140 float ftmp; 142 141 signed int ccount = m_next_cycle; 143 debugOutput(DEBUG_LEVEL_VERBOSE, "tx cycle miss: %d requested, %d expected\n",cycle,m_next_cycle);144 142 145 143 while (ccount!=cycle) { … … 175 173 } 176 174 177 if (!m_disabled) { 178 if (++m_next_cycle >= 8000) 179 m_next_cycle -= 8000; 180 } else 181 m_next_cycle = -1; 175 if ((m_next_cycle=cycle+1) >= 8000) 176 m_next_cycle -= 8000; 182 177 183 178 // Deal cleanly with potential wrap-around cycle counter conditions … … 250 245 251 246 } else { 247 252 248 retval=RAW1394_ISO_OK; 253 249 *length += read_size; … … 387 383 } 388 384 389 m_next_cycle = -1;390 m_closedown_count = -1;391 m_streaming_active = 0;392 m_cycle_count = -1;393 m_cycle_ofs = 0.0;394 395 385 return true; 396 386 } … … 455 445 return false; 456 446 } 447 if (!(*it)->setBufferType(Port::E_RingBuffer)) { 448 debugFatal("Could not set buffer type"); 449 return false; 450 } 451 if (!(*it)->setDataType(Port::E_MidiEvent)) { 452 debugFatal("Could not set data type"); 453 return false; 454 } 455 // FIXME: probably need rate control too. See 456 // Port::useRateControl() and AmdtpStreamProcessor. 457 457 break; 458 458 … … 696 696 * @return true if all successfull 697 697 */ 698 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc) 699 { 700 bool ok=true; 701 char byte; 702 703 quadlet_t *target_event=NULL; 704 int j; 705 706 for ( PortVectorIterator it = m_PacketPorts.begin(); 707 it != m_PacketPorts.end(); 708 ++it ) 709 { 698 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, 699 unsigned int dbc) { 700 bool ok=true; 701 char byte; 702 703 // Use char here since the target address won't necessarily be 704 // aligned; use of an unaligned quadlet_t may cause issues on 705 // certain architectures. Besides, the target for MIDI data going 706 // directly to the MOTU isn't structured in quadlets anyway; it is a 707 // sequence of 3 unaligned bytes. 708 unsigned char *target = NULL; 709 710 for ( PortVectorIterator it = m_PacketPorts.begin(); 711 it != m_PacketPorts.end(); 712 ++it ) { 710 713 711 714 #ifdef DEBUG 712 MotuPortInfo *pinfo=dynamic_cast<MotuPortInfo *>(*it); 713 assert(pinfo); // this should not fail!! 714 715 // the only packet type of events for AMDTP is MIDI in mbla 716 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi); 715 //FIXME: make this into a static_cast when not DEBUG? 716 Port *port=dynamic_cast<Port *>(*it); 717 assert(port); // this should not fail!! 718 719 // Currently the only packet type of events for MOTU 720 // is MIDI in mbla. However in future control data 721 // might also be sent via "packet" events. 722 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi); 717 723 #endif 718 719 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 720 721 // TODO: decode the midi (or other type) stuff here 722 723 } 724 725 return ok; 724 // FIXME: MIDI output is completely untested at present. 725 switch (port->getPortType()) { 726 case Port::E_Midi: { 727 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 728 729 // Send a byte if we can. MOTU MIDI data is 730 // sent using a 3-byte sequence starting at 731 // the port's position. For now we'll 732 // always send in the first event of a 733 // packet, but this might need refinement 734 // later. 735 if (mp->canRead()) { 736 mp->readEvent(&byte); 737 target = (unsigned char *)data + mp->getPosition(); 738 *(target++) = 0x01; 739 *(target++) = 0x00; 740 *(target++) = byte; 741 } 742 break; 743 } 744 default: 745 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType()); 746 return ok; 747 } 748 } 749 750 return ok; 726 751 } 727 752 … … 871 896 } 872 897 898 bool MotuTransmitStreamProcessor::preparedForStart() { 899 // Reset some critical variables required so the stream starts cleanly. This 900 // method is called once on every stream restart, including those during 901 // xrun recovery. Initialisations which should be done once should be 902 // placed in the init() method instead. 903 m_running = 0; 904 m_next_cycle = -1; 905 m_closedown_count = -1; 906 m_streaming_active = 0; 907 m_cycle_count = -1; 908 m_cycle_ofs = 0.0; 909 910 // At this point we'll also disable the stream processor here. 911 // At this stage stream processors are always explicitly re-enabled 912 // after being started, so by starting in the disabled state we 913 // ensure that every start will be exactly the same. 914 disable(); 915 916 return true; 917 } 918 873 919 /* --------------------- RECEIVE ----------------------- */ 874 920 … … 890 936 bool MotuReceiveStreamProcessor::init() { 891 937 892 893 894 895 896 897 898 899 900 938 // call the parent init 939 // this has to be done before allocating the buffers, 940 // because this sets the buffersizes from the processormanager 941 if(!ReceiveStreamProcessor::init()) { 942 debugFatal("Could not do base class init (%d)\n",this); 943 return false; 944 } 945 946 return true; 901 947 } 902 948 … … 906 952 unsigned int cycle, unsigned int dropped) { 907 953 908 enum raw1394_iso_disposition retval=RAW1394_ISO_OK; 909 signed int have_lost_cycles = 0; 910 911 // Detect missed receive cycles 912 // FIXME: it would be nice to advance the rx buffer by the amount of 913 // frames missed. However, since the MOTU transmits more frames per 914 // cycle than the average and "catches up" with periodic empty cycles 915 // it's not trivial to work out precisely how many frames were missed. 916 // Ultimately I think we need to do so if sync is to be maintained 917 // across a transient receive failure. 918 if (m_next_cycle < 0) 919 m_next_cycle = cycle; 920 if ((signed)cycle != m_next_cycle) { 921 debugOutput(DEBUG_LEVEL_VERBOSE, "lost rx cycles; received %d, expected %d\n", 922 cycle, m_next_cycle); 923 m_next_cycle = cycle; 924 have_lost_cycles = 1; 925 } 926 if (!m_disabled) { 927 if (++m_next_cycle >= 8000) 928 m_next_cycle -= 8000; 929 } else 930 m_next_cycle = -1; 931 932 // If the packet length is 8 bytes (ie: just a CIP-like header) there is 933 // no isodata. 934 if (length > 8) { 935 // The iso data blocks from the MOTUs comprise a CIP-like header 936 // followed by a number of events (8 for 1x rates, 16 for 2x rates, 937 // 32 for 4x rates). 938 quadlet_t *quadlet = (quadlet_t *)data; 939 unsigned int dbs = get_bits(ntohl(quadlet[0]), 23, 8); // Size of one event in terms of fdf_size 940 unsigned int fdf_size = get_bits(ntohl(quadlet[1]), 23, 8) == 0x22 ? 32:0; // Event unit size in bits 941 unsigned int event_length = (fdf_size * dbs) / 8; // Event size in bytes 942 unsigned int n_events = (length-8) / event_length; 943 944 // Don't even attempt to process a packet if it isn't what we expect 945 // from a MOTU 946 if (tag!=1 || fdf_size!=32) { 947 return RAW1394_ISO_OK; 948 } 949 950 // Signal that we're running 951 if (n_events) m_running=true; 952 953 /* Send actual ticks-per-frame values (as deduced by the incoming 954 * SPHs) to the DLL for averaging. Doing this here means the DLL 955 * should acquire a reasonable estimation of the ticks per frame 956 * even while the stream is formally disabled. This in turn means 957 * the transmit stream should have access to a very realistic 958 * estimate by the time it is enabled. The major disadvantage 959 * is a small increase in the overheads of this function compared 960 * to what would be the case if this was delayed by pushing it into 961 * the decode functions. 962 */ 963 unsigned int ev; 964 signed int sph_ofs; 965 966 /* If this is the first block received or we have lost cycles, 967 * initialise the m_last_cycle_ofs to a value which won't cause the 968 * DLL to become polluted with an inappropriate ticks-per-frame 969 * estimate. 970 */ 971 if (m_last_cycle_ofs<0 || have_lost_cycles) { 972 sph_ofs = ntohl(*(quadlet_t *)(data+8)) & 0xfff; 973 m_last_cycle_ofs = sph_ofs-(int)(m_ticks_per_frame); 974 } 975 for (ev=0; ev<n_events; ev++) { 976 sph_ofs = ntohl(*(quadlet_t *)(data+8+ev*m_event_size)) & 0xfff; 977 signed int sph_diff = (sph_ofs - m_last_cycle_ofs); 978 // Handle wraparound of the cycle offset 979 if (sph_diff < 0) 980 sph_diff += 3072; 981 float err = sph_diff - m_ticks_per_frame; 982 // FIXME: originally we used a value of 0.0005 for the coefficient 983 // which mirrored the value used in 984 // AmdtpReceiveStreamProcessor::putPacket() for a similar purpose. 985 // However, tests showed that this introduced discontinuities in 986 // the output audio signal, so an alternative value was sought. 987 // Further tests are needed, but a value of 0.015 seems to work 988 // well, at least at a sample rate of 48 kHz. 989 m_ticks_per_frame += 0.015*err; 990 m_last_cycle_ofs = sph_ofs; 991 } 992 993 // Don't process the stream when it is not enabled 994 if (m_disabled) { 995 return RAW1394_ISO_OK; 996 } 997 998 // If closedown is active we also just throw data way, but in this case 999 // we keep the frame counter going to prevent a false xrun detection 1000 if (m_closedown_active) { 954 enum raw1394_iso_disposition retval=RAW1394_ISO_OK; 955 signed int have_lost_cycles = 0; 956 957 // Detect missed receive cycles 958 // FIXME: it would be nice to advance the rx buffer by the amount of 959 // frames missed. However, since the MOTU transmits more frames per 960 // cycle than the average and "catches up" with periodic empty 961 // cycles it's not trivial to work out precisely how many frames 962 // were missed. Ultimately I think we need to do so if sync is to 963 // be maintained across a transient receive failure. 964 if (m_next_cycle < 0) 965 m_next_cycle = cycle; 966 if ((signed)cycle != m_next_cycle) { 967 debugOutput(DEBUG_LEVEL_VERBOSE, "lost rx cycles; received %d, expected %d\n", 968 cycle, m_next_cycle); 969 m_next_cycle = cycle; 970 have_lost_cycles = 1; 971 } 972 if (++m_next_cycle >= 8000) 973 m_next_cycle -= 8000; 974 975 // If the packet length is 8 bytes (ie: just a CIP-like header) 976 // there is no isodata. 977 if (length > 8) { 978 // The iso data blocks from the MOTUs comprise a CIP-like 979 // header followed by a number of events (8 for 1x rates, 16 980 // for 2x rates, 32 for 4x rates). 981 quadlet_t *quadlet = (quadlet_t *)data; 982 unsigned int dbs = get_bits(ntohl(quadlet[0]), 23, 8); // Size of one event in terms of fdf_size 983 unsigned int fdf_size = get_bits(ntohl(quadlet[1]), 23, 8) == 0x22 ? 32:0; // Event unit size in bits 984 unsigned int event_length = (fdf_size * dbs) / 8; // Event size in bytes 985 unsigned int n_events = (length-8) / event_length; 986 987 // Don't even attempt to process a packet if it isn't what 988 // we expect from a MOTU. Yes, an FDF value of 32 bears 989 // little relationship to the actual data (24 bit integer) 990 // sent by the MOTU - it's one of those areas where MOTU 991 // have taken a curious detour around the standards. 992 if (tag!=1 || fdf_size!=32) { 993 return RAW1394_ISO_OK; 994 } 995 996 // Signal that we're running 997 if (n_events) m_running=true; 998 999 /* Send actual ticks-per-frame values (as deduced by the 1000 * incoming SPHs) to the DLL for averaging. Doing this here 1001 * means the DLL should acquire a reasonable estimation of 1002 * the ticks per frame even while the stream is formally 1003 * disabled. This in turn means the transmit stream should 1004 * have access to a very realistic estimate by the time it 1005 * is enabled. The major disadvantage is a small increase 1006 * in the overheads of this function compared to what would 1007 * be the case if this was delayed by pushing it into the 1008 * decode functions. 1009 */ 1010 unsigned int ev; 1011 signed int sph_ofs; 1012 1013 /* If this is the first block received or we have lost 1014 * cycles, initialise the m_last_cycle_ofs to a value which 1015 * won't cause the DLL to become polluted with an 1016 * inappropriate ticks-per-frame estimate. 1017 */ 1018 if (m_last_cycle_ofs<0 || have_lost_cycles) { 1019 sph_ofs = ntohl(*(quadlet_t *)(data+8)) & 0xfff; 1020 m_last_cycle_ofs = sph_ofs-(int)(m_ticks_per_frame); 1021 } 1022 for (ev=0; ev<n_events; ev++) { 1023 sph_ofs = ntohl(*(quadlet_t *)(data+8+ev*m_event_size)) & 0xfff; 1024 signed int sph_diff = (sph_ofs - m_last_cycle_ofs); 1025 // Handle wraparound of the cycle offset 1026 if (sph_diff < 0) 1027 sph_diff += 3072; 1028 float err = sph_diff - m_ticks_per_frame; 1029 // FIXME: originally we used a value of 0.0005 for 1030 // the coefficient which mirrored the value used in 1031 // AmdtpReceiveStreamProcessor::putPacket() for a 1032 // similar purpose. However, tests showed that this 1033 // introduced discontinuities in the output audio 1034 // signal, so an alternative value was sought. 1035 // Further tests are needed, but a value of 0.015 1036 // seems to work well, at least at a sample rate of 1037 // 48 kHz. 1038 m_ticks_per_frame += 0.015*err; 1039 m_last_cycle_ofs = sph_ofs; 1040 } 1041 1042 // Don't process the stream when it is not enabled 1043 if (m_disabled) { 1044 return RAW1394_ISO_OK; 1045 } 1046 1047 // If closedown is active we also just throw data way, but 1048 // in this case we keep the frame counter going to prevent a 1049 // false xrun detection 1050 if (m_closedown_active) { 1051 incrementFrameCounter(n_events); 1052 if (m_framecounter > (signed int)m_period) 1053 return RAW1394_ISO_DEFER; 1054 return RAW1394_ISO_OK; 1055 } 1056 1057 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n"); 1058 1059 // Add the data payload (events) to the ringbuffer. We'll 1060 // just copy everything including the 4 byte timestamp at 1061 // the start of each event (that is, everything except the 1062 // CIP-like header). The demultiplexer can deal with the 1063 // complexities such as the channel 24-bit data. 1064 unsigned int write_size = length-8; 1065 if (freebob_ringbuffer_write(m_event_buffer,(char *)(data+8),write_size) < write_size) { 1066 debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n", 1067 cycle, m_framecounter, m_handler->getPacketCount()); 1068 m_xruns++; 1069 1070 retval=RAW1394_ISO_DEFER; 1071 } else { 1072 retval=RAW1394_ISO_OK; 1073 // Process all ports that should be handled on a 1074 // per-packet basis. This is MIDI for AMDTP (due to 1075 // the need of DBC) 1076 int dbc = get_bits(ntohl(quadlet[0]), 8, 8); // Low byte of CIP quadlet 0 1077 if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) { 1078 debugWarning("Problem decoding Packet Ports\n"); 1079 retval=RAW1394_ISO_DEFER; 1080 } 1081 // time stamp processing can be done here 1082 } 1083 1084 // update the frame counter 1001 1085 incrementFrameCounter(n_events); 1002 if (m_framecounter > (signed int)m_period) 1003 return RAW1394_ISO_DEFER; 1004 return RAW1394_ISO_OK; 1005 } 1006 1007 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n"); 1008 1009 // Add the data payload (events) to the ringbuffer. We'll just copy 1010 // everything including the 4 byte timestamp at the start of each 1011 // event (that is, everything except the CIP-like header). The 1012 // demultiplexer can deal with the complexities such as the channel 1013 // 24-bit data. 1014 unsigned int write_size = length-8; 1015 if (freebob_ringbuffer_write(m_event_buffer,(char *)(data+8),write_size) < write_size) { 1016 debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n", 1017 cycle, m_framecounter, m_handler->getPacketCount()); 1018 m_xruns++; 1019 1020 retval=RAW1394_ISO_DEFER; 1021 } else { 1022 retval=RAW1394_ISO_OK; 1023 // Process all ports that should be handled on a per-packet basis 1024 // This is MIDI for AMDTP (due to the need of DBC) 1025 int dbc = get_bits(ntohl(quadlet[0]), 8, 8); // Low byte of CIP quadlet 0 1026 if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) { 1027 debugWarning("Problem decoding Packet Ports\n"); 1086 // keep this at the end, because otherwise the 1087 // raw1394_loop_iterate functions inner loop keeps 1088 // requesting packets without going to the xmit handler, 1089 // leading to xmit starvation 1090 if(m_framecounter>(signed int)m_period) { 1028 1091 retval=RAW1394_ISO_DEFER; 1029 1092 } 1030 // time stamp processing can be done here 1031 } 1032 1033 // update the frame counter 1034 incrementFrameCounter(n_events); 1035 // keep this at the end, because otherwise the raw1394_loop_iterate functions inner loop 1036 // keeps requesting packets without going to the xmit handler, leading to xmit starvation 1037 if(m_framecounter>(signed int)m_period) { 1038 retval=RAW1394_ISO_DEFER; 1039 } 1040 1041 } else { // no events in packet 1042 // discard packet 1043 // can be important for sync though 1044 } 1093 1094 } else { // no events in packet 1095 // discard packet 1096 // can be important for sync though 1097 } 1045 1098 1046 1099 return retval; 1047 1100 } 1048 1101 … … 1149 1202 return false; 1150 1203 } 1204 if (!(*it)->setBufferType(Port::E_RingBuffer)) { 1205 debugFatal("Could not set buffer type"); 1206 return false; 1207 } 1208 if (!(*it)->setDataType(Port::E_MidiEvent)) { 1209 debugFatal("Could not set data type"); 1210 return false; 1211 } 1212 // FIXME: probably need rate control too. See 1213 // Port::useRateControl() and AmdtpStreamProcessor. 1151 1214 break; 1152 1215 case Port::E_Control: … … 1320 1383 * @return true if all successfull 1321 1384 */ 1322 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)1323 {1385 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, 1386 unsigned int dbc) { 1324 1387 bool ok=true; 1325 1326 quadlet_t *target_event=NULL; 1327 int j; 1328 1388 1389 // Use char here since the source address won't necessarily be 1390 // aligned; use of an unaligned quadlet_t may cause issues on 1391 // certain architectures. Besides, the source for MIDI data going 1392 // directly to the MOTU isn't structured in quadlets anyway; it is a 1393 // sequence of 3 unaligned bytes. 1394 unsigned char *src = NULL; 1395 1329 1396 for ( PortVectorIterator it = m_PacketPorts.begin(); 1330 1331 1397 it != m_PacketPorts.end(); 1398 ++it ) { 1332 1399 1333 1400 #ifdef DEBUG 1334 MotuPortInfo *pinfo=dynamic_cast<MotuPortInfo *>(*it); 1335 assert(pinfo); // this should not fail!! 1336 1337 // the only packet type of events for AMDTP is MIDI in mbla 1338 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi); 1401 //FIXME: make these into a static_casts when not DEBUG? 1402 Port *port=dynamic_cast<Port *>(*it); 1403 assert(port); // this should not fail!! 1404 1405 // Currently the only packet type of events for MOTU 1406 // is MIDI in mbla. However in future control data 1407 // might also be sent via "packet" events, so allow 1408 // for this possible expansion. 1339 1409 #endif 1340 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 1341 1342 1343 // do decoding here 1344 1345 } 1346 1410 // FIXME: MIDI input is completely untested at present. 1411 switch (port->getPortType()) { 1412 case Port::E_Midi: { 1413 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 1414 signed int sample; 1415 unsigned int j = 0; 1416 // Get MIDI bytes if present anywhere in the 1417 // packet. MOTU MIDI data is sent using a 1418 // 3-byte sequence starting at the port's 1419 // position. It's thought that there can never 1420 // be more than one MIDI byte per packet, but 1421 // for completeness we'll check the entire packet 1422 // anyway. 1423 src = (unsigned char *)data + mp->getPosition(); 1424 while (j < nevents) { 1425 if (*src==0x01 && *(src+1)==0x00) { 1426 sample = *(src+2); 1427 if (!mp->writeEvent(&sample)) { 1428 debugWarning("MIDI packet port events lost\n"); 1429 ok = false; 1430 } 1431 } 1432 j++; 1433 src += m_event_size; 1434 } 1435 break; 1436 } 1437 default: 1438 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType()); 1439 return ok; 1440 } 1441 } 1442 1347 1443 return ok; 1348 1444 } … … 1442 1538 return true; 1443 1539 } 1540 1541 bool MotuReceiveStreamProcessor::preparedForStart() { 1542 // Reset some critical variables required so the stream starts cleanly. This 1543 // method is called once on every stream restart, including those during 1544 // xrun recovery. Initialisations which should be done once should be 1545 // placed in the init() method instead. 1546 m_running = 0; 1547 m_next_cycle = -1; 1548 m_closedown_active = 0; 1549 m_last_cycle_ofs = -1; 1550 1551 // At this point we'll also disable the stream processor here. 1552 // At this stage stream processors are always explicitly re-enabled 1553 // after being started, so by starting in the disabled state we 1554 // ensure that every start will be exactly the same. 1555 disable(); 1556 1557 return true; 1558 } 1559 1444 1560 1445 1561 } // end of namespace FreebobStreaming branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.h
r309 r312 76 76 77 77 virtual bool preparedForStop(); 78 virtual bool preparedForStart(); 78 79 79 80 protected: … … 165 166 166 167 virtual bool preparedForStop(); 168 virtual bool preparedForStart(); 167 169 168 170 protected: branches/libfreebob-2.0/src/libstreaming/StreamProcessor.h
r287 r312 112 112 113 113 virtual bool preparedForStop() {return true;}; 114 virtual bool preparedForStart() {return true;}; 114 115 115 116 protected: branches/libfreebob-2.0/src/libstreaming/StreamProcessorManager.cpp
r309 r312 320 320 it != m_ReceiveProcessors.end(); 321 321 ++it ) { 322 if (!(*it)->preparedForStart()) { 323 debugOutput(DEBUG_LEVEL_VERBOSE,"Receive stream processor (%p) failed to prepare for start\n", *it); 324 return false; 325 } 322 326 if (!m_isoManager->registerStream(*it)) { 323 327 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register receive stream processor (%p) with the Iso manager\n",*it); … … 332 336 it != m_TransmitProcessors.end(); 333 337 ++it ) { 338 if (!(*it)->preparedForStart()) { 339 debugOutput(DEBUG_LEVEL_VERBOSE,"Transmit stream processor (%p) failed to prepare for start\n", *it); 340 return false; 341 } 334 342 if (!m_isoManager->registerStream(*it)) { 335 343 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register transmit stream processor (%p) with the Iso manager\n",*it); branches/libfreebob-2.0/src/motu/motu_avdevice.cpp
r311 r312 404 404 405 405 char *buff; 406 unsigned int i;407 406 FreebobStreaming::Port *p=NULL; 408 407 … … 412 411 } 413 412 414 // example of adding an midi port: 415 // asprintf(&buff,"dev%d_cap_%s",m_id,"myportnamehere"); 416 // p=new FreebobStreaming::MotuMidiPort( 417 // buff, 418 // FreebobStreaming::Port::E_Capture, 419 // 0 // you can add all other port specific stuff you 420 // // need to pass by extending MotuXXXPort and MotuPortInfo 421 // ); 422 // free(buff); 423 // 424 // if (!p) { 425 // debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 426 // } else { 427 // if (!m_receiveProcessor->addPort(p)) { 428 // debugWarning("Could not register port with stream processor\n"); 429 // return false; 430 // } else { 431 // debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 432 // } 433 // } 434 413 // Add MIDI port. The MOTU only has one MIDI input port, with each 414 // MIDI byte sent using a 3 byte sequence starting at byte 4 of the 415 // event data. 416 asprintf(&buff,"dev%d_cap_MIDI0",m_id); 417 p = new FreebobStreaming::MotuMidiPort(buff, 418 FreebobStreaming::Port::E_Capture, 4); 419 if (!p) { 420 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 421 } else { 422 if (!m_receiveProcessor->addPort(p)) { 423 debugWarning("Could not register port with stream processor\n"); 424 free(buff); 425 return false; 426 } else { 427 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 428 } 429 } 430 free(buff); 431 435 432 // example of adding an control port: 436 433 // asprintf(&buff,"dev%d_cap_%s",m_id,"myportnamehere"); … … 478 475 } 479 476 480 // // example of adding an midi port: 481 // asprintf(&buff,"dev%d_pbk_%s",m_id,"myportnamehere"); 482 // 483 // p=new FreebobStreaming::MotuMidiPort( 484 // buff, 485 // FreebobStreaming::Port::E_Playback, 486 // 0 // you can add all other port specific stuff you 487 // // need to pass by extending MotuXXXPort and MotuPortInfo 488 // ); 489 // free(buff); 490 // 491 // if (!p) { 492 // debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 493 // } else { 494 // if (!m_transmitProcessor->addPort(p)) { 495 // debugWarning("Could not register port with stream processor\n"); 496 // return false; 497 // } else { 498 // debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 499 // } 500 // } 501 477 // Add MIDI port. The MOTU only has one output MIDI port, with each 478 // MIDI byte transmitted using a 3 byte sequence starting at byte 4 479 // of the event data. 480 asprintf(&buff,"dev%d_pbk_MIDI0",m_id); 481 p = new FreebobStreaming::MotuMidiPort(buff, 482 FreebobStreaming::Port::E_Capture, 4); 483 if (!p) { 484 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 485 } else { 486 if (!m_receiveProcessor->addPort(p)) { 487 debugWarning("Could not register port with stream processor\n"); 488 free(buff); 489 return false; 490 } else { 491 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 492 } 493 } 494 free(buff); 495 502 496 // example of adding an control port: 503 497 // asprintf(&buff,"dev%d_pbk_%s",m_id,"myportnamehere"); branches/libfreebob-2.0/support/jack/freebob_driver.c
r302 r312 207 207 for (node = driver->capture_ports; node; 208 208 node = jack_slist_next (node)) { 209 jack_port_unregister (driver->client, 210 ((jack_port_t *) node->data)); 209 // Don't try to unregister NULL entries added for non-audio 210 // freebob ports by freebob_driver_attach(). 211 if (node->data != NULL) { 212 jack_port_unregister (driver->client, 213 ((jack_port_t *) node->data)); 214 } 211 215 } 212 216