// File: /workspace/github_cpp_makefile_star2_O3/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, 0x18(%rsp)
leaq 0x6bd6(%rip), %r13      # 0x9008
movq %rax, 0x20(%rsp)
movq $0x0, 0x10(%rsp)
movq $0x0, 0x28(%rsp)
xorl %ebx, %ebx
xorl %r15d, %r15d
xorl %r14d, %r14d
movl %r14d, %ecx
movl %ecx, %r14d
movl %ebp, %edi
movq %r12, %rsi
movq %r13, %rdx
callq 0x2050
movb $0x1, %cl
cmpl $0x72, %eax
je 0x2454
cmpl $0x65, %eax
jg 0x248b
cmpl $-0x1, %eax
je 0x24fa
cmpl $0x61, %eax
je 0x24bf
cmpl $0x64, %eax
jne 0x27bc
movb $0x1, %bl
jmp 0x2451
cmpl $0x66, %eax
je 0x24df
cmpl $0x6f, %eax
je 0x24c4
cmpl $0x73, %eax
jne 0x27bc
movq 0xdb2b(%rip), %rax      # 0xffd0
movq (%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2070
movq %rax, 0x20(%rsp)
movb $0x1, %al
movq %rax, 0x10(%rsp)
jmp 0x2451
movb $0x1, %r15b
jmp 0x2451
movq 0xdb05(%rip), %rax      # 0xffd0
movq (%rax), %rax
movq %rax, 0x8(%rsp)
movb $0x1, %al
movq %rax, 0x18(%rsp)
jmp 0x2451
movq 0xdaea(%rip), %rax      # 0xffd0
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movb $0x1, %al
movq %rax, 0x28(%rsp)
jmp 0x2451
testb $0x1, %r14b
je 0x2517
testb $0x1, %bl
movq 0x18(%rsp), %r13
movq 0x10(%rsp), %rbp
jne 0x252e
testb $0x1, %r15b
je 0x2536
jmp 0x252e
testb $0x1, %r15b
movq 0x18(%rsp), %r13
movq 0x10(%rsp), %rbp
je 0x2536
movb $0x1, %al
testb $0x1, %bl
je 0x2551
movq %r12, %rdi
callq 0x22cf
testb $0x1, %r13b
je 0x254c
testb $0x1, %bl
je 0x27cc
movb $0x1, %r13b
xorl %eax, %eax
jmp 0x2551
xorl %eax, %eax
xorl %r13d, %r13d
movl %ebp, %ecx
notb %cl
orb %bl, %cl
testb $0x1, %cl
je 0x27c4
movl %ebp, %ecx
orb %bl, %cl
orb %bl, %r15b
orb %r14b, %r15b
xorb $0x1, %r15b
orb %r14b, %r15b
movl %r15d, %edx
notb %dl
movzbl %dl, %edx
andl $0x1, %edx
movzbl %cl, %ebx
andl $0x1, %ebx
incl %ebx
testb %al, %al
cmovnel %edx, %ebx
testb $0x1, %r15b
cmovnel %edx, %ebx
leaq 0x38(%rsp), %rdi
callq 0x6728
testb $0x1, 0x28(%rsp)
je 0x25c4
leaq 0x38(%rsp), %rdi
movl $0x4, %edx
movq 0x30(%rsp), %r14
movq %r14, %rsi
callq 0x6776
testb %al, %al
jne 0x25d5
movq %r14, %rdi
callq 0x2287
leaq 0x38(%rsp), %rdi
movl $0x4, %edx
xorl %esi, %esi
callq 0x6802
cmpl $0x2, %ebx
je 0x2615
cmpl $0x1, %ebx
jne 0x2652
movl $0x2de0, %edi           # imm = 0x2DE0
callq 0x20e0
movq %rax, %r14
movq %rax, %rdi
callq 0x3a88
testb $0x1, %r13b
je 0x2655
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x48da
testb %al, %al
jne 0x2655
movq 0x8(%rsp), %rdi
callq 0x22ab
movl $0x30, %edi
callq 0x20e0
movq %rax, %r14
movq %rax, %rdi
callq 0x493c
testb $0x1, %r13b
je 0x263d
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x49ba
testb $0x1, %bpl
je 0x2655
movq %r14, %rdi
movq 0x20(%rsp), %rsi
callq 0x49e2
jmp 0x2655
xorl %r14d, %r14d
testb $0x1, %r15b
je 0x2679
movl $0xa8, %edi
callq 0x20e0
movq %rax, %rbx
movq %rax, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x2cfc
jmp 0x26ab
movl $0x30, %edi
callq 0x20e0
movq %rax, %r15
movq %rax, %rdi
movq %r14, %rsi
callq 0x2f9c
movl $0xa8, %edi
callq 0x20e0
movq %rax, %rbx
movq %rax, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x2cfc
movl $0x40, %edi
callq 0x20e0
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2be4
movl $0x58, %edi
callq 0x20e0
movq %rax, %r12
movss 0x692c(%rip), %xmm0     # 0x9004
movq %rax, %rdi
callq 0x2870
movq %r12, %rdi
movq %r15, %rsi
callq 0x298a
movb $0x1, 0xda2f(%rip)      # 0x10121
leaq 0xd23f(%rip), %rsi      # 0xf938
leaq 0x58(%rsp), %r13
movl $0x98, %edx
movq %r13, %rdi
callq 0x20c0
movl $0x2, %edi
movq %r13, %rsi
xorl %edx, %edx
callq 0x2150
leaq 0x38(%rsp), %r13
leaq 0xf0(%rsp), %rbp
movb 0xd9f4(%rip), %al       # 0x10121
cmpb $0x1, %al
jne 0x2756
movl $0x3e8, %edx            # imm = 0x3E8
movq %r13, %rdi
movq %rbp, %rsi
callq 0x684c
testq %rax, %rax
je 0x2756
movq %r12, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x2990
jmp 0x2727
movq %r12, %rdi
callq 0x2b02
leaq 0x38(%rsp), %rdi
callq 0x6760
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *0x38(%rax)
movq %rbx, %rdi
callq 0x2d20
movl $0xa8, %esi
movq %rbx, %rdi
callq 0x20f0
testq %r14, %r14
je 0x279e
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
leaq 0x38(%rsp), %rdi
callq 0x6734
xorl %eax, %eax
addq $0x1098, %rsp           # imm = 0x1098
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r12, %rdi
callq 0x22f3
movq %r12, %rdi
callq 0x2248
movq %r12, %rdi
callq 0x2220
movq %rax, %r13
movl $0x30, %esi
jmp 0x27e6
movq %rax, %r13
movl $0x2de0, %esi           # imm = 0x2DE0
movq %r14, %rdi
jmp 0x2820
jmp 0x27f7
movq %rax, %r13
movl $0x30, %esi
jmp 0x281d
movq %rax, %r13
movl $0xa8, %esi
movq %rbx, %rdi
jmp 0x2820
jmp 0x282d
jmp 0x282d
movq %rax, %r13
movl $0x58, %esi
movq %r12, %rdi
jmp 0x2820
movq %rax, %r13
movl $0x40, %esi
movq %r15, %rdi
callq 0x20f0
jmp 0x2830
jmp 0x282d
jmp 0x282d
jmp 0x282d
movq %rax, %r13
leaq 0x38(%rsp), %rdi
callq 0x6734
movq %r13, %rdi
callq 0x21d0