/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A source object for AAC audio files in ADTS format
// Implementation

#include "ADTSAudioFileSource.hh"
#include "InputFile.hh"
#include <GroupsockHelper.hh>

////////// ADTSAudioFileSource //////////

static unsigned const samplingFrequencyTable[16] = {
  96000, 88200, 64000, 48000,
  44100, 32000, 24000, 22050,
  16000, 12000, 11025, 8000,
  7350, 0, 0, 0
};

ADTSAudioFileSource*
ADTSAudioFileSource::createNew(UsageEnvironment& env, char const* fileName) {
  FILE* fid = NULL;
  do {
    fid = OpenInputFile(env, fileName);
    if (fid == NULL) break;

    // Now, having opened the input file, read the fixed header of the first frame,
    // to get the audio stream's parameters:
    unsigned char fixedHeader[4]; // it's actually 3.5 bytes long
    if (fread(fixedHeader, 1, sizeof fixedHeader, fid) < sizeof fixedHeader) break;

    // Check the 'syncword':
    if (!(fixedHeader[0] == 0xFF && (fixedHeader[1]&0xF0) == 0xF0)) {
      env.setResultMsg("Bad 'syncword' at start of ADTS file");
      break;
    }

    // Get and check the 'profile':
    u_int8_t profile = (fixedHeader[2]&0xC0)>>6; // 2 bits
    if (profile == 3) {
      env.setResultMsg("Bad (reserved) 'profile': 3 in first frame of ADTS file");
      break;
    }

    // Get and check the 'sampling_frequency_index':
    u_int8_t sampling_frequency_index = (fixedHeader[2]&0x3C)>>2; // 4 bits
    if (samplingFrequencyTable[sampling_frequency_index] == 0) {
      env.setResultMsg("Bad 'sampling_frequency_index' in first frame of ADTS file");
      break;
    }

    // Get and check the 'channel_configuration':
    u_int8_t channel_configuration
      = ((fixedHeader[2]&0x01)<<2)|((fixedHeader[3]&0xC0)>>6); // 3 bits

    // If we get here, the frame header was OK.
    // Reset the fid to the beginning of the file:
#ifndef _WIN32_WCE
    rewind(fid);
#else
    SeekFile64(fid, SEEK_SET,0);
#endif
#ifdef DEBUG
    fprintf(stderr, "Read first frame: profile %d, "
	    "sampling_frequency_index %d => samplingFrequency %d, "
	    "channel_configuration %d\n",
	    profile,
	    sampling_frequency_index, samplingFrequencyTable[sampling_frequency_index],
	    channel_configuration);
#endif
    return new ADTSAudioFileSource(env, fid, profile,
				   sampling_frequency_index, channel_configuration);
  } while (0);

  // An error occurred:
  CloseInputFile(fid);
  return NULL;
}

ADTSAudioFileSource
::ADTSAudioFileSource(UsageEnvironment& env, FILE* fid, u_int8_t profile,
		      u_int8_t samplingFrequencyIndex, u_int8_t channelConfiguration)
  : FramedFileSource(env, fid) {
  fSamplingFrequency = samplingFrequencyTable[samplingFrequencyIndex];
  fNumChannels = channelConfiguration == 0 ? 2 : channelConfiguration;
  fuSecsPerFrame
    = (1024/*samples-per-frame*/*1000000) / fSamplingFrequency/*samples-per-second*/;

  // Construct the 'AudioSpecificConfig', and from it, the corresponding ASCII string:
  unsigned char audioSpecificConfig[2];
  u_int8_t const audioObjectType = profile + 1;
  audioSpecificConfig[0] = (audioObjectType<<3) | (samplingFrequencyIndex>>1);
  audioSpecificConfig[1] = (samplingFrequencyIndex<<7) | (channelConfiguration<<3);
  sprintf(fConfigStr, "%02X%02x", audioSpecificConfig[0], audioSpecificConfig[1]);
}

ADTSAudioFileSource::~ADTSAudioFileSource() {
  CloseInputFile(fFid);
}

// Note: We should change the following to use asynchronous file reading, #####
// as we now do with ByteStreamFileSource. #####
void ADTSAudioFileSource::doGetNextFrame() {
  // Begin by reading the 7-byte fixed_variable headers:
  unsigned char headers[7];
  if (fread(headers, 1, sizeof headers, fFid) < sizeof headers
      || feof(fFid) || ferror(fFid)) {
    // The input source has ended:
    handleClosure();
    return;
  }

  // Extract important fields from the headers:
  Boolean protection_absent = headers[1]&0x01;
  u_int16_t frame_length
    = ((headers[3]&0x03)<<11) | (headers[4]<<3) | ((headers[5]&0xE0)>>5);
#ifdef DEBUG
  u_int16_t syncword = (headers[0]<<4) | (headers[1]>>4);
  fprintf(stderr, "Read frame: syncword 0x%x, protection_absent %d, frame_length %d\n", syncword, protection_absent, frame_length);
  if (syncword != 0xFFF) fprintf(stderr, "WARNING: Bad syncword!\n");
#endif
  unsigned numBytesToRead
    = frame_length > sizeof headers ? frame_length - sizeof headers : 0;

  // If there's a 'crc_check' field, skip it:
  if (!protection_absent) {
    SeekFile64(fFid, 2, SEEK_CUR);
    numBytesToRead = numBytesToRead > 2 ? numBytesToRead - 2 : 0;
  }

  // Next, read the raw frame data into the buffer provided:
  if (numBytesToRead > fMaxSize) {
    fNumTruncatedBytes = numBytesToRead - fMaxSize;
    numBytesToRead = fMaxSize;
  }
  int numBytesRead = fread(fTo, 1, numBytesToRead, fFid);
  if (numBytesRead < 0) numBytesRead = 0;
  fFrameSize = numBytesRead;
  fNumTruncatedBytes += numBytesToRead - numBytesRead;

  // Set the 'presentation time':
  if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) {
    // This is the first frame, so use the current time:
    gettimeofday(&fPresentationTime, NULL);
  } else {
    // Increment by the play time of the previous frame:
    unsigned uSeconds = fPresentationTime.tv_usec + fuSecsPerFrame;
    fPresentationTime.tv_sec += uSeconds/1000000;
    fPresentationTime.tv_usec = uSeconds%1000000;
  }

  fDurationInMicroseconds = fuSecsPerFrame;

  // Switch to another task, and inform the reader that he has data:
  nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
				(TaskFunc*)FramedSource::afterGetting, this);
}
