// File: /workspace/github_cpp_makefile_star2_O1/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, 0x28(%rsp)
leaq 0x6bd6(%rip), %r13      # 0x9008
movq %rax, 0x18(%rsp)
movq $0x0, 0x10(%rsp)
movq $0x0, 0x20(%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 0x27a9
movb $0x1, %bl
jmp 0x2451
cmpl $0x66, %eax
je 0x24df
cmpl $0x6f, %eax
je 0x24c4
cmpl $0x73, %eax
jne 0x27a9
movq 0xdb2b(%rip), %rax      # 0xffd0
movq (%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2070
movq %rax, 0x18(%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, 0x28(%rsp)
jmp 0x2451
movq 0xdaea(%rip), %rax      # 0xffd0
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movb $0x1, %al
movq %rax, 0x20(%rsp)
jmp 0x2451
testb $0x1, %r14b
je 0x2513
testb $0x1, %bl
jne 0x27b1
testb $0x1, %r15b
jne 0x27b1
testb $0x1, %r15b
je 0x2522
testb $0x1, %bl
jne 0x27b1
movq 0x28(%rsp), %r13
testb $0x1, %r13b
je 0x253c
testb $0x1, %r15b
jne 0x253c
testb $0x1, %bl
je 0x27b9
testb $0x1, 0x10(%rsp)
je 0x254c
testb $0x1, %bl
je 0x27c1
movl %r15d, %ebp
orb %bl, %bpl
orb %r14b, %bpl
xorb $0x1, %bpl
orb %r14b, %bpl
movl %ebp, %eax
notb %al
movzbl %al, %eax
andl $0x1, %eax
movzbl %bl, %ebx
andl $0x1, %ebx
incl %ebx
testb $0x1, %r15b
cmovnel %eax, %ebx
testb $0x1, %bpl
cmovnel %eax, %ebx
leaq 0x38(%rsp), %rdi
callq 0x6710
testb $0x1, 0x20(%rsp)
je 0x25b0
leaq 0x38(%rsp), %rdi
movl $0x4, %edx
movq 0x30(%rsp), %r14
movq %r14, %rsi
callq 0x6764
testb %al, %al
jne 0x25c1
movq %r14, %rdi
callq 0x2287
leaq 0x38(%rsp), %rdi
movl $0x4, %edx
xorl %esi, %esi
callq 0x67de
cmpl $0x2, %ebx
je 0x2601
cmpl $0x1, %ebx
jne 0x263f
movl $0x2de0, %edi           # imm = 0x2DE0
callq 0x20e0
movq %rax, %r14
movq %rax, %rdi
callq 0x3ab0
testb $0x1, %r13b
je 0x2642
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x488c
testb %al, %al
jne 0x2642
movq 0x8(%rsp), %rdi
callq 0x22ab
movl $0x30, %edi
callq 0x20e0
movq %rax, %r14
movq %rax, %rdi
callq 0x48e8
testb $0x1, %r13b
je 0x2629
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x4966
testb $0x1, 0x10(%rsp)
je 0x2642
movq %r14, %rdi
movq 0x18(%rsp), %rsi
callq 0x498e
jmp 0x2642
xorl %r14d, %r14d
testb $0x1, %bpl
je 0x2666
movl $0xa8, %edi
callq 0x20e0
movq %rax, %rbx
movq %rax, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x2d08
jmp 0x2698
movl $0x30, %edi
callq 0x20e0
movq %rax, %r15
movq %rax, %rdi
movq %r14, %rsi
callq 0x2fa8
movl $0xa8, %edi
callq 0x20e0
movq %rax, %rbx
movq %rax, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x2d08
movl $0x40, %edi
callq 0x20e0
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2bf0
movl $0x58, %edi
callq 0x20e0
movq %rax, %r12
movss 0x693f(%rip), %xmm0     # 0x9004
movq %rax, %rdi
callq 0x2868
movq %r12, %rdi
movq %r15, %rsi
callq 0x2990
movb $0x1, 0xda42(%rip)      # 0x10121
leaq 0xd252(%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 0xda07(%rip), %al       # 0x10121
cmpb $0x1, %al
jne 0x2743
movl $0x3e8, %edx            # imm = 0x3E8
movq %r13, %rdi
movq %rbp, %rsi
callq 0x67fc
testq %rax, %rax
je 0x2743
movq %r12, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x2996
jmp 0x2714
movq %r12, %rdi
callq 0x2b10
leaq 0x38(%rsp), %rdi
callq 0x674e
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *0x38(%rax)
movq %rbx, %rdi
callq 0x2d2c
movl $0xa8, %esi
movq %rbx, %rdi
callq 0x20f0
testq %r14, %r14
je 0x278b
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
leaq 0x38(%rsp), %rdi
callq 0x671c
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 0x22cf
movq %r12, %rdi
callq 0x2220
movq %r12, %rdi
callq 0x2248
movq %rax, %r13
movl $0x30, %esi
jmp 0x27db
movq %rax, %r13
movl $0x2de0, %esi           # imm = 0x2DE0
movq %r14, %rdi
jmp 0x2815
jmp 0x27ec
movq %rax, %r13
movl $0x30, %esi
jmp 0x2812
movq %rax, %r13
movl $0xa8, %esi
movq %rbx, %rdi
jmp 0x2815
jmp 0x2822
jmp 0x2822
movq %rax, %r13
movl $0x58, %esi
movq %r12, %rdi
jmp 0x2815
movq %rax, %r13
movl $0x40, %esi
movq %r15, %rdi
callq 0x20f0
jmp 0x2825
jmp 0x2822
jmp 0x2822
jmp 0x2822
movq %rax, %r13
leaq 0x38(%rsp), %rdi
callq 0x671c
movq %r13, %rdi
callq 0x21d0