% Write a NIST format audio file (nBits must be 8 or 16)
%
% function nistwrite(data, samplerate, nBits, filename)
%
% data is a (N-by-1) vector of signed integers (8 bits -> -128:127 or 16 bits => -32768:32767)
%
% by Guillaume LATHOUD at IDIAP (lathoud@idiap.ch)

function nistwrite(data, samplerate, nBits, filename)

    if nBits ~= 8 & nBits ~= 16
        error('nBits must be 8 or 16');
    end
    
    nBytes = nBits / 8;
    data = floor(data); % to make sure we have integers
    
    % 1) Prepare the NIST header        

    header = sprintf('NIST_1A\n   1024\n');
    header = sprintf('%ssample_rate -i %d\n', header, samplerate);
    header = sprintf('%srecord_freq -r %d.000000\n', header, samplerate);
    header = sprintf('%sstart_time -r 0.000000\n', header);
    header = sprintf('%ssample_min -i %d\n', header, min(data));
    header = sprintf('%ssample_max -i %d\n', header, max(data));
    header = sprintf('%ssample_count -i %d\n', header, length(data));
    header = sprintf('%schannel_count -i 1\n', header);
    header = sprintf('%ssample_n_bytes -i %d\n', header, nBytes);
    if nBytes == 2
        header = sprintf('%ssample_byte_format -s2 10\n', header);    
    end
    header = sprintf('%ssample_sig_bits -i %d\n', header, nBits);
    header = sprintf('%send_head\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', header);
    
    header = sprintf('%s%s', header, blanks(1024-length(header)));
    
    % 2) Prepare the data

    % Clip it
    
    maximum = 2^(nBits-1) - 1;
    minimum = - (2^(nBits-1));
    data = min(data, maximum);
    data = max(minimum, data);
    
    % Turn it into 2-complement (i.e. positive)
    % floor() to make sure these are integer
    data = floor(mod(data + 2^nBits, 2^nBits));
    
    % If 16-bit, split each word (most significant byte first)
    if nBytes == 2
        high = bitshift(data, -8);
        low = bitand(data, 255);
        data = reshape([high'; low'], [length(data)*2 1]);
    end

    % 3) Write the file
    
    fd = fopen(filename, 'w');
    fprintf(fd, header);
    fwrite(fd, data, 'ubit8');
    if fclose(fd) ~= 0
        error('Error writing the file. Could not close it.');
    end
    