// File: /workspace/github_cpp_makefile_star2_O2/ke6jjj[P]r-dat/main.cc
// Function: main
int
main(int argc, char *argv[])
{
  float buf[SAMPLES_PER_READ];
  size_t nread;
  bool do_raw = false;
  bool do_dat = false;
  bool do_dds = false;
  bool do_file = false;
  bool do_output = false;
  bool do_dds_session = false;
  enum { DECODE_RAW, DECODE_DAT, DECODE_DDS } decode_mode = DECODE_DAT;
  int c;
  const char *filename, *outfile;
  unsigned int dds_session;

  while ((c = getopt(argc, argv, "hdraf:o:s:")) != -1) {
    switch (c) {
    default:
    case 'h':
      usage(argv[0]);
      break;
    case 'd':
      do_dds = true;
      break;
    case 'r':
      do_raw = true;
      break;
    case 'a':
      do_dat = true;
      break;
    case 'f':
      do_file = true;
      filename = optarg;
      break;
    case 'o':
      do_output = true;
      outfile = optarg;
      break;
    case 's':
      do_dds_session = true;
      dds_session = strtoul(optarg, NULL, 0);
      break;
    }
  }

  //
  // Only one decode mode allowed.
  //
  if ((do_raw && (do_dds || do_dat)) || (do_dat && do_dds)) {
    usage(argv[0]);
  }

  //
  // Can only do output if DAT or DDS is selected.
  //
  if (do_output && !do_dat && !do_dds) {
    fprintf(stderr, "Can't dump result unless doing DAT audio or DDS.\n");
    usage(argv[0]);
  }
  
  //
  // Can only do DDS session if DDS is selected.
  //
  if (do_dds_session && !do_dds) {
    fprintf(stderr, "DDS session number is only valid for DDS.\n");
    usage(argv[0]);
  }

  //
  // Default to DAT if no choice specified.
  //
  if (!do_raw && !do_dds && !do_dat)
    do_raw = true;

  if (do_raw)
    decode_mode = DECODE_RAW;
  else if (do_dat)
    decode_mode = DECODE_DAT;
  else if (do_dds)
    decode_mode = DECODE_DDS;

  File in;

  if (do_file) {
    if (!in.Open(filename, sizeof(float)))  {
      fprintf(stderr, "Can't open file '%s'.\n", filename);
      exit(1);
    }
  } else {
    in.Open(STDIN_FILENO, sizeof(float));
  }

  RDATDecoder      *decoder;
  NRZISyncDeframer *deframer;
  DATWordReceiver  *blocker;
  DATTrackFramer   *tracker = NULL;
  DATFrameReceiver *streamer = NULL;

  switch (decode_mode) {
  case DECODE_DAT:
    {
    AudioFrameReceiver *audio = new AudioFrameReceiver();
    if (do_output) {
      if (!audio->SetDumpFile(outfile)) {
        fprintf(stderr, "Can't dump to output file '%s'.\n", outfile);
        exit(1);
      }
    }
    // Cast receiver to generic base class for rest of code.
    streamer = audio;
    }
    break;
  case DECODE_DDS:
    {
    DDSFrameReceiver *dds = new DDSFrameReceiver();
    if (do_output) {
      dds->DumpToDirectory(outfile);
    }
    if (do_dds_session) {
      dds->DumpSession(dds_session);
    }
    streamer = dds;
    }
    break;
  default:
    break;
  }

  if (decode_mode == DECODE_RAW) {
    blocker = new DATWordReceiver(NULL, true);
  } else {
    tracker = new DATTrackFramer(*streamer);
    blocker = new DATWordReceiver(tracker, false);
  }
    
  deframer = new NRZISyncDeframer(blocker);
  decoder = new RDATDecoder(9408000.0 * 8);
  decoder->SetSymbolDecoder(deframer);

  running = true;

  //
  // Install the sigint handler so that the user can stop the
  // processing safely.
  //
  struct sigaction int_handler = { .sa_handler = sigint_handler };
  ::sigaction(SIGINT, &int_handler, NULL);

  while (running) {
    nread = in.Read(buf, SAMPLES_PER_READ);
    if (nread == 0)
      break;
    decoder->Process(buf, nread);
  }

  decoder->Stop();

  in.Close();
  
  delete decoder;
  delete deframer;
  delete blocker;
  delete streamer;

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1098, %rsp           # imm = 0x1098
movq %rsi, %r12
movl %edi, %ebp
movq $0x0, 0x10(%rsp)
leaq 0x5cc6(%rip), %r13      # 0x8008
movq %rax, 0x20(%rsp)
movq $0x0, 0x18(%rsp)
movq $0x0, 0x28(%rsp)
xorl %ebx, %ebx
xorl %r14d, %r14d
xorl %r15d, %r15d
movl %r15d, %ecx
movl %ecx, %r15d
movl %ebp, %edi
movq %r12, %rsi
movq %r13, %rdx
callq 0x2050
movb $0x1, %cl
cmpl $0x72, %eax
je 0x2364
cmpl $-0x1, %eax
je 0x23fa
cmpl $0x61, %eax
je 0x23c2
cmpl $0x64, %eax
je 0x23be
cmpl $0x66, %eax
je 0x23c7
cmpl $0x6f, %eax
je 0x23df
cmpl $0x73, %eax
jne 0x2700
movq 0xcc2c(%rip), %rax      # 0xefd0
movq (%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2070
movq %rax, 0x20(%rsp)
movb $0x1, %al
movq %rax, 0x18(%rsp)
jmp 0x2361
movb $0x1, %bl
jmp 0x2361
movb $0x1, %r14b
jmp 0x2361
movq 0xcc02(%rip), %rax      # 0xefd0
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movb $0x1, %al
movq %rax, 0x28(%rsp)
jmp 0x2361
movq 0xcbea(%rip), %rax      # 0xefd0
movq (%rax), %rax
movq %rax, 0x8(%rsp)
movb $0x1, %al
movq %rax, 0x10(%rsp)
jmp 0x2361
testb $0x1, %r15b
je 0x2419
testb $0x1, %bl
movq 0x10(%rsp), %r13
jne 0x2700
testb $0x1, %r14b
je 0x2430
jmp 0x2700
testb $0x1, %r14b
movq 0x10(%rsp), %r13
je 0x2430
movb $0x1, %al
testb $0x1, %bl
je 0x2432
jmp 0x2700
xorl %eax, %eax
movl %r13d, %ecx
notb %cl
orb %al, %cl
testb $0x1, %cl
jne 0x2447
testb $0x1, %bl
je 0x26cf
testb $0x1, 0x18(%rsp)
je 0x2457
testb $0x1, %bl
je 0x26e4
movl %r15d, %ebp
orb %bl, %bpl
orb %al, %bpl
xorb $0x1, %bpl
orb %r15b, %bpl
movl %ebp, %ecx
notb %cl
movzbl %cl, %ecx
andl $0x1, %ecx
movzbl %bl, %ebx
andl $0x1, %ebx
incl %ebx
testb $0x1, %al
cmovnel %ecx, %ebx
testb $0x1, %bpl
cmovnel %ecx, %ebx
leaq 0x38(%rsp), %rdi
callq 0x6508
testb $0x1, 0x28(%rsp)
je 0x24c5
leaq 0x38(%rsp), %rdi
pushq $0x4
popq %rdx
movq 0x30(%rsp), %r14
movq %r14, %rsi
callq 0x6550
testb %al, %al
jne 0x24d4
movq 0xcb2a(%rip), %rax      # 0xefe0
movq (%rax), %rdi
leaq 0x5bb0(%rip), %rsi      # 0x8070
movq %r14, %rdx
jmp 0x2524
leaq 0x38(%rsp), %rdi
pushq $0x4
popq %rdx
xorl %esi, %esi
callq 0x65c0
cmpl $0x2, %ebx
je 0x2533
cmpl $0x1, %ebx
jne 0x256f
movl $0x2de0, %edi           # imm = 0x2DE0
callq 0x20e0
movq %rax, %r14
movq %rax, %rdi
callq 0x38f8
testb $0x1, %r13b
je 0x2572
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x474e
testb %al, %al
jne 0x2572
movq 0xcacb(%rip), %rax      # 0xefe0
movq (%rax), %rdi
leaq 0x5b68(%rip), %rsi      # 0x8087
movq 0x8(%rsp), %rdx
xorl %eax, %eax
callq 0x2190
pushq $0x1
popq %rdi
callq 0x2150
pushq $0x30
popq %rdi
callq 0x20e0
movq %rax, %r14
movq %rax, %rdi
callq 0x47a8
testb $0x1, %r13b
je 0x2559
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x481e
testb $0x1, 0x18(%rsp)
je 0x2572
movq %r14, %rdi
movq 0x20(%rsp), %rsi
callq 0x4846
jmp 0x2572
xorl %r14d, %r14d
testb $0x1, %bpl
je 0x2594
movl $0xa8, %edi
callq 0x20e0
movq %rax, %rbx
pushq $0x1
popq %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x2c04
jmp 0x25c4
pushq $0x30
popq %rdi
callq 0x20e0
movq %rax, %r15
movq %rax, %rdi
movq %r14, %rsi
callq 0x2e44
movl $0xa8, %edi
callq 0x20e0
movq %rax, %rbx
movq %rax, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x2c04
pushq $0x40
popq %rdi
callq 0x20e0
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2af4
pushq $0x58
popq %rdi
callq 0x20e0
movq %rax, %r12
movss 0x5a17(%rip), %xmm0     # 0x8004
movq %rax, %rdi
callq 0x279c
movq %r12, %rdi
movq %r15, %rsi
callq 0x28ae
movb $0x1, 0xcb22(%rip)      # 0xf129
leaq 0xc32a(%rip), %rsi      # 0xe938
leaq 0x58(%rsp), %r13
movl $0x98, %edx
movq %r13, %rdi
callq 0x20c0
pushq $0x2
popq %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x2160
leaq 0x38(%rsp), %r13
leaq 0xf0(%rsp), %rbp
movb 0xcae9(%rip), %al       # 0xf129
cmpb $0x1, %al
jne 0x2669
movl $0x3e8, %edx            # imm = 0x3E8
movq %r13, %rdi
movq %rbp, %rsi
callq 0x65de
testq %rax, %rax
je 0x2669
movq %r12, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x28b4
jmp 0x263a
movq %r12, %rdi
callq 0x2a20
leaq 0x38(%rsp), %rdi
callq 0x653a
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *0x38(%rax)
movq %rbx, %rdi
callq 0x2c28
movl $0xa8, %esi
movq %rbx, %rdi
callq 0x20f0
testq %r14, %r14
je 0x26b1
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
leaq 0x38(%rsp), %rdi
callq 0x6514
xorl %eax, %eax
addq $0x1098, %rsp           # imm = 0x1098
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xc90a(%rip), %rax      # 0xefe0
movq (%rax), %rcx
leaq 0x5933(%rip), %rdi      # 0x8013
pushq $0x31
jmp 0x26f7
movq 0xc8f5(%rip), %rax      # 0xefe0
movq (%rax), %rcx
leaq 0x5950(%rip), %rdi      # 0x8045
pushq $0x2a
popq %rsi
pushq $0x1
popq %rdx
callq 0x2200
movq (%r12), %rdi
callq 0x276e
movq %rax, %r13
pushq $0x30
popq %rsi
jmp 0x2719
movq %rax, %r13
movl $0x2de0, %esi           # imm = 0x2DE0
movq %r14, %rdi
jmp 0x274c
jmp 0x2727
movq %rax, %r13
pushq $0x30
jmp 0x2748
movq %rax, %r13
movl $0xa8, %esi
movq %rbx, %rdi
jmp 0x274c
jmp 0x2759
jmp 0x2759
movq %rax, %r13
pushq $0x58
popq %rsi
movq %r12, %rdi
jmp 0x274c
movq %rax, %r13
pushq $0x40
popq %rsi
movq %r15, %rdi
callq 0x20f0
jmp 0x275c
jmp 0x2759
jmp 0x2759
jmp 0x2759
movq %rax, %r13
leaq 0x38(%rsp), %rdi
callq 0x6514
movq %r13, %rdi
callq 0x21e0