import argparse

"""

Works only for raw 8 bit signed mono data.

This script was writen as an easy way to convert original Amiga ST-XX raw
samples to a more documented format that keeps the original data untouched.

See also:
- http://paulbourke.net/dataformats/audio/
- https://github.com/audacity/audacity/blob/fa00dd0/lib-src/libsndfile/src/aiff.c
- https://archive.org/details/AmigaSTXX

"""

sample_rate_in_extended_precision = {
        11025: b'\x40\x0c\xac\x44\x00\x00\x00\x00\x00\x00',
        16000: b'\x40\x0c\xfa\x00\x00\x00\x00\x00\x00\x00',
        16726: b'\x40\x0d\x82\xac\x00\x00\x00\x00\x00\x00',
        22050: b'\x40\x0d\xac\x44\x00\x00\x00\x00\x00\x00',
        44100: b'\x40\x0e\xac\x44\x00\x00\x00\x00\x00\x00',
        }

DEFAULT_SAMPLE_RATE = 16726

def convert(input_file_name, output_file_name, sample_rate):
    sample_data = bytearray(open(input_file_name,  'rb').read())

    nb_samples= len(sample_data)

    form_chunk_size = 4 + 4 + 4
    comm_chunk_size = 4 + 4 + 2 + 4 + 2 + 10
    ssnd_chunk_size = 4 + 4 + 4 + 4

    total_size = form_chunk_size + comm_chunk_size + ssnd_chunk_size + nb_samples
    nb_channels = 1
    sample_size = 8

    form_chunk = b'FORM' + \
            (total_size - 8).to_bytes(4, byteorder='big') + \
            b'AIFF'

    comm_chunk = b'COMM\x00\x00\x00\x12' + \
            nb_channels.to_bytes(2, byteorder='big') + \
            (sample_rate*nb_channels).to_bytes(4, byteorder='big') + \
            sample_size.to_bytes(2, byteorder='big') + \
            sample_rate_in_extended_precision[sample_rate]

    ssnd_chunk = b'SSND' + \
            (total_size-34).to_bytes(4, byteorder='big') + \
            b'\x00\x00\x00\x00' + \
            b'\x00\x00\x00\x00'

    header = form_chunk + comm_chunk + ssnd_chunk

    open(output_file_name, 'wb').write(header+sample_data)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('input_file')
    parser.add_argument('-o', '--output-file', help='The name of the output file (default is the name of the input file with ".aiff" extension)')
    parser.add_argument('-r', '--sample-rate', help='The sample rate of the source in Hz. The default is {}.'.format(DEFAULT_SAMPLE_RATE), default=DEFAULT_SAMPLE_RATE)
    args = parser.parse_args()

    input_file_name = args.input_file
    output_file_name = args.output_file or input_file_name + '.aiff'

    convert(input_file_name, output_file_name, args.sample_rate)
