410 | | |
---|
411 | | if(!encodeAudioPorts((quadlet_t *)data, offset, nevents)) { |
---|
412 | | debugError("Could not encode audio ports\n"); |
---|
413 | | return false; |
---|
414 | | } |
---|
415 | | |
---|
416 | | // for ( PortVectorIterator it = m_Ports.begin(); |
---|
417 | | // it != m_Ports.end(); |
---|
418 | | // ++it ) |
---|
419 | | // { |
---|
420 | | // if ( (*it)->isDisabled() ) { continue; }; |
---|
421 | | // |
---|
422 | | // //FIXME: make this into a static_cast when not DEBUG? |
---|
423 | | // AmdtpPortInfo *pinfo = dynamic_cast<AmdtpPortInfo *> ( *it ); |
---|
424 | | // assert ( pinfo ); // this should not fail!! |
---|
425 | | // |
---|
426 | | // switch( pinfo->getFormat() ) |
---|
427 | | // { |
---|
428 | | // case AmdtpPortInfo::E_MBLA: |
---|
429 | | // if( encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) |
---|
430 | | // { |
---|
431 | | // debugWarning ( "Could not encode port %s to MBLA events", (*it)->getName().c_str() ); |
---|
432 | | // no_problem = false; |
---|
433 | | // } |
---|
434 | | // break; |
---|
435 | | // case AmdtpPortInfo::E_SPDIF: // still unimplemented |
---|
436 | | // break; |
---|
437 | | // case AmdtpPortInfo::E_Midi: |
---|
438 | | // if( encodePortToMidiEvents(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents) ) |
---|
439 | | // { |
---|
440 | | // debugWarning ( "Could not encode port %s to Midi events", (*it)->getName().c_str() ); |
---|
441 | | // no_problem = false; |
---|
442 | | // } |
---|
443 | | // break; |
---|
444 | | // default: // ignore |
---|
445 | | // break; |
---|
446 | | // } |
---|
447 | | // } |
---|
448 | | return no_problem; |
---|
| 409 | switch(m_StreamProcessorManager.getAudioDataType()) { |
---|
| 410 | case StreamProcessorManager::eADT_Int24: |
---|
| 411 | encodeAudioPortsInt24((quadlet_t *)data, offset, nevents); |
---|
| 412 | break; |
---|
| 413 | case StreamProcessorManager::eADT_Float: |
---|
| 414 | encodeAudioPortsFloat((quadlet_t *)data, offset, nevents); |
---|
| 415 | break; |
---|
| 416 | } |
---|
| 417 | encodeMidiPorts((quadlet_t *)data, offset, nevents); |
---|
| 418 | return true; |
---|
455 | | bool no_problem = true; |
---|
456 | | for(PortVectorIterator it = m_Ports.begin(); |
---|
457 | | it != m_Ports.end(); |
---|
458 | | ++it ) |
---|
459 | | { |
---|
460 | | //FIXME: make this into a static_cast when not DEBUG? |
---|
461 | | AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); |
---|
462 | | assert(pinfo); // this should not fail!! |
---|
463 | | |
---|
464 | | switch( pinfo->getFormat() ) |
---|
465 | | { |
---|
466 | | case AmdtpPortInfo::E_MBLA: |
---|
467 | | if ( encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) |
---|
468 | | { |
---|
469 | | debugWarning("Could not encode silence for port %s to MBLA events", (*it)->getName().c_str()); |
---|
470 | | no_problem = false; |
---|
471 | | } |
---|
472 | | break; |
---|
473 | | case AmdtpPortInfo::E_SPDIF: // still unimplemented |
---|
474 | | break; |
---|
475 | | case AmdtpPortInfo::E_Midi: |
---|
476 | | if( encodeSilencePortToMidiEvents(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents) ) |
---|
477 | | { |
---|
478 | | debugWarning ( "Could not encode silence for port %s to Midi events", (*it)->getName().c_str() ); |
---|
479 | | no_problem = false; |
---|
480 | | } |
---|
481 | | break; |
---|
482 | | default: // ignore |
---|
483 | | break; |
---|
484 | | } |
---|
485 | | } |
---|
486 | | return no_problem; |
---|
487 | | } |
---|
488 | | |
---|
489 | | int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, |
---|
490 | | unsigned int offset, unsigned int nevents ) |
---|
491 | | { |
---|
492 | | unsigned int j=0; |
---|
493 | | |
---|
494 | | quadlet_t *target_event; |
---|
495 | | |
---|
496 | | target_event= ( quadlet_t * ) ( data + p->getPosition() ); |
---|
497 | | |
---|
498 | | switch ( m_StreamProcessorManager.getAudioDataType() ) |
---|
499 | | { |
---|
500 | | default: |
---|
501 | | debugError("bad type: %d\n", m_StreamProcessorManager.getAudioDataType()); |
---|
502 | | return -1; |
---|
503 | | case StreamProcessorManager::eADT_Int24: |
---|
504 | | { |
---|
505 | | quadlet_t *buffer= ( quadlet_t * ) ( p->getBufferAddress() ); |
---|
506 | | |
---|
507 | | assert ( nevents + offset <= p->getBufferSize() ); |
---|
508 | | |
---|
509 | | buffer+=offset; |
---|
510 | | |
---|
511 | | for ( j = 0; j < nevents; j += 1 ) // decode max nsamples |
---|
512 | | { |
---|
513 | | *target_event = htonl ( ( * ( buffer ) & 0x00FFFFFF ) | 0x40000000 ); |
---|
514 | | buffer++; |
---|
515 | | target_event += m_dimension; |
---|
516 | | } |
---|
517 | | } |
---|
518 | | break; |
---|
519 | | case StreamProcessorManager::eADT_Float: |
---|
520 | | { |
---|
521 | | float *buffer= ( float * ) ( p->getBufferAddress() ); |
---|
522 | | |
---|
523 | | assert ( nevents + offset <= p->getBufferSize() ); |
---|
524 | | |
---|
525 | | buffer+=offset; |
---|
526 | | |
---|
527 | | for ( j = 0; j < nevents; j += 1 ) // decode max nsamples |
---|
528 | | { |
---|
529 | | |
---|
530 | | // don't care for overflow |
---|
531 | | float v = *buffer * AMDTP_FLOAT_MULTIPLIER; // v: -231 .. 231 |
---|
532 | | unsigned int tmp = ( ( int ) v ); |
---|
533 | | *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); |
---|
534 | | |
---|
535 | | buffer++; |
---|
536 | | target_event += m_dimension; |
---|
537 | | } |
---|
538 | | } |
---|
539 | | break; |
---|
540 | | } |
---|
541 | | |
---|
542 | | return 0; |
---|
543 | | } |
---|
544 | | |
---|
545 | | // note: make sure that the midi events in the port buffer are only placed on (buffer+offset+x)%8 == 0 |
---|
546 | | // i.e. 8 frame aligned |
---|
547 | | int AmdtpTransmitStreamProcessor::encodePortToMidiEvents ( AmdtpMidiPort *p, quadlet_t *data, |
---|
548 | | unsigned int offset, unsigned int nevents ) |
---|
549 | | { |
---|
550 | | unsigned int j=0; |
---|
551 | | unsigned int position = p->getPosition(); |
---|
552 | | unsigned int location = p->getLocation(); |
---|
553 | | |
---|
554 | | quadlet_t *target_event; |
---|
555 | | quadlet_t tmpval; |
---|
556 | | |
---|
557 | | quadlet_t *buffer = (quadlet_t *)(p->getBufferAddress()); |
---|
558 | | |
---|
559 | | assert(nevents + offset <= p->getBufferSize()); |
---|
560 | | |
---|
561 | | buffer+=offset; |
---|
562 | | |
---|
563 | | for ( j = location; j < nevents; j += 8 ) |
---|
564 | | { |
---|
565 | | target_event = (quadlet_t *) (data + ((j * m_dimension) + position)); |
---|
566 | | |
---|
567 | | if ( *buffer & 0xFF000000 ) // we can send a byte |
---|
568 | | { |
---|
569 | | tmpval = ((*buffer)<<16) & 0x00FF0000; |
---|
570 | | tmpval=IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); |
---|
571 | | *target_event = htonl(tmpval); |
---|
572 | | |
---|
573 | | // debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", |
---|
574 | | // p->getName().c_str(), position, location, nevents, m_dimension ); |
---|
575 | | // debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", |
---|
576 | | // data, target_event, tmpval ); |
---|
577 | | } else { |
---|
578 | | // can't send a byte, either because there is no byte, |
---|
579 | | // or because this would exceed the maximum rate |
---|
580 | | // FIXME: this can be ifdef optimized since it's a constant |
---|
581 | | *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); |
---|
582 | | } |
---|
583 | | buffer+=8; |
---|
584 | | } |
---|
585 | | |
---|
586 | | return 0; |
---|
587 | | } |
---|
588 | | |
---|
589 | | int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, |
---|
590 | | unsigned int offset, unsigned int nevents ) |
---|
591 | | { |
---|
592 | | unsigned int j=0; |
---|
593 | | |
---|
594 | | quadlet_t *target_event; |
---|
595 | | |
---|
596 | | target_event= ( quadlet_t * ) ( data + p->getPosition() ); |
---|
597 | | |
---|
598 | | switch ( m_StreamProcessorManager.getAudioDataType() ) |
---|
599 | | { |
---|
600 | | default: |
---|
601 | | case StreamProcessorManager::eADT_Int24: |
---|
602 | | case StreamProcessorManager::eADT_Float: |
---|
603 | | { |
---|
604 | | for ( j = 0; j < nevents; j += 1 ) // decode max nsamples |
---|
605 | | { |
---|
606 | | *target_event = htonl ( 0x40000000 ); |
---|
607 | | target_event += m_dimension; |
---|
608 | | } |
---|
609 | | } |
---|
610 | | break; |
---|
611 | | } |
---|
612 | | |
---|
613 | | return 0; |
---|
614 | | } |
---|
615 | | |
---|
616 | | int AmdtpTransmitStreamProcessor::encodeSilencePortToMidiEvents ( AmdtpMidiPort *p, quadlet_t *data, |
---|
617 | | unsigned int offset, unsigned int nevents ) |
---|
618 | | { |
---|
619 | | unsigned int j=0; |
---|
620 | | unsigned int position = p->getPosition(); |
---|
621 | | unsigned int location = p->getLocation(); |
---|
622 | | |
---|
623 | | quadlet_t *target_event; |
---|
624 | | |
---|
625 | | for ( j = location; j < nevents; j += 8 ) |
---|
626 | | { |
---|
627 | | target_event = (quadlet_t *) (data + ((j * m_dimension) + position)); |
---|
628 | | *target_event=htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); |
---|
629 | | } |
---|
630 | | |
---|
631 | | return 0; |
---|
| 425 | // no need to update the port cache when transmitting silence since |
---|
| 426 | // no dynamic values are used to do so. |
---|
| 427 | |
---|
| 428 | encodeAudioPortsSilence((quadlet_t *)data, offset, nevents); |
---|
| 429 | encodeMidiPortsSilence((quadlet_t *)data, offset, nevents); |
---|
| 430 | return true; |
---|
655 | | switch ( m_StreamProcessorManager.getAudioDataType() ) |
---|
656 | | { |
---|
657 | | case StreamProcessorManager::eADT_Float: |
---|
| 479 | float *buffer = (float *)(p.buffer); |
---|
| 480 | buffer += offset; |
---|
| 481 | |
---|
| 482 | for (j = 0;j < nevents; j += 1) |
---|
| 483 | { |
---|
| 484 | // don't care for overflow |
---|
| 485 | float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; |
---|
| 486 | unsigned int tmp = ((int) v); |
---|
| 487 | *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); |
---|
| 488 | buffer++; |
---|
| 489 | target_event += m_dimension; |
---|
| 490 | } |
---|
| 491 | } |
---|
| 492 | } |
---|
| 493 | |
---|
| 494 | /** |
---|
| 495 | * @brief encodes all audio ports in the cache to events (int24 data) |
---|
| 496 | * @param data |
---|
| 497 | * @param offset |
---|
| 498 | * @param nevents |
---|
| 499 | */ |
---|
| 500 | void |
---|
| 501 | AmdtpTransmitStreamProcessor::encodeAudioPortsInt24(quadlet_t *data, |
---|
| 502 | unsigned int offset, |
---|
| 503 | unsigned int nevents) |
---|
| 504 | { |
---|
| 505 | unsigned int j; |
---|
| 506 | quadlet_t *target_event; |
---|
| 507 | unsigned int i; |
---|
| 508 | |
---|
| 509 | for (i = 0; i < m_nb_audio_ports; i++) { |
---|
| 510 | struct _MBLA_port_cache &p = m_audio_ports.at(i); |
---|
| 511 | target_event = (quadlet_t *)(data + i); |
---|
| 512 | assert(nevents + offset <= p.buffer_size ); |
---|
| 513 | |
---|
| 514 | uint32_t *buffer = (uint32_t *)(p.buffer); |
---|
| 515 | buffer += offset; |
---|
| 516 | |
---|
| 517 | for (j = 0; j < nevents; j += 1) |
---|
| 518 | { |
---|
| 519 | *target_event = htonl(((*buffer) & 0x00FFFFFF) | 0x40000000); |
---|
| 520 | buffer++; |
---|
| 521 | target_event += m_dimension; |
---|
| 522 | } |
---|
| 523 | } |
---|
| 524 | } |
---|
| 525 | |
---|
| 526 | /** |
---|
| 527 | * @brief encodes all midi ports in the cache to events (silence) |
---|
| 528 | * @param data |
---|
| 529 | * @param offset |
---|
| 530 | * @param nevents |
---|
| 531 | */ |
---|
| 532 | void |
---|
| 533 | AmdtpTransmitStreamProcessor::encodeMidiPortsSilence(quadlet_t *data, |
---|
| 534 | unsigned int offset, |
---|
| 535 | unsigned int nevents) |
---|
| 536 | { |
---|
| 537 | quadlet_t *target_event; |
---|
| 538 | unsigned int i,j; |
---|
| 539 | |
---|
| 540 | for (i = 0; i < m_nb_midi_ports; i++) { |
---|
| 541 | struct _MIDI_port_cache &p = m_midi_ports.at(i); |
---|
| 542 | |
---|
| 543 | for (j = p.location;j < nevents; j += 8) { |
---|
| 544 | target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); |
---|
| 545 | *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); |
---|
| 546 | } |
---|
| 547 | } |
---|
| 548 | } |
---|
| 549 | |
---|
| 550 | /** |
---|
| 551 | * @brief encodes all midi ports in the cache to events |
---|
| 552 | * @param data |
---|
| 553 | * @param offset |
---|
| 554 | * @param nevents |
---|
| 555 | */ |
---|
| 556 | void |
---|
| 557 | AmdtpTransmitStreamProcessor::encodeMidiPorts(quadlet_t *data, |
---|
| 558 | unsigned int offset, |
---|
| 559 | unsigned int nevents) |
---|
| 560 | { |
---|
| 561 | quadlet_t *target_event; |
---|
| 562 | unsigned int i,j; |
---|
| 563 | |
---|
| 564 | for (i = 0; i < m_nb_midi_ports; i++) { |
---|
| 565 | struct _MIDI_port_cache &p = m_midi_ports.at(i); |
---|
| 566 | uint32_t *buffer = (quadlet_t *)(p.buffer); |
---|
| 567 | buffer += offset; |
---|
| 568 | |
---|
| 569 | for (j = p.location;j < nevents; j += 8) { |
---|
| 570 | target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); |
---|
| 571 | if ( *buffer & 0xFF000000 ) // we can send a byte |
---|
659 | | float *buffer = (float *)(p.buffer); |
---|
660 | | buffer += offset; |
---|
661 | | |
---|
662 | | for (j = 0;j < nevents; j += 1) // decode max nsamples |
---|
663 | | { |
---|
664 | | // don't care for overflow |
---|
665 | | float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; |
---|
666 | | unsigned int tmp = ((int) v); |
---|
667 | | *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); |
---|
668 | | buffer++; |
---|
669 | | target_event += m_dimension; |
---|
670 | | } |
---|
| 573 | quadlet_t tmpval; |
---|
| 574 | tmpval = ((*buffer)<<16) & 0x00FF0000; |
---|
| 575 | tmpval = IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); |
---|
| 576 | *target_event = htonl(tmpval); |
---|
| 577 | |
---|
| 578 | // debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", |
---|
| 579 | // p->getName().c_str(), position, location, nevents, m_dimension ); |
---|
| 580 | // debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", |
---|
| 581 | // data, target_event, tmpval ); |
---|
| 582 | } else { |
---|
| 583 | // can't send a byte, either because there is no byte, |
---|
| 584 | // or because this would exceed the maximum rate |
---|
| 585 | // FIXME: this can be ifdef optimized since it's a constant |
---|
| 586 | *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); |
---|
| 662 | for(PortVectorIterator it = m_Ports.begin(); |
---|
| 663 | it != m_Ports.end(); |
---|
| 664 | ++it ) |
---|
| 665 | { |
---|
| 666 | AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); |
---|
| 667 | debugOutput(DEBUG_LEVEL_VERBOSE, "idx %u: looking at port %s at position %u, location %u\n", |
---|
| 668 | idx, (*it)->getName().c_str(), pinfo->getPosition(), pinfo->getLocation()); |
---|
| 669 | if ((*it)->getPortType() == Port::E_Midi) { |
---|
| 670 | struct _MIDI_port_cache p; |
---|
| 671 | p.port = dynamic_cast<AmdtpMidiPort *>(*it); |
---|
| 672 | if(p.port == NULL) { |
---|
| 673 | debugError("Port is not an AmdtpMidiPort!\n"); |
---|
| 674 | return false; |
---|
| 675 | } |
---|
| 676 | p.position = pinfo->getPosition(); |
---|
| 677 | p.location = pinfo->getLocation(); |
---|
| 678 | p.buffer = NULL; // to be filled by updatePortCache |
---|
| 679 | #ifdef DEBUG |
---|
| 680 | p.buffer_size = (*it)->getBufferSize(); |
---|
| 681 | #endif |
---|
| 682 | |
---|
| 683 | m_midi_ports.push_back(p); |
---|
| 684 | debugOutput(DEBUG_LEVEL_VERBOSE, "Cached port %s at position %u, location %u\n", |
---|
| 685 | p.port->getName().c_str(), p.position, p.location); |
---|
| 686 | } |
---|
| 687 | } |
---|
| 688 | |
---|