// File: /workspace/github_cpp_makefile_star2_O2/ke6jjj[P]r-dat/AudioFrameReceiver.cc
// Function: AudioFrameReceiver::ReceiveFrame(Track const&, Track const&)
void
AudioFrameReceiver::ReceiveFrame(const Track& a, const Track& b)
{
  const uint8_t *item;
  uint32_t absoluteFrame = 0;

  printf("\n");

  //
  // Examine the Absolute Time subcode.
  //
  if (a.GetSubcode(2, &item)) {
    TimeCode time(item);
    absoluteFrame = time.AbsoluteFrame();
    printf("Absolute time: %02dh-%02dm-%02ds-%02df (%d)\n",
      time.Hour(),
      time.Minute(),
      time.Second(),
      time.Frame(),
      absoluteFrame
    );
    uint16_t program = time.Program();
    switch (program) {
    case TimeCode::PROGRAM_NOT_VALID:
      break;
    case TimeCode::PROGRAM_LEAD_IN:
    case TimeCode::PROGRAM_LEAD_OUT:
      printf("Program ID   : (%s)\n",
             program == TimeCode::PROGRAM_LEAD_IN ? "LEAD IN" : "LEAD_OUT");
      break;
    default:
      printf("Program ID   : %03d\n", program);
      break;
    }
    uint8_t index = time.Index();
    switch (index) {
    case TimeCode::INDEX_NOT_VALID:
      break;
    default:
      printf("Index ID     : %03d\n", index);
      break;
    }
  }
  
  //
  // If the absolute frame number is corrupted or the universal "I don't know"
  // value of 100h-100m-100s-100f (12203433), then display a session-psuedo
  // frame.
  //
  if (absoluteFrame == 0 || absoluteFrame == 12203433) {
    TimeCode time(static_cast<uint32_t>(mNextSessionFrameNumber));
    printf("Psuedo   time: %02dh-%02dm-%02ds-%02df (%d)\n",
      time.Hour(),
      time.Minute(),
      time.Second(),
      time.Frame(),
      mNextSessionFrameNumber
    );
    absoluteFrame = mNextSessionFrameNumber;
  }

  uint8_t control_id;
  if (a.GetControlID(control_id) && control_id != 0) {
    printf("Control      :");
    if (control_id & 0x1)
      // TOC ID
      printf(" TOC");
    if (control_id & 0x2)
      // Shortening ID
      printf(" SKIP");
    if (control_id & 0x4)
      // Start ID
      printf(" START");
    if (control_id & 0x8)
      printf(" PRIORITY");
    printf("\n");
  }
  
  //
  // Examine Program Time subcode.
  //
  if (a.GetSubcode(1, &item)) {
    TimeCode time(item);
    printf("Program time : %02dh-%02dm-%02ds-%02df\n",
      time.Hour(),
      time.Minute(),
      time.Second(),
      time.Frame()
    );
  }
    
  //
  // Examine Running Time / Pro R time.
  //
  if (a.GetSubcode(3, &item)) {
    TimeCode time(item);
    if (item[0] & 0x4) {
      //
      // Running Time.
      //
      printf("Running time : %02dh-%02dm-%02ds-%02df\n",
        time.Hour(),
        time.Minute(),
        time.Second(),
        time.Frame()
      );
    } else {
      //
      // Pro R Time
      //
      uint8_t sid = (item[0] & 3);
      uint8_t freq = (item[1] & 0xC0) >> 6;
      uint8_t xrate = (item[1] & 0x38) >> 3;
      uint8_t msb = (item[1] & 0x07);
      uint8_t lsb = item[2];
      const char *code_type;
      switch (sid) {
      case 0:
        code_type = "IEC/SMPTE";
        break;
      case 1:
        code_type = "Pro DIO; sample address";
        break;
      case 2:
        code_type = "Pro DIO; Time-of-day";
        break;
      case 3:
        code_type = "Reserved-3";
        break;
      default:
        code_type = "?";
        break;
      }
      const char *freq_str;
      switch (freq) {
      case 0:
        freq_str = "48 kHz";
        break;
      case 1:
        freq_str = "44.1 kHz";
        break;
      case 2:
        freq_str = "32 kHz";
        break;
      case 3:
        freq_str = "Reserved-3";
        break;
      default:
        freq_str = "?";
        break;
      }
      const char *smpte_xrate;
      switch (xrate) {
      case 0:
        smpte_xrate = "30 Hz";
        break;
      case 1:
        smpte_xrate = "29.97 Hz NDF";
        break;
      case 2:
        smpte_xrate = "29.97 Hz DF";
        break;
      case 3:
        smpte_xrate = "25 Hz";
        break;
      case 4:
        smpte_xrate = "24 Hz";
        break;
      case 5:
        smpte_xrate = "Reserved-5";
        break;
      case 6:
        smpte_xrate = "Reserved-6";
        break;
      case 7:
        smpte_xrate = "Reserved-7";
        break;
      default:
        smpte_xrate = "?";
        break;
      }
      printf("Pro R Time   : %02dh-%02dm-%02ds-%02df (%s-%s-%s)\n",
        time.Hour(),
        time.Minute(),
        time.Second(),
        time.Frame(),
        code_type,
        freq_str,
        smpte_xrate
      );
    }
  }

  //
  // Examine Table of Contents subcode.
  //
  if (a.GetSubcode(4, &item)) {
    printf("Table of Cont:\n");
    TimeCode time(item);
    uint16_t program = time.Program();
    switch (program) {
    case TimeCode::PROGRAM_NOT_VALID:
      break;
    case TimeCode::PROGRAM_LEAD_IN:
    case TimeCode::PROGRAM_LEAD_OUT:
      printf("  Program ID : (%s)\n",
             program == TimeCode::PROGRAM_LEAD_IN ? "LEAD IN" : "LEAD_OUT");
      break;
    default:
      printf("  Program ID : %03d\n", program);
      break;
    }
    uint8_t index = time.Index();
    switch (index) {
    case TimeCode::INDEX_NOT_VALID:
      break;
    default:
      printf("  Index ID   : %03d\n", index);
      break;
    }
    printf("  Time       : %02dh-%02dm-%02ds-%02df\n",
      time.Hour(),
      time.Minute(),
      time.Second(),
      time.Frame()
    );
  }

  //
  // Examine the Date & Time subcode.
  //
  if (a.GetSubcode(5, &item))
    HandleDateTime(item, absoluteFrame);
  else
    HandleDateTime(NULL, absoluteFrame);

  //
  // Examine Catalog Number subcode.
  //
  if (a.GetSubcode(6, &item)) {
  }

  //
  // Examine ISRC subcode.
  //
  if (a.GetSubcode(7, &item)) {
    printf("ISRC         : (not yet)\n");
  }

  //
  // Examine Pro Binary subcode.
  //
  if (a.GetSubcode(8, &item)) {
    printf("Pro Binary   : (not yet)\n");
  }

  //
  // Print the sub-code signature.
  //
  const Track::SubcodeSignatureArray& signature = a.SubcodeSignature();
  printf("Subcode packs:");
  for (size_t i = 0; i < 7; i++)
    printf(" %-2d", signature[i]);
  putchar('\n');

  //
  // Fetch and demultiplex all the data from the track pair.
  //
  mFrame.FillFromTrackPair(a, b);
  const DATFrame::DataArray& data = mFrame.Data();

  //
  // Print out error statistics for the frame.
  //
  unsigned int c1_errors = mFrame.C1Errors();
  unsigned int c1_uncorrectable = mFrame.C1UncorrectableErrors();
  unsigned int c1_corrected = c1_errors - c1_uncorrectable;
  unsigned int c2_uncorrectable = mFrame.C2UncorrectableErrors();
  unsigned int c2_corrected = c1_uncorrectable - c2_uncorrectable;

  printf("Errors  C1/C2: %d/%d",
    c1_corrected,
    c2_corrected
  );

  if (c2_uncorrectable > 0)
    printf(" %d UNCORRECTED\n", c2_uncorrectable);
  else
    printf(" (all corrected)\n");
  

  printf("Samples      : L    R\n");
  for (size_t i = 0; i < 8; i++) {
    printf("               %02x%02x %02x%02x\n",
      data[i][1], data[i][0],
      data[i][3], data[i][2]
    );
  }

  //
  // Ensure that everything printed so far is immediately visible.
  //
  fflush(stdout);

  //
  // Dump samples to file, if asked.
  //
  if (mFile != NULL) {
    for (size_t i = 0; i < DATFrame::kUserDataRows; i++) {
      fwrite(data[i], DATFrame::kBytesPerRow, 1, mFile);
    }
    mFramesWritten += DATFrame::kUserDataRows;
  }

  mHaveLastAbsoluteFrameNumber = true;
  mLastAbsoluteFrameNumber = absoluteFrame;
  mNextSessionFrameNumber++;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdx, 0x40(%rsp)
movq %rsi, %r15
movq %rdi, %rbx
pushq $0xa
popq %rdi
callq 0x2180
pushq $0x2
popq %rsi
leaq 0x18(%rsp), %rdx
movq %r15, %rdi
callq 0x343e
testb %al, %al
je 0x3b9d
movq 0x18(%rsp), %rsi
leaq 0xe(%rsp), %r14
movq %r14, %rdi
callq 0x75b0
movq %r14, %rdi
callq 0x76d8
movl %eax, %r13d
leaq 0xe(%rsp), %rdi
callq 0x76c8
movl %eax, %r12d
leaq 0xe(%rsp), %rdi
callq 0x76cc
movl %eax, %r14d
leaq 0xe(%rsp), %rdi
callq 0x76d0
movl %eax, %ebp
leaq 0xe(%rsp), %rdi
callq 0x76d4
movzbl %r12b, %esi
movzbl %r14b, %edx
movzbl %bpl, %ecx
movzbl %al, %r8d
leaq 0x50ea(%rip), %rdi      # 0x8bf9
movl %r13d, %r9d
xorl %eax, %eax
callq 0x2040
leaq 0xe(%rsp), %rdi
callq 0x76c0
cmpw $0x80aa, %ax            # imm = 0x80AA
je 0x3b70
movzwl %ax, %esi
cmpl $0x80bb, %esi           # imm = 0x80BB
je 0x3b3c
cmpl $0x80ee, %esi           # imm = 0x80EE
jne 0x3b62
cmpw $0x80bb, %ax            # imm = 0x80BB
leaq 0x50f4(%rip), %rax      # 0x8c3b
leaq 0x50f5(%rip), %rsi      # 0x8c43
cmoveq %rax, %rsi
leaq 0x50cd(%rip), %rdi      # 0x8c26
xorl %eax, %eax
callq 0x2040
jmp 0x3b70
leaq 0x50e3(%rip), %rdi      # 0x8c4c
xorl %eax, %eax
callq 0x2040
leaq 0xe(%rsp), %rdi
callq 0x76c4
cmpb $-0x56, %al
je 0x3b8f
movzbl %al, %esi
leaq 0x50d9(%rip), %rdi      # 0x8c61
xorl %eax, %eax
callq 0x2040
cmpl $0xba35a9, %r13d        # imm = 0xBA35A9
je 0x3b9d
testl %r13d, %r13d
jne 0x3c03
movl 0x2db8(%rbx), %esi
leaq 0xe(%rsp), %r14
movq %r14, %rdi
callq 0x7652
movq %r14, %rdi
callq 0x76c8
movzbl %al, %ebp
movq %r14, %rdi
callq 0x76cc
movzbl %al, %r12d
movq %r14, %rdi
callq 0x76d0
movl %eax, %r13d
movq %r14, %rdi
callq 0x76d4
movzbl %r13b, %ecx
movzbl %al, %r8d
movl 0x2db8(%rbx), %r9d
leaq 0x5086(%rip), %rdi      # 0x8c76
movl %ebp, %esi
movl %r12d, %edx
xorl %eax, %eax
callq 0x2040
movl 0x2db8(%rbx), %r13d
leaq 0xd(%rsp), %rsi
movq %r15, %rdi
callq 0x37ea
testb %al, %al
je 0x3c89
cmpb $0x0, 0xd(%rsp)
je 0x3c89
leaq 0x5081(%rip), %rdi      # 0x8ca3
xorl %eax, %eax
callq 0x2040
movb 0xd(%rsp), %al
testb $0x1, %al
je 0x3c43
leaq 0x507a(%rip), %rdi      # 0x8cb2
xorl %eax, %eax
callq 0x2040
movb 0xd(%rsp), %al
testb $0x2, %al
je 0x3c59
leaq 0x5069(%rip), %rdi      # 0x8cb7
xorl %eax, %eax
callq 0x2040
movb 0xd(%rsp), %al
testb $0x4, %al
je 0x3c6f
leaq 0x5059(%rip), %rdi      # 0x8cbd
xorl %eax, %eax
callq 0x2040
movb 0xd(%rsp), %al
testb $0x8, %al
je 0x3c81
leaq 0x504a(%rip), %rdi      # 0x8cc4
xorl %eax, %eax
callq 0x2040
pushq $0xa
popq %rdi
callq 0x2180
pushq $0x1
popq %rsi
leaq 0x18(%rsp), %rdx
movq %r15, %rdi
callq 0x343e
testb %al, %al
je 0x3cfb
movq 0x18(%rsp), %rsi
leaq 0xe(%rsp), %r14
movq %r14, %rdi
callq 0x75b0
movq %r14, %rdi
callq 0x76c8
movl %eax, %r12d
leaq 0xe(%rsp), %rdi
callq 0x76cc
movl %eax, %r14d
leaq 0xe(%rsp), %rdi
callq 0x76d0
movl %eax, %ebp
leaq 0xe(%rsp), %rdi
callq 0x76d4
movzbl %r12b, %esi
movzbl %r14b, %edx
movzbl %bpl, %ecx
movzbl %al, %r8d
leaq 0x4fda(%rip), %rdi      # 0x8cce
xorl %eax, %eax
callq 0x2040
pushq $0x3
popq %rsi
leaq 0x18(%rsp), %rdx
movq %r15, %rdi
callq 0x343e
testb %al, %al
movl %r13d, 0x24(%rsp)
je 0x3e38
movq 0x18(%rsp), %rsi
leaq 0xe(%rsp), %rdi
callq 0x75b0
movq 0x18(%rsp), %rcx
movzbl (%rcx), %eax
testb $0x4, %al
jne 0x3dea
andl $0x3, %eax
movzbl 0x1(%rcx), %ecx
leaq 0x536b(%rip), %r12      # 0x90b0
movslq (%r12,%rax,4), %rax
movq %rax, 0x38(%rsp)
movl %ecx, %eax
shrl $0x6, %eax
leaq 0x5386(%rip), %r13      # 0x90e0
movslq (%r13,%rax,4), %rax
movq %rax, 0x30(%rsp)
shrl %ecx
andl $0x1c, %ecx
leaq 0x5350(%rip), %r14      # 0x90c0
movslq (%rcx,%r14), %rax
movq %rax, 0x28(%rsp)
leaq 0xe(%rsp), %rdi
callq 0x76c8
movb %al, 0x17(%rsp)
leaq 0xe(%rsp), %rdi
callq 0x76cc
movb %al, 0x16(%rsp)
leaq 0xe(%rsp), %rdi
callq 0x76d0
movl %eax, %ebp
leaq 0xe(%rsp), %rdi
callq 0x76d4
addq 0x38(%rsp), %r12
addq 0x30(%rsp), %r13
addq 0x28(%rsp), %r14
movzbl 0x17(%rsp), %esi
movzbl 0x16(%rsp), %edx
movzbl %bpl, %ecx
movzbl %al, %r8d
leaq 0x4ff0(%rip), %rdi      # 0x8dc3
movq %r12, %r9
xorl %eax, %eax
pushq %r14
pushq %r13
callq 0x2040
popq %rcx
popq %rdx
movl 0x24(%rsp), %r13d
jmp 0x3e38
leaq 0xe(%rsp), %rdi
callq 0x76c8
movl %eax, %r12d
leaq 0xe(%rsp), %rdi
callq 0x76cc
movl %eax, %r14d
leaq 0xe(%rsp), %rdi
callq 0x76d0
movl %eax, %ebp
leaq 0xe(%rsp), %rdi
callq 0x76d4
movzbl %r12b, %esi
movzbl %r14b, %edx
movzbl %bpl, %ecx
movzbl %al, %r8d
leaq 0x4ec5(%rip), %rdi      # 0x8cf6
xorl %eax, %eax
callq 0x2040
pushq $0x4
popq %rsi
leaq 0x18(%rsp), %rdx
movq %r15, %rdi
callq 0x343e
testb %al, %al
je 0x3f30
leaq 0x50ee(%rip), %rdi      # 0x8f45
callq 0x21c0
movq 0x18(%rsp), %rsi
leaq 0xe(%rsp), %r14
movq %r14, %rdi
callq 0x75b0
movq %r14, %rdi
callq 0x76c0
cmpw $0x80aa, %ax            # imm = 0x80AA
je 0x3ec3
movzwl %ax, %esi
cmpl $0x80bb, %esi           # imm = 0x80BB
je 0x3e8f
cmpl $0x80ee, %esi           # imm = 0x80EE
jne 0x3eb5
cmpw $0x80bb, %ax            # imm = 0x80BB
leaq 0x4da1(%rip), %rax      # 0x8c3b
leaq 0x4da2(%rip), %rsi      # 0x8c43
cmoveq %rax, %rsi
leaq 0x4f4a(%rip), %rdi      # 0x8df6
xorl %eax, %eax
callq 0x2040
jmp 0x3ec3
leaq 0x4f4f(%rip), %rdi      # 0x8e0b
xorl %eax, %eax
callq 0x2040
leaq 0xe(%rsp), %rdi
callq 0x76c4
cmpb $-0x56, %al
je 0x3ee2
movzbl %al, %esi
leaq 0x4f45(%rip), %rdi      # 0x8e20
xorl %eax, %eax
callq 0x2040
leaq 0xe(%rsp), %rdi
callq 0x76c8
movl %eax, %r12d
leaq 0xe(%rsp), %rdi
callq 0x76cc
movl %eax, %r14d
leaq 0xe(%rsp), %rdi
callq 0x76d0
movl %eax, %ebp
leaq 0xe(%rsp), %rdi
callq 0x76d4
movzbl %r12b, %esi
movzbl %r14b, %edx
movzbl %bpl, %ecx
movzbl %al, %r8d
leaq 0x4f0c(%rip), %rdi      # 0x8e35
xorl %eax, %eax
callq 0x2040
pushq $0x5
popq %rsi
leaq 0x18(%rsp), %r12
movq %r15, %rdi
movq %r12, %rdx
callq 0x343e
testb %al, %al
je 0x3f4e
movq 0x18(%rsp), %rsi
jmp 0x3f50
xorl %esi, %esi
movq %rbx, %rdi
movl %r13d, %edx
callq 0x4136
pushq $0x6
popq %rsi
movq %r15, %rdi
movq %r12, %rdx
callq 0x343e
pushq $0x7
popq %rsi
movq %r15, %rdi
movq %r12, %rdx
callq 0x343e
testb %al, %al
je 0x3f87
leaq 0x4fd2(%rip), %rdi      # 0x8f54
callq 0x21c0
pushq $0x8
popq %rsi
leaq 0x18(%rsp), %rdx
movq %r15, %rdi
callq 0x343e
testb %al, %al
je 0x3fa7
leaq 0x4fcb(%rip), %rdi      # 0x8f6d
callq 0x21c0
movq %r15, %rdi
callq 0x3490
movq %rax, %r14
leaq 0x4ea4(%rip), %rdi      # 0x8e5d
xorl %eax, %eax
callq 0x2040
leaq 0x4ea5(%rip), %r12      # 0x8e6c
xorl %r13d, %r13d
cmpq $0x7, %r13
je 0x3fe4
movzbl (%r14,%r13), %esi
movq %r12, %rdi
xorl %eax, %eax
callq 0x2040
incq %r13
jmp 0x3fca
pushq $0xa
popq %rdi
callq 0x2180
leaq 0x18(%rbx), %r12
movq %r12, %rdi
movq %r15, %rsi
movq 0x40(%rsp), %rdx
callq 0x5792
movq %r12, %rdi
callq 0x5976
movq %rax, %r14
movq %r12, %rdi
callq 0x599a
movq %rax, %r13
movq %r12, %rdi
callq 0x59a2
movq %rax, %rbp
subl %ebp, %r13d
movq %r12, %rdi
callq 0x59aa
movq %rax, %r15
subl %r15d, %ebp
leaq 0x4e39(%rip), %rdi      # 0x8e72
movl %r13d, %esi
movl %ebp, %edx
xorl %eax, %eax
callq 0x2040
testl %r15d, %r15d
je 0x405d
leaq 0x4e36(%rip), %rdi      # 0x8e87
movl %r15d, %esi
xorl %eax, %eax
callq 0x2040
jmp 0x4069
leaq 0x4f22(%rip), %rdi      # 0x8f86
callq 0x21c0
movl 0x24(%rsp), %ebp
leaq 0x4f23(%rip), %rdi      # 0x8f97
callq 0x21c0
leaq 0x4e18(%rip), %r15      # 0x8e98
xorl %r12d, %r12d
cmpq $0x8, %r12
je 0x40af
movzbl 0x1(%r14,%r12,4), %esi
movzbl (%r14,%r12,4), %edx
movzbl 0x3(%r14,%r12,4), %ecx
movzbl 0x2(%r14,%r12,4), %r8d
movq %r15, %rdi
xorl %eax, %eax
callq 0x2040
incq %r12
jmp 0x4083
movq 0xaf0a(%rip), %rax      # 0xefc0
movq (%rax), %rdi
callq 0x2120
cmpq $0x0, 0x8(%rbx)
je 0x40fe
xorl %r13d, %r13d
pushq $0x4
popq %r15
pushq $0x1
popq %r12
cmpq $0x1680, %r13           # imm = 0x1680
je 0x40f2
leaq (%r14,%r13), %rdi
movq 0x8(%rbx), %rcx
movq %r15, %rsi
movq %r12, %rdx
callq 0x2200
addq $0x4, %r13
jmp 0x40d0
addq $0x5a0, 0x10(%rbx)      # imm = 0x5A0
movl 0x24(%rsp), %ebp
movb $0x1, 0x2db0(%rbx)
movl %ebp, 0x2db4(%rbx)
incl 0x2db8(%rbx)
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x412e
jmp 0x412e
jmp 0x412e
jmp 0x412e
jmp 0x412e
jmp 0x412e
jmp 0x412e
movq %rax, %rdi
callq 0x21e0