#This work is licensed under the
#Creative Commons Attribution-Share Alike 3.0 United States License.
#To view a copy of this license, visit
#http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
#Creative Commons,
#171 Second Street, Suite 300,
#San Francisco, California, 94105, USA.

INPUT "signed PCM samples, stream parameters",
try_mid_side,try_adaptive_mid_side,max_partition_order,max_rice_value,
max_LPC_order,exhaustive_model_search;
OUTPUT "a FLAC encoded file";
VAR block_size "block size";
VAR stream_md5 "stream MD5 sum";
VAR pcm_data "PCM data";
VAR pcm_frames "PCM frames count";
VAR PCM_frames_read "channel data not empty";
VAR flac_file "FLAC file";
VAR flac_frame "FLAC frame";
VAR flac_frame_length "FLAC frame length";

VAR sample_rate "sample rate";
VAR bps "bits-per-sample";
VAR channel_count "channels";

VAR min_frame_size "minimum frame size";
VAR max_frame_size "maximum frame size";
VAR total_pcm_frames "total PCM frames";

VAR encoding_parameters "encoding parameters";
VAR try_mid_side "try mid-side";
VAR try_adaptive_mid_side "try adaptive mid-side";
VAR max_partition_order "maximum partition order";
VAR max_rice_value "maximum Rice value";
VAR max_LPC_order "maximum LPC order";
VAR exhaustive_model_search "exhaustive model search";

FUNC write_metadata "write metadata blocks" "flac:write_placeholder_blocks";
FUNC rewrite_metadata "rewrite metadata blocks" "flac:write_placeholder_blocks";
FUNC initialize_stream_md5 "initialize stream MD5";
FUNC read_frame "read PCM frames from input";
FUNC update_md5 "update stream MD5" "flac:update_md5_w";
FUNC encode_frame "encode a FLAC frame" "flac:encode_frame";
FUNC return_to_start "return to start of metadata blocks";
encoding_parameters <-
try_mid_side,
try_adaptive_mid_side,
max_partition_order,
max_rice_value,
max_LPC_order,
exhaustive_model_search;
min_frame_size <- 2 ^ 24 - 1 /*largest unsigned 24-bit value*/;
max_frame_size <- 0;
total_pcm_frames <- 0;
stream_md5 <- initialize_stream_md5();
bytes(102, 76, 97, 67) -> write 4 bytes;
write_metadata(sample_rate,
               channel_count,
               bps,
               block_size,
               min_frame_size,
               max_frame_size,
               total_pcm_frames,
               stream_md5);
pcm_data,pcm_frames <- read_frame(block_size);
while pcm_frames > 0 {
    flac_frame,flac_frame_length <- encode_frame(encoding_parameters,
                                                 channel_count,
                                                 bps,
                                                 pcm_data,
                                                 pcm_frames);
    flac_frame -> write flac_frame_length bytes;
    if flac_frame_length < min_frame_size {
        min_frame_size <- flac_frame_length;
    }
    if flac_frame_length > max_frame_size {
        max_frame_size <- flac_frame_length;
    }
    total_pcm_frames <- total_pcm_frames + pcm_frames;
    stream_md5 <- update_md5(stream_md5, pcm_data);
    pcm_data,pcm_frames <- read_frame(block_size);
}
seek 4;
rewrite_metadata(sample_rate,
                 channel_count,
                 bps,
                 block_size,
                 min_frame_size,
                 max_frame_size,
                 total_pcm_frames,
                 stream_md5);
return flac_file;
