text:
use std::fmt;
use std::io::{self, Read, Write, Cursor};
use std::mem;
use std::net::{SocketAddrV4, SocketAddrV6};
use std::net::{self, SocketAddr, TcpStream, TcpListener};
use std::os::windows::prelude::*;
use std::sync::{Mutex, MutexGuard};

use net2::{self, TcpBuilder};
use net::tcp::Shutdown;
use wio::iocp::CompletionStatus;
use wio::net::*;
use winapi::*;

use {Evented, EventSet, PollOpt, Selector, Token};
use event::IoEvent;
use sys::windows::selector::{Overlapped, Registration};
use sys::windows::{bad_state, wouldblock, Family};
use sys::windows::from_raw_arc::FromRawArc;

pub struct TcpSocket {
    /// Separately stored implementation to ensure that the `Drop`
    /// implementation on this type is only executed when it's actually dropped
    /// (many clones of this `imp` are made).
    imp: Imp,
}

#[derive(Clone)]
struct Imp {
    /// A stable address and synchronized access for all internals. This serves
    /// to ensure that all `Overlapped` pointers are valid for a long period of
    /// time as well as allowing completion callbacks to have access to the
    /// internals without having ownership.
    ///
    /// Note that the reference count also allows us "loan out" copies to
    /// completion ports while I/O is running to guarantee that this stays alive
    /// until the I/O completes. You'll notice a number of calls to
    /// `mem::forget` below, and these only happen on successful scheduling of
    /// I/O and are paired with `overlapped2arc!` macro invocations in the
    /// completion callbacks (to have a decrement match the increment).
    inner: FromRawArc<Io>,
}

struct Io {
    inner: Mutex<Inner>,
    read: Overlapped, // also used for connect/accept
    write: Overlapped,
}

struct Inner {
    socket: Socket,
    family: Family,
    iocp: Registration,
    deferred_connect: Option<SocketAddr>,
    bound: bool,
    read: State<Vec<u8>, Cursor<Vec<u8>>>,
    write: State<(Vec<u8>, usize), (Vec<u8>, usize)>,
    accept: State<TcpStream, TcpStream>,
    accept_buf: AcceptAddrsBuf,
}

/// Internal state transitions for this socket.
///
/// This enum keeps track of which `std::net` primitive we currently are.
/// Reusing `std::net` allows us to use the extension traits in `net2` and `wio`
/// along with not having to manage the literal socket creation ourselves.
enum Socket {
    Empty,                  // socket has been closed
    Building(TcpBuilder),   // not-connected nor not-listened socket
    Stream(TcpStream),      // accepted or connected socket
    Listener(TcpListener),  // listened socket
}

enum State<T, U> {
    Empty,              // no I/O operation in progress
    Pending(T),         // an I/O operation is in progress
    Ready(U),           // I/O has finished with this value
    Error(io::Error),   // there was an I/O error
}

impl TcpSocket {
    pub fn v4() -> io::Result<TcpSocket> {
        TcpBuilder::new_v4().map(|s| {
            TcpSocket::new(Socket::Building(s), Family::V4)
        })
    }

    pub fn v6() -> io::Result<TcpSocket> {
        TcpBuilder::new_v6().map(|s| {
            TcpSocket::new(Socket::Building(s), Family::V6)
        })
    }

    fn new(socket: Socket, fam: Family) -> TcpSocket {
        TcpSocket {
            imp: Imp {
                inner: FromRawArc::new(Io {
                    read: Overlapped::new(read_done),
                    write: Overlapped::new(write_done),
                    inner: Mutex::new(Inner {
                        socket: socket,
                        family: fam,
                        iocp: Registration::new(),
                        deferred_connect: None,
                        bound: false,
                        accept: State::Empty,
                        read: State::Empty,
                        write: State::Empty,
                        accept_buf: AcceptAddrsBuf::new(),
                    }),
                }),
            },
        }
    }

    pub fn connect(&self, addr: &SocketAddr) -> io::Result<bool> {
        let mut me = self.inner();
        let me = &mut *me;
        if me.deferred_connect.is_some() {
            return Err(bad_state())
        }
        // If we haven't been registered defer the actual connect until we're
        // registered
        if me.iocp.port().is_none() {
            me.deferred_connect = Some(*addr);
            return Ok(false)
        }
        let (socket, connected) = match me.socket {
            Socket::Building(ref b) => {
                // connect_overlapped only works on bound sockets, so if we're
                // not bound yet go ahead and bind us
                if !me.bound {
                    try!(b.bind(&addr_any(me.family)));
                    me.bound = true;
                }
                let res = unsafe {
                    trace!("scheduling a connect");
                    try!(b.connect_overlapped(addr,
                                              self.imp.inner.read.get_mut()))
                };
                // see docs above on Imp.inner for rationale on forget
                mem::forget(self.imp.clone());
                res
            }
            _ => return Err(bad_state()),
        };
        me.socket = Socket::Stream(socket);
        Ok(connected)
    }

    pub fn bind(&self, addr: &SocketAddr) -> io::Result<()> {
        let mut me = self.inner();
        try!(try!(me.socket.builder()).bind(addr));
        me.bound = true;
        Ok(())
    }

    pub fn listen(&self, backlog: usize) -> io::Result<()> {
        let mut me = self.inner();
        let listener = try!(try!(me.socket.builder()).listen(backlog as i32));
        me.socket = Socket::Listener(listener);
        Ok(())
    }

    pub fn accept(&self) -> io::Result<Option<TcpSocket>> {
        let mut me = self.inner();
        try!(me.socket.listener());
        let ret = match mem::replace(&mut me.accept, State::Empty) {
            State::Empty => return Ok(None),
            State::Pending(t) => {
                me.accept = State::Pending(t);
                return Ok(None)
            }
            State::Ready(s) => {
                Ok(Some(TcpSocket::new(Socket::Stream(s), me.family)))
            }
            State::Error(e) => Err(e),
        };
        self.imp.schedule_read(&mut me);
        return ret
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        try!(self.inner().socket.stream()).peer_addr()
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        match self.inner().socket {
            Socket::Stream(ref s) => s.local_addr(),
            Socket::Listener(ref s) => s.local_addr(),
            Socket::Empty |
            Socket::Building(..) => Err(bad_state()),
        }
    }

    pub fn try_clone(&self) -> io::Result<TcpSocket> {
        let me = self.inner();
        match me.socket {
            Socket::Stream(ref s) => s.try_clone().map(|s| {
                TcpSocket::new(Socket::Stream(s), me.family)
            }),
            Socket::Listener(ref s) => s.try_clone().map(|s| {
                TcpSocket::new(Socket::Listener(s), me.family)
            }),
            Socket::Empty |
            Socket::Building(..) => Err(bad_state()),
        }
    }

    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        try!(self.inner().socket.stream()).shutdown(match how {
            Shutdown::Read => net::Shutdown::Read,
            Shutdown::Write => net::Shutdown::Write,
            Shutdown::Both => net::Shutdown::Both,
        })
    }

    /*
     *
     * ===== Socket Options =====
     *
     */

    pub fn set_reuseaddr(&self, val: bool) -> io::Result<()> {
        try!(self.inner().socket.builder()).reuse_address(val).map(|_| ())
    }

    pub fn take_socket_error(&self) -> io::Result<()> {
        unimplemented!();
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        net2::TcpStreamExt::set_nodelay(try!(self.inner().socket.stream()),
                                        nodelay)
    }

    pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
        let dur = seconds.map(|s| s * 1000);
        net2::TcpStreamExt::set_keepalive_ms(try!(self.inner().socket.stream()),
                                             dur)
    }

    fn inner(&self) -> MutexGuard<Inner> {
        self.imp.inner()
    }

    fn post_register(&self, interest: EventSet, me: &mut Inner) {
        if interest.is_readable() {
            self.imp.schedule_read(me);
        }

        // At least with epoll, if a socket is registered with an interest in
        // writing and it's immediately writable then a writable event is
        // generated immediately, so do so here.
        if interest.is_writable() {
            if let State::Empty = me.write {
                if let Socket::Stream(..) = me.socket {
                    me.iocp.defer(EventSet::writable());
                }
            }
        }
    }
}

impl Imp {
    fn inner(&self) -> MutexGuard<Inner> {
        self.inner.inner.lock().unwrap()
    }

    /// Issues a "read" operation for this socket, if applicable.
    ///
    /// This is intended to be invoked from either a completion callback or a
    /// normal context. The function is infallible because errors are stored
    /// internally to be returned later.
    ///
    /// It is required that this function is only called after the handle has
    /// been registered with an event loop.
    fn schedule_read(&self, me: &mut Inner) {
        match me.socket {
            Socket::Empty |
            Socket::Building(..) => {}

            Socket::Listener(ref l) => {
                match me.accept {
                    State::Empty => {}
                    _ => return
                }
                let accept_buf = &mut me.accept_buf;
                let res = match me.family {
                    Family::V4 => TcpBuilder::new_v4(),
                    Family::V6 => TcpBuilder::new_v6(),
                }.and_then(|builder| unsafe {
                    trace!("scheduling an accept");
                    l.accept_overlapped(&builder, accept_buf,
                                        self.inner.read.get_mut())
                });
                match res {
                    Ok((socket, _)) => {
                        // see docs above on Imp.inner for rationale on forget
                        me.accept = State::Pending(socket);
                        mem::forget(self.clone());
                    }
                    Err(e) => {
                        me.accept = State::Error(e);
                        me.iocp.defer(EventSet::readable());
                    }
                }
            }

            Socket::Stream(ref s) => {
                match me.read {
                    State::Empty => {}
                    _ => return,
                }
                let mut buf = me.iocp.get_buffer(64 * 1024);
                let res = unsafe {
                    trace!("scheduling a read");
                    let cap = buf.capacity();
                    buf.set_len(cap);
                    s.read_overlapped(&mut buf, self.inner.read.get_mut())
                };
                match res {
                    Ok(_) => {
                        // see docs above on Imp.inner for rationale on forget
                        me.read = State::Pending(buf);
                        mem::forget(self.clone());
                    }
                    Err(e) => {
                        // Like above, be sure to indicate that hup has happened
                        // whenever we get `ECONNRESET`
                        let mut set = EventSet::readable();
                        if e.raw_os_error() == Some(WSAECONNRESET as i32) {
                            set = set | EventSet::hup();
                        }
                        me.read = State::Error(e);
                        me.iocp.defer(set);
                        me.iocp.put_buffer(buf);
                    }
                }
            }
        }
    }

    /// Similar to `schedule_read`, except that this issues, well, writes.
    ///
    /// This function will continually attempt to write the entire contents of
    /// the buffer `buf` until they have all been written. The `pos` argument is
    /// the current offset within the buffer up to which the contents have
    /// already been written.
    ///
    /// A new writable event (e.g. allowing another write) will only happen once
    /// the buffer has been written completely (or hit an error).
    fn schedule_write(&self, buf: Vec<u8>, pos: usize,
                      me: &mut Inner) {
        trace!("scheduling a write");
        let err = match me.socket.stream() {
            Ok(s) => unsafe {
                s.write_overlapped(&buf[pos..], self.inner.write.get_mut())
            },
            Err(..) => return,
        };
        match err {
            Ok(_) => {
                // see docs above on Imp.inner for rationale on forget
                me.write = State::Pending((buf, pos));
                mem::forget(self.clone());
            }
            Err(e) => {
                me.write = State::Error(e);
                me.iocp.defer(EventSet::writable());
                me.iocp.put_buffer(buf);
            }
        }
    }
}

impl Socket {
    fn builder(&self) -> io::Result<&TcpBuilder> {
        match *self {
            Socket::Building(ref s) => Ok(s),
            _ => Err(bad_state()),
        }
    }

    fn listener(&self) -> io::Result<&TcpListener> {
        match *self {
            Socket::Listener(ref s) => Ok(s),
            _ => Err(bad_state()),
        }
    }

    fn stream(&self) -> io::Result<&TcpStream> {
        match *self {
            Socket::Stream(ref s) => Ok(s),
            _ => Err(bad_state()),
        }
    }
}

fn read_done(status: &CompletionStatus, dst: &mut Vec<IoEvent>) {
    let me2 = Imp {
        inner: unsafe { overlapped2arc!(status.overlapped(), Io, read) },
    };

    let mut me = me2.inner();

    if let Socket::Listener(..) = me.socket {
        match mem::replace(&mut me.accept, State::Empty) {
            State::Pending(s) => {
                trace!("finished an accept");
                me.accept = State::Ready(s);
                return me.iocp.push_event(EventSet::readable(), dst)
            }
            s => me.accept = s,
        }
    } else {
        match mem::replace(&mut me.read, State::Empty) {
            State::Pending(mut buf) => {
                trace!("finished a read: {}", status.bytes_transferred());
                unsafe {
                    buf.set_len(status.bytes_transferred() as usize);
                }
                me.read = State::Ready(Cursor::new(buf));

                // If we transferred 0 bytes then be sure to indicate that hup
                // happened.
                let mut e = EventSet::readable();
                if status.bytes_transferred() == 0 {
                    e = e | EventSet::hup();
                }
                return me.iocp.push_event(e, dst)
            }
            s => me.read = s,
        }

        // If a read didn't complete, then the connect must have just finished.
        trace!("finished a connect");
        me.iocp.push_event(EventSet::writable(), dst);
        me2.schedule_read(&mut me);
    }

}

fn write_done(status: &CompletionStatus, dst: &mut Vec<IoEvent>) {
    trace!("finished a write {}", status.bytes_transferred());
    let me2 = Imp {
        inner: unsafe { overlapped2arc!(status.overlapped(), Io, write) },
    };
    let mut me = me2.inner();
    let (buf, pos) = match mem::replace(&mut me.write, State::Empty) {
        State::Pending(pair) => pair,
        _ => unreachable!(),
    };
    let new_pos = pos + (status.bytes_transferred() as usize);
    if new_pos == buf.len() {
        me.iocp.push_event(EventSet::writable(), dst);
    } else {
        me2.schedule_write(buf, new_pos, &mut me);
    }
}

fn addr_any(family: Family) -> SocketAddr {
    match family {
        Family::V4 => {
            let addr = SocketAddrV4::new(super::ipv4_any(), 0);
            SocketAddr::V4(addr)
        }
        Family::V6 => {
            let addr = SocketAddrV6::new(super::ipv6_any(), 0, 0, 0);
            SocketAddr::V6(addr)
        }
    }
}

impl Read for TcpSocket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut me = self.inner();
        match mem::replace(&mut me.read, State::Empty) {
            State::Empty => Err(wouldblock()),
            State::Pending(buf) => {
                me.read = State::Pending(buf);
                Err(wouldblock())
            }
            State::Ready(mut cursor) => {
                let amt = try!(cursor.read(buf));
                // Once the entire buffer is written we need to schedule the
                // next read operation.
                if cursor.position() as usize == cursor.get_ref().len() {
                    me.iocp.put_buffer(cursor.into_inner());
                    self.imp.schedule_read(&mut me);
                } else {
                    me.read = State::Ready(cursor);
                }
                Ok(amt)
            }
            State::Error(e) => {
                self.imp.schedule_read(&mut me);
                Err(e)
            }
        }
    }
}

impl Write for TcpSocket {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let mut me = self.inner();
        let me = &mut *me;
        match me.write {
            State::Empty => {}
            _ => return Err(wouldblock())
        }
        try!(me.socket.stream());
        if me.iocp.port().is_none() {
            return Err(wouldblock())
        }
        let mut intermediate = me.iocp.get_buffer(64 * 1024);
        let amt = try!(intermediate.write(buf));
        self.imp.schedule_write(intermediate, 0, me);
        Ok(amt)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl Evented for TcpSocket {
    fn register(&self, selector: &mut Selector, token: Token,
                interest: EventSet, opts: PollOpt) -> io::Result<()> {
        let addr = {
            let mut me = self.inner();
            {
                let me = &mut *me;
                let socket = match me.socket {
                    Socket::Stream(ref s) => s as &AsRawSocket,
                    Socket::Listener(ref l) => l as &AsRawSocket,
                    Socket::Building(ref b) => b as &AsRawSocket,
                    Socket::Empty => return Err(bad_state()),
                };
                try!(me.iocp.register_socket(socket, selector, token, interest,
                                             opts));
            }
            match me.deferred_connect.take() {
                Some(addr) => addr,
                None => {
                    self.post_register(interest, &mut me);
                    return Ok(())
                }
            }
        };

        // If we were connected before being registered process that request
        // here and go along our merry ways. Note that the callback for a
        // successful connect will worry about generating writable/readable
        // events and scheduling a new read.
        self.connect(&addr).map(|_| ())
    }

    fn reregister(&self, selector: &mut Selector, token: Token,
                  interest: EventSet, opts: PollOpt) -> io::Result<()> {
        let mut me = self.inner();
        {
            let me = &mut *me;
            let socket = match me.socket {
                Socket::Stream(ref s) => s as &AsRawSocket,
                Socket::Listener(ref l) => l as &AsRawSocket,
                Socket::Building(ref b) => b as &AsRawSocket,
                Socket::Empty => return Err(bad_state()),
            };
            try!(me.iocp.reregister_socket(socket, selector, token, interest,
                                           opts));
        }
        self.post_register(interest, &mut me);
        Ok(())
    }

    fn deregister(&self, selector: &mut Selector) -> io::Result<()> {
        self.inner().iocp.deregister(selector)
    }
}

impl fmt::Debug for TcpSocket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "TcpSocket { ... }".fmt(f)
    }
}

impl Drop for TcpSocket {
    fn drop(&mut self) {
        // When the `TcpSocket` itself is dropped then we close the internal
        // handle (e.g. call `closesocket`). This will cause all pending I/O
        // operations to forcibly finish and we'll get notifications for all of
        // them and clean up the rest of our internal state (yay!)
        self.inner().socket = Socket::Empty;
    }
}


If you ask me (and since you are reading this, I'm assuming you are), this is THE ULTIMATE mac & cheese, for the real cheese lover. I had accumulated a lot of cheese over the past couple of weeks somehow (guess it's what happens when you have a bad habit of buying cheese and your mum encourages it by bringing you more cheese when she visits…) and I didn't want to let it spoil. I remembered seeing a recipe in an old BBC Good Food magazine for using up your leftover Christmas cheese and I decided that this is a great way to use up all the cheese I had. In my fridge, I had a mix of the following cheeses: Vacherin (one of my favourite cheeses this winter), Chabichou du Poidou (soft goat's cheese), St Helen's Goat's Cheese (firmer goat's cheese), Bulgarian firm cow's cheese (Kashkaval), Gruyère and Parmesan. I also had some pancetta and cooked ham that needed using up so I added them too. They made a fantastic addition to the already very tasty cheese sauce.
300g leftover cheese of your choice, grated, crumbled or chopped depending on the consistency. I used: Vacherin, Chabichou du Poidou, St Helen's Goat's Cheese, Bulgarian cow's cheese (kashkaval), Gruyère and Parmesan.
Cook the macaroni as per pack instructions until they are al dente. In the meantime, make the cheese sauce. Melt the butter then stir in the flour and mustard powder and cook for 1 minute, stirring. Pour in the milk a little at a time, stirring really well each time to get rid of any lumps. Continue until all the milk is added, then bring to the boil, stirring all the time so it doesn't get lumpy. Cook for 2 mins until thickened. Reserve around 50g of the cheese (I reserved some of the grated cheese as it would melt better) and add the remaining 250g cheese and a grind of pepper to the milk and stir really well. Meanwhile, if using pancetta/bacon, fry it up until cooked and slightly crispy.
Heat the grill to high. Pour the pasta and the meats into the cheese sauce and stir well. Transfer to an ovenproof dish and top with the remaining cheese and the breadcrumbs. Grill for 2-3 minutes until golden and bubbling. Serve with some side salad.
Recipe adapted from BBC Good Food magazine, issue December 2010.
If you make this, please do share what combinations of cheeses you used!


At what point are you going to make an initial proposal for the feature set and cost John?
Are you going to prioritize development of 1U rack hardware above continuing OS development of the existing platform? I am sure I am not alone in hoping that doesn't happen.
I just spent a bunch of time going through all these presets. Wow.....what great work. Thank you so much for these. I learned a lot just looking at how some of these were constructed. Patch 42, Starpeggios was just awesome!
Topic: Andromeda owners and Solaris , please share your thoughts !


text:
HomeAuto NewsNissan starts Sunny Production
Nissan starts Sunny Production
August 31, 2011 goaonwheels Auto News, Nissan 3
Nissan has started the production of the Sunny Sedan at the company's manufacturing plant at Oragadam, near Chennai. This is the second completely made in India car to be rolled out by Nissan from the Chennai plant in a period of 15 months.
It is manufactured with 85% local content of which 40% of the components are sourced from Chennai. The sedan is expected to appeal to young families looking for a medium sized sedan that combines a dynamic upscale design with the space, quality and features associated with the Nissan brand.
Nissan Motor India Announces the Start of Production of Nissan SUNNY
Second Made-in-India model produced by Nissan
To be produced at the company's manufacturing plant near Chennai
Chennai, August 30, 2011: Nissan Motor India Pvt. Ltd. (NMIPL) today celebrated the start of production of its 'Made-in-India' mid-size sedan Nissan SUNNY at the company's manufacturing plant at Oragadam, near Chennai. This is the second completely made in India car to be rolled out by Nissan from the Chennai plant in a period of 15 months.
The Nissan SUNNY was unveiled on August 3, 2011 and is being readied to hit the market by the coming festive season. It is manufactured with 85% local content of which 40% of the components are sourced from Chennai. The sedan is expected to appeal to young families looking for a medium sized sedan that combines a dynamic upscale design with the space, quality and features associated with the Nissan brand.
Commenting on the achievement, Mr. Kiminobu Tokuyama, Managing Director and CEO, NMIPL. said, "Start of production of Nissan SUNNY is another significant milestone for Nissan in India. We wanted the mid-size sedan to be available during the upcoming festival season and we successfully accelerated our work program to make that schedule. Nissan SUNNY will help to leverage our position as one of the key players in the Indian market".
Speaking on the occasion, Mr. Kou Kimura, CEO and MD, Renault Nissan Alliance India Pvt Ltd (RNAIPL) said, "Today's start of production of SUNNY reinstates Nissan's commitment to India and is the second of many other local products to come. It highlights the high-performance level of our state of the art plant, which is producing its second model in less than 15 months".
The new Nissan SUNNY made its international debut at the 8th China (Guangzhou) International Automobile Exhibition in 2010 and later in the US. The SUNNY is the second model built on Nissan's all new V-platform.
Nissan Goa
Nissan Goa Dealers
Nissan Micra India
Nissan Micra price
Nissan Micra specifications
Nissan Sunny Micra
Nissan Sunny teaser site
Nissan's new sedan
V platform
Land Rover All-New Defender Concept at Frankfurt Motor Show
The much awaited Skoda Laura RS makes its way to India
Datsun launches Redi–Go in Goa
June 9, 2016 Intern 1 0
AM Ventures, the dealers for Nissan – Datsun in Goa, introduced the new entry level hatchback the Redi – Go in the Goan market priced at Rs. 2.49 lakhs (Ex showroom-Goa). The car is available […]
Nissan Note global compact car unveiled, Will it see India entry?
July 17, 2012 goaonwheels 0
Nissan held the global premiere of its all-new Note in Yokohama on July 16, 2012, introducing the Japan-market model. The Note is a bigger hatch and one model above the Micra. The new hatchback includes […]
Nissan's small car with Ashok Leyland to hit market by 2014
March 12, 2012 goaonwheels 0
Japanese car maker Nissan will launch an entry-level small car, developed in partnership with Ashok Leyland, by 2014 that could be priced around Rs. 2 lakh to Rs. 4 lakh. "We are working on multiple […]

redpajama_set_name: RedPajamaCommonCrawl


text:
/****************************************************************************************
Portions of this file are derived from the following 3GPP standard:

    3GPP TS 26.073
    ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
    Available from http://www.3gpp.org

(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
Permission to distribute, modify and use this file under the standard license
terms listed above has been obtained from the copyright holder.
****************************************************************************************/
/*
------------------------------------------------------------------------------

 Pathname: ./audio/gsm-amr/c/src/cod_amr.c
 Funtions: cod_amr_init
           cod_amr_reset
           cod_amr_exit
           cod_amr_first
           cod_amr

     Date: 06/09/2000

------------------------------------------------------------------------------
 REVISION HISTORY

 Description: Made changes based on comments from the review meeting.

 Description: Synchronized file with UMTS version 3.2.0. Updated coding
              template. Removed unnecessary include files.

 Description: Added initialization of the overflow flag in cod_amr_init()
              and in cod_amr_reset(). This overflow flag is now part of
              the cod_amrState structure.

 Description: Cleaned up INCLUDES. removed inclusion of basic_op.h and repeat
              inclusion of copy.h

 Description: Updated function call to dtx_enc

 Description:  For cod_amr_first() and cod_amr()
              1. Replaced copy() function with memcpy()

 Description:  Replaced OSCL mem type functions and eliminated include
               files that now are chosen by OSCL definitions

 Description:  Replaced "int" and/or "char" with OSCL defined types.

 Description:

------------------------------------------------------------------------------
 MODULE DESCRIPTION

 These functions comprise the main encoder routine operating on a frame basis.

------------------------------------------------------------------------------
*/

/*----------------------------------------------------------------------------
; INCLUDES
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>

#include "cod_amr.h"
#include "typedef.h"
#include "cnst.h"
#include "copy.h"
#include "qua_gain.h"
#include "lpc.h"
#include "lsp.h"
#include "pre_big.h"
#include "ol_ltp.h"
#include "p_ol_wgh.h"
#include "spreproc.h"
#include "cl_ltp.h"
#include "pred_lt.h"
#include "spstproc.h"
#include "cbsearch.h"
#include "gain_q.h"
#include "convolve.h"
#include "ton_stab.h"
#include "vad.h"
#include "dtx_enc.h"

/*----------------------------------------------------------------------------
; MACROS
; Define module specific macros here
----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
; DEFINES
; Include all pre-processor statements here. Include conditional
; compile variables also.
----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
; LOCAL FUNCTION DEFINITIONS
; Function Prototype declaration
----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
; LOCAL VARIABLE DEFINITIONS
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/

/* Spectral expansion factors */

static const Word16 gamma1[M] =
{
    30802, 28954, 27217, 25584, 24049,
    22606, 21250, 19975, 18777, 17650
};

/* gamma1 differs for the 12k2 coder */
static const Word16 gamma1_12k2[M] =
{
    29491, 26542, 23888, 21499, 19349,
    17414, 15672, 14105, 12694, 11425
};

static const Word16 gamma2[M] =
{
    19661, 11797, 7078, 4247, 2548,
    1529, 917, 550, 330, 198
};

/*
------------------------------------------------------------------------------
 FUNCTION NAME: cod_amr_init
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    state = pointer to a pointer to a structure of type cod_amrState

 Outputs:
    Structure pointed to by the pointer pointed to by state is
      initialized to its reset value
    state points to the allocated memory

 Returns:
    Returns 0 if memory was successfully initialized,
        otherwise returns -1.

 Global Variables Used:
    None.

 Local Variables Needed:
    None.

------------------------------------------------------------------------------
 FUNCTION DESCRIPTION

 This function allocates memory and initializes state variables.

------------------------------------------------------------------------------
 REQUIREMENTS

 None.

------------------------------------------------------------------------------
 REFERENCES

 cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001

------------------------------------------------------------------------------
 PSEUDO-CODE

int cod_amr_init (cod_amrState **state, Flag dtx)
{
  cod_amrState* s;

  if (state == (cod_amrState **) NULL){
      fprintf(stderr, "cod_amr_init: invalid parameter\n");
      return -1;
  }
  *state = NULL;

  // allocate memory
  if ((s= (cod_amrState *) malloc(sizeof(cod_amrState))) == NULL){
      fprintf(stderr, "cod_amr_init: can not malloc state structure\n");
      return -1;
  }

  s->lpcSt = NULL;
  s->lspSt = NULL;
  s->clLtpSt = NULL;
  s->gainQuantSt = NULL;
  s->pitchOLWghtSt = NULL;
  s->tonStabSt = NULL;
  s->vadSt = NULL;
  s->dtx_encSt = NULL;
  s->dtx = dtx;

  // Init sub states
  if (cl_ltp_init(&s->clLtpSt) ||
      lsp_init(&s->lspSt) ||
      gainQuant_init(&s->gainQuantSt) ||
      p_ol_wgh_init(&s->pitchOLWghtSt) ||
      ton_stab_init(&s->tonStabSt) ||
#ifndef VAD2
      vad1_init(&s->vadSt) ||
#else
      vad2_init(&s->vadSt) ||
#endif
      dtx_enc_init(&s->dtx_encSt) ||
      lpc_init(&s->lpcSt)) {
     cod_amr_exit(&s);
     return -1;
  }

  cod_amr_reset(s);

  *state = s;

  return 0;
}

------------------------------------------------------------------------------
 RESOURCES USED [optional]

 When the code is written for a specific target processor the
 the resources used should be documented below.

 HEAP MEMORY USED: x bytes

 STACK MEMORY USED: x bytes

 CLOCK CYCLES: (cycle count equation for this function) + (variable
                used to represent cycle count for each subroutine
                called)
     where: (cycle count variable) = cycle count for [subroutine
                                     name]

------------------------------------------------------------------------------
 CAUTION [optional]
 [State any special notes, constraints or cautions for users of this function]

------------------------------------------------------------------------------
*/

Word16 cod_amr_init(cod_amrState **state, Flag dtx)
{
    cod_amrState* s;

    if (state == (cod_amrState **) NULL)
    {
        /* fprint(stderr, "cod_amr_init: invalid parameter\n");  */
        return(-1);
    }
    *state = NULL;

    /* allocate memory */
    if ((s = (cod_amrState *) malloc(sizeof(cod_amrState))) == NULL)
    {
        /* fprint(stderr, "cod_amr_init:
                           can not malloc state structure\n");  */
        return(-1);
    }

    s->lpcSt = NULL;
    s->lspSt = NULL;
    s->clLtpSt = NULL;
    s->gainQuantSt = NULL;
    s->pitchOLWghtSt = NULL;
    s->tonStabSt = NULL;
    s->vadSt = NULL;
    s->dtx_encSt = NULL;
    s->dtx = dtx;

    /* Initialize overflow Flag */

    s->overflow = 0;

    /* Init sub states */
    if (cl_ltp_init(&s->clLtpSt) ||
            lsp_init(&s->lspSt) ||
            gainQuant_init(&s->gainQuantSt) ||
            p_ol_wgh_init(&s->pitchOLWghtSt) ||
            ton_stab_init(&s->tonStabSt) ||
#ifndef VAD2
            vad1_init(&s->vadSt) ||
#else
            vad2_init(&s->vadSt) ||
#endif
            dtx_enc_init(&s->dtx_encSt) ||
            lpc_init(&s->lpcSt))
    {
        cod_amr_exit(&s);
        return(-1);
    }

    cod_amr_reset(s);

    *state = s;

    return(0);
}

/****************************************************************************/

/*
------------------------------------------------------------------------------
 FUNCTION NAME: cod_amr_reset
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    state = pointer to a structure of type cod_amrState

 Outputs:
    Structure pointed to by state is initialized to initial values.

 Returns:
    Returns 0 if memory was successfully initialized,
        otherwise returns -1.

 Global Variables Used:
    None.

 Local Variables Needed:
    None.

------------------------------------------------------------------------------
 FUNCTION DESCRIPTION

 This function resets the state memory for cod_amr.

------------------------------------------------------------------------------
 REQUIREMENTS

 None.

------------------------------------------------------------------------------
 REFERENCES

 cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001

------------------------------------------------------------------------------
 PSEUDO-CODE

int cod_amr_reset (cod_amrState *st)
{
   Word16 i;

   if (st == (cod_amrState *) NULL){
      fprintf(stderr, "cod_amr_reset: invalid parameter\n");
      return -1;
   }

    *-----------------------------------------------------------------------*
    *          Initialize pointers to speech vector.                        *
    *-----------------------------------------------------------------------*

   st->new_speech = st->old_speech + L_TOTAL - L_FRAME;   // New speech

   st->speech = st->new_speech - L_NEXT;                  // Present frame

   st->p_window = st->old_speech + L_TOTAL - L_WINDOW;    // For LPC window
   st->p_window_12k2 = st->p_window - L_NEXT; // EFR LPC window: no lookahead

   // Initialize static pointers

   st->wsp = st->old_wsp + PIT_MAX;
   st->exc = st->old_exc + PIT_MAX + L_INTERPOL;
   st->zero = st->ai_zero + MP1;
   st->error = st->mem_err + M;
   st->h1 = &st->hvec[L_SUBFR];

   // Static vectors to zero

   Set_zero(st->old_speech, L_TOTAL);
   Set_zero(st->old_exc,    PIT_MAX + L_INTERPOL);
   Set_zero(st->old_wsp,    PIT_MAX);
   Set_zero(st->mem_syn,    M);
   Set_zero(st->mem_w,      M);
   Set_zero(st->mem_w0,     M);
   Set_zero(st->mem_err,    M);
   Set_zero(st->zero,       L_SUBFR);
   Set_zero(st->hvec,       L_SUBFR);    // set to zero "h1[-L_SUBFR..-1]"

   // OL LTP states
   for (i = 0; i < 5; i++)
   {
      st->old_lags[i] = 40;
   }

   // Reset lpc states
   lpc_reset(st->lpcSt);

   // Reset lsp states
   lsp_reset(st->lspSt);

   // Reset clLtp states
   cl_ltp_reset(st->clLtpSt);

   gainQuant_reset(st->gainQuantSt);

   p_ol_wgh_reset(st->pitchOLWghtSt);

   ton_stab_reset(st->tonStabSt);

#ifndef VAD2
   vad1_reset(st->vadSt);
#else
   vad2_reset(st->vadSt);
#endif

   dtx_enc_reset(st->dtx_encSt);

   st->sharp = SHARPMIN;

   return 0;
}

------------------------------------------------------------------------------
 RESOURCES USED [optional]

 When the code is written for a specific target processor the
 the resources used should be documented below.

 HEAP MEMORY USED: x bytes

 STACK MEMORY USED: x bytes

 CLOCK CYCLES: (cycle count equation for this function) + (variable
                used to represent cycle count for each subroutine
                called)
     where: (cycle count variable) = cycle count for [subroutine
                                     name]

------------------------------------------------------------------------------
 CAUTION [optional]
 [State any special notes, constraints or cautions for users of this function]

------------------------------------------------------------------------------
*/

Word16 cod_amr_reset(cod_amrState *st)
{
    Word16 i;

    if (st == (cod_amrState *) NULL)
    {
        /* fprint(stderr, "cod_amr_reset: invalid parameter\n");  */
        return(-1);
    }

    /*-----------------------------------------------------------------------*
     *          Initialize pointers to speech vector.                        *
     *-----------------------------------------------------------------------*/

    st->new_speech = st->old_speech + L_TOTAL - L_FRAME;   /* New speech     */

    st->speech = st->new_speech - L_NEXT;                  /* Present frame  */

    st->p_window = st->old_speech + L_TOTAL - L_WINDOW;    /* For LPC window */
    st->p_window_12k2 = st->p_window - L_NEXT; /* EFR LPC window: no lookahead */

    /* Initialize static pointers */

    st->wsp = st->old_wsp + PIT_MAX;
    st->exc = st->old_exc + PIT_MAX + L_INTERPOL;
    st->zero = st->ai_zero + MP1;
    st->error = st->mem_err + M;
    st->h1 = &st->hvec[L_SUBFR];

    /* Initialize overflow Flag */

    st->overflow = 0;

    /* Static vectors to zero */
    memset(st->old_speech, 0, sizeof(Word16)*L_TOTAL);
    memset(st->old_exc, 0,    sizeof(Word16)*(PIT_MAX + L_INTERPOL));
    memset(st->old_wsp, 0,    sizeof(Word16)*PIT_MAX);
    memset(st->mem_syn, 0,    sizeof(Word16)*M);
    memset(st->mem_w,   0,    sizeof(Word16)*M);
    memset(st->mem_w0,  0,    sizeof(Word16)*M);
    memset(st->mem_err, 0,    sizeof(Word16)*M);
    memset(st->zero, 0,       sizeof(Word16)*L_SUBFR);
    memset(st->hvec, 0,       sizeof(Word16)*L_SUBFR);    /* set to zero "h1[-L_SUBFR..-1]" */

    /* OL LTP states */
    for (i = 0; i < 5; i++)
    {
        st->old_lags[i] = 40;
    }

    /* Reset lpc states */
    lpc_reset(st->lpcSt);

    /* Reset lsp states */
    lsp_reset(st->lspSt);

    /* Reset clLtp states */
    cl_ltp_reset(st->clLtpSt);

    gainQuant_reset(st->gainQuantSt);

    p_ol_wgh_reset(st->pitchOLWghtSt);

    ton_stab_reset(st->tonStabSt);

#ifndef VAD2
    vad1_reset(st->vadSt);
#else
    vad2_reset(st->vadSt);
#endif

    dtx_enc_reset(st->dtx_encSt);

    st->sharp = SHARPMIN;

    return(0);
}

/****************************************************************************/

/*
------------------------------------------------------------------------------
 FUNCTION NAME: cod_amr_exit
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    state = pointer to a pointer to a structure of type cod_amrState

 Outputs:
    state points to a NULL address

 Returns:
    None.

 Global Variables Used:
    None.

 Local Variables Needed:
    None.

------------------------------------------------------------------------------
 FUNCTION DESCRIPTION

 This function frees the memory used for state memory.

------------------------------------------------------------------------------
 REQUIREMENTS

 None.

------------------------------------------------------------------------------
 REFERENCES

 cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001

------------------------------------------------------------------------------
 PSEUDO-CODE

void cod_amr_exit (cod_amrState **state)
{
   if (state == NULL || *state == NULL)
      return;

   // dealloc members
   lpc_exit(&(*state)->lpcSt);
   lsp_exit(&(*state)->lspSt);
   gainQuant_exit(&(*state)->gainQuantSt);
   cl_ltp_exit(&(*state)->clLtpSt);
   p_ol_wgh_exit(&(*state)->pitchOLWghtSt);
   ton_stab_exit(&(*state)->tonStabSt);
#ifndef VAD2
   vad1_exit(&(*state)->vadSt);
#else
   vad2_exit(&(*state)->vadSt);
#endif
   dtx_enc_exit(&(*state)->dtx_encSt);

   // deallocate memory
   free(*state);
   *state = NULL;

   return;
}

------------------------------------------------------------------------------
 RESOURCES USED [optional]

 When the code is written for a specific target processor the
 the resources used should be documented below.

 HEAP MEMORY USED: x bytes

 STACK MEMORY USED: x bytes

 CLOCK CYCLES: (cycle count equation for this function) + (variable
                used to represent cycle count for each subroutine
                called)
     where: (cycle count variable) = cycle count for [subroutine
                                     name]

------------------------------------------------------------------------------
 CAUTION [optional]
 [State any special notes, constraints or cautions for users of this function]

------------------------------------------------------------------------------
*/

void cod_amr_exit(cod_amrState **state)
{
    if (state == NULL || *state == NULL)
    {
        return;
    }

    /* dealloc members */
    lpc_exit(&(*state)->lpcSt);
    lsp_exit(&(*state)->lspSt);
    gainQuant_exit(&(*state)->gainQuantSt);
    cl_ltp_exit(&(*state)->clLtpSt);
    p_ol_wgh_exit(&(*state)->pitchOLWghtSt);
    ton_stab_exit(&(*state)->tonStabSt);
#ifndef VAD2
    vad1_exit(&(*state)->vadSt);
#else
    vad2_exit(&(*state)->vadSt);
#endif
    dtx_enc_exit(&(*state)->dtx_encSt);

    /* deallocate memory */
    free(*state); // BX
    *state = NULL;

    return;
}

/****************************************************************************/

/*
------------------------------------------------------------------------------
 FUNCTION NAME: cod_amr_first
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    st = pointer to a structure of type cod_amrState
    new_speech = pointer to buffer of length L_FRAME that contains
                 the speech input (Word16)

 Outputs:
    The structure of type cod_amrState pointed to by st is updated.

 Returns:
    return_value = 0 (int)

 Global Variables Used:
    None.

 Local Variables Needed:
    None.

------------------------------------------------------------------------------
 FUNCTION DESCRIPTION

 This function copes with look-ahead and calls cod_amr.
 No input argument are passed to this function. However, before
 calling this function, 40 new speech data should be copied to the
 vector new_speech[]. This is a global pointer which is declared in
 this file (it points to the end of speech buffer minus 200).

------------------------------------------------------------------------------
 REQUIREMENTS

 None.

------------------------------------------------------------------------------
 REFERENCES

 cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001

------------------------------------------------------------------------------
 PSEUDO-CODE

int cod_amr_first(cod_amrState *st,     // i/o : State struct
                  Word16 new_speech[])  // i   : speech input (L_FRAME)
{
   Copy(new_speech,&st->new_speech[-L_NEXT], L_NEXT);
   //   Copy(new_speech,st->new_speech,L_FRAME);

   return 0;
}

------------------------------------------------------------------------------
 RESOURCES USED [optional]

 When the code is written for a specific target processor the
 the resources used should be documented below.

 HEAP MEMORY USED: x bytes

 STACK MEMORY USED: x bytes

 CLOCK CYCLES: (cycle count equation for this function) + (variable
                used to represent cycle count for each subroutine
                called)
     where: (cycle count variable) = cycle count for [subroutine
                                     name]

------------------------------------------------------------------------------
 CAUTION [optional]
 [State any special notes, constraints or cautions for users of this function]

------------------------------------------------------------------------------
*/

Word16 cod_amr_first(cod_amrState *st,     /* i/o : State struct           */
                     Word16 new_speech[])  /* i   : speech input (L_FRAME) */
{

    memcpy(&st->new_speech[-L_NEXT], new_speech, L_NEXT*sizeof(Word16));

    /*   Copy(new_speech,st->new_speech,L_FRAME); */

    return(0);
}

/****************************************************************************/

/*
------------------------------------------------------------------------------
 FUNCTION NAME: cod_amr
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    st = pointer to a structure of type cod_amrState
    mode = AMR mode of type enum Mode
    new_speech = pointer to buffer of length L_FRAME that contains
             the speech input of type Word16
    ana = pointer to the analysis parameters of type Word16
    usedMode = pointer to the used mode of type enum Mode
    synth = pointer to a buffer containing the local synthesis speech of
        type Word16

 Outputs:
    The structure of type cod_amrState pointed to by st is updated.
    The analysis parameter buffer pointed to by ana is updated.
    The value pointed to by usedMode is updated.
    The local synthesis speech buffer pointed to by synth is updated.

 Returns:
    return_value = 0 (int)

 Global Variables Used:
    None.

 Local Variables Needed:
    None.

------------------------------------------------------------------------------
 FUNCTION DESCRIPTION

 This function is the main encoder routine. It is called every 20 ms speech
 frame, operating on the newly read 160 speech samples. It performs the
 principle encoding functions to produce the set of encoded parameters
 which include the LSP, adaptive codebook, and fixed codebook
 quantization indices (addresses and gains).

 Before calling this function, 160 new speech data should be copied to the
 vector new_speech[]. This is a global pointer which is declared in
 this file (it points to the end of speech buffer minus 160).

 The outputs of the function are:
     ana[]:     vector of analysis parameters.
     synth[]:   Local synthesis speech (for debugging purposes)

------------------------------------------------------------------------------
 REQUIREMENTS

 None.

------------------------------------------------------------------------------
 REFERENCES

 cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001

------------------------------------------------------------------------------
 PSEUDO-CODE

int cod_amr(
    cod_amrState *st,          // i/o : State struct
    enum Mode mode,            // i   : AMR mode
    Word16 new_speech[],       // i   : speech input (L_FRAME)
    Word16 ana[],              // o   : Analysis parameters
    enum Mode *usedMode,       // o   : used mode
    Word16 synth[]             // o   : Local synthesis
)
{
   // LPC coefficients
   Word16 A_t[(MP1) * 4];      // A(z) unquantized for the 4 subframes
   Word16 Aq_t[(MP1) * 4];     // A(z)   quantized for the 4 subframes
   Word16 *A, *Aq;             // Pointer on A_t and Aq_t
   Word16 lsp_new[M];

   // Other vectors
   Word16 xn[L_SUBFR];         // Target vector for pitch search
   Word16 xn2[L_SUBFR];        // Target vector for codebook search
   Word16 code[L_SUBFR];       // Fixed codebook excitation
   Word16 y1[L_SUBFR];         // Filtered adaptive excitation
   Word16 y2[L_SUBFR];         // Filtered fixed codebook excitation
   Word16 gCoeff[6];           // Correlations between xn, y1, & y2:
   Word16 res[L_SUBFR];        // Short term (LPC) prediction residual
   Word16 res2[L_SUBFR];       // Long term (LTP) prediction residual

   // Vector and scalars needed for the MR475
   Word16 xn_sf0[L_SUBFR];     // Target vector for pitch search
   Word16 y2_sf0[L_SUBFR];     // Filtered codebook innovation
   Word16 code_sf0[L_SUBFR];   // Fixed codebook excitation
   Word16 h1_sf0[L_SUBFR];     // The impulse response of sf0
   Word16 mem_syn_save[M];     // Filter memory
   Word16 mem_w0_save[M];      // Filter memory
   Word16 mem_err_save[M];     // Filter memory
   Word16 sharp_save;          // Sharpening
   Word16 evenSubfr;           // Even subframe indicator
   Word16 T0_sf0 = 0;          // Integer pitch lag of sf0
   Word16 T0_frac_sf0 = 0;     // Fractional pitch lag of sf0
   Word16 i_subfr_sf0 = 0;     // Position in exc[] for sf0
   Word16 gain_pit_sf0;        // Quantized pitch gain for sf0
   Word16 gain_code_sf0;       // Quantized codebook gain for sf0

   // Scalars
   Word16 i_subfr, subfrNr;
   Word16 T_op[L_FRAME/L_FRAME_BY2];
   Word16 T0, T0_frac;
   Word16 gain_pit, gain_code;

   // Flags
   Word16 lsp_flag = 0;        // indicates resonance in LPC filter
   Word16 gp_limit;            // pitch gain limit value
   Word16 vad_flag;            // VAD decision flag
   Word16 compute_sid_flag;    // SID analysis  flag

   Copy(new_speech, st->new_speech, L_FRAME);

   *usedMode = mode;

   // DTX processing
   if (st->dtx)
   {  // no test() call since this if is only in simulation env
      // Find VAD decision

#ifdef  VAD2
      vad_flag = vad2 (st->new_speech,    st->vadSt);
      vad_flag = vad2 (st->new_speech+80, st->vadSt) || vad_flag;
#else
      vad_flag = vad1(st->vadSt, st->new_speech);
#endif

      // NB! usedMode may change here
      compute_sid_flag = tx_dtx_handler(st->dtx_encSt,
                                        vad_flag,
                                        usedMode);
   }
   else
   {
      compute_sid_flag = 0;
   }

    *------------------------------------------------------------------------*
    *  - Perform LPC analysis:                                               *
    *       * autocorrelation + lag windowing                                *
    *       * Levinson-durbin algorithm to find a[]                          *
    *       * convert a[] to lsp[]                                           *
    *       * quantize and code the LSPs                                     *
    *       * find the interpolated LSPs and convert to a[] for all          *
    *         subframes (both quantized and unquantized)                     *
    *------------------------------------------------------------------------*

   // LP analysis
   lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t);

   // From A(z) to lsp. LSP quantization and interpolation
   lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana);

   // Buffer lsp's and energy
   dtx_buffer(st->dtx_encSt,
          lsp_new,
          st->new_speech);

   // Check if in DTX mode
   if (sub(*usedMode, MRDTX) == 0)
   {
      dtx_enc(st->dtx_encSt,
              compute_sid_flag,
              st->lspSt->qSt,
              st->gainQuantSt->gc_predSt,
              &ana);

      Set_zero(st->old_exc,    PIT_MAX + L_INTERPOL);
      Set_zero(st->mem_w0,     M);
      Set_zero(st->mem_err,    M);
      Set_zero(st->zero,       L_SUBFR);
      Set_zero(st->hvec,       L_SUBFR);    // set to zero "h1[-L_SUBFR..-1]"
      // Reset lsp states
      lsp_reset(st->lspSt);
      Copy(lsp_new, st->lspSt->lsp_old, M);
      Copy(lsp_new, st->lspSt->lsp_old_q, M);

      // Reset clLtp states
      cl_ltp_reset(st->clLtpSt);
      st->sharp = SHARPMIN;
   }
   else
   {
       // check resonance in the filter
      lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old);
   }

    *----------------------------------------------------------------------*
    * - Find the weighted input speech w_sp[] for the whole speech frame   *
    * - Find the open-loop pitch delay for first 2 subframes               *
    * - Set the range for searching closed-loop pitch in 1st subframe      *
    * - Find the open-loop pitch delay for last 2 subframes                *
    *----------------------------------------------------------------------*

#ifdef VAD2
   if (st->dtx)
   {  // no test() call since this if is only in simulation env
       st->vadSt->L_Rmax = 0;
       st->vadSt->L_R0 = 0;
   }
#endif
   for(subfrNr = 0, i_subfr = 0;
       subfrNr < L_FRAME/L_FRAME_BY2;
       subfrNr++, i_subfr += L_FRAME_BY2)
   {
      // Pre-processing on 80 samples
      pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech,
              st->mem_w, st->wsp);

      if ((sub(mode, MR475) != 0) && (sub(mode, MR515) != 0))
      {
         // Find open loop pitch lag for two subframes
         ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr],
                &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr,
                st->dtx);
      }
   }

   if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0))
   {
      // Find open loop pitch lag for ONE FRAME ONLY
      // search on 160 samples

      ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0],
             st->old_lags, st->ol_gain_flg, 1, st->dtx);
      T_op[1] = T_op[0];
   }

#ifdef VAD2
   if (st->dtx)
   {  // no test() call since this if is only in simulation env
      LTP_flag_update(st->vadSt, mode);
   }
#endif

#ifndef VAD2
   // run VAD pitch detection
   if (st->dtx)
   {  // no test() call since this if is only in simulation env
      vad_pitch_detection(st->vadSt, T_op);
   }
#endif

   if (sub(*usedMode, MRDTX) == 0)
   {
      goto the_end;
   }

    *------------------------------------------------------------------------*
    *          Loop for every subframe in the analysis frame                 *
    *------------------------------------------------------------------------*
    *  To find the pitch and innovation parameters. The subframe size is     *
    *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
    *     - find the weighted LPC coefficients                               *
    *     - find the LPC residual signal res[]                               *
    *     - compute the target signal for pitch search                       *
    *     - compute impulse response of weighted synthesis filter (h1[])     *
    *     - find the closed-loop pitch parameters                            *
    *     - encode the pitch dealy                                           *
    *     - update the impulse response h1[] by including fixed-gain pitch   *
    *     - find target vector for codebook search                           *
    *     - codebook search                                                  *
    *     - encode codebook address                                          *
    *     - VQ of pitch and codebook gains                                   *
    *     - find synthesis speech                                            *
    *     - update states of weighting filter                                *
    *------------------------------------------------------------------------*

   A = A_t;      // pointer to interpolated LPC parameters
   Aq = Aq_t;    // pointer to interpolated quantized LPC parameters

   evenSubfr = 0;
   subfrNr = -1;
   for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
   {
      subfrNr = add(subfrNr, 1);
      evenSubfr = sub(1, evenSubfr);

      // Save states for the MR475 mode
      if ((evenSubfr != 0) && (sub(*usedMode, MR475) == 0))
      {
         Copy(st->mem_syn, mem_syn_save, M);
         Copy(st->mem_w0, mem_w0_save, M);
         Copy(st->mem_err, mem_err_save, M);
         sharp_save = st->sharp;
      }

       *-----------------------------------------------------------------*
       * - Preprocessing of subframe                                     *
       *-----------------------------------------------------------------*
      if (sub(*usedMode, MR475) != 0)
      {
         subframePreProc(*usedMode, gamma1, gamma1_12k2,
                         gamma2, A, Aq, &st->speech[i_subfr],
                         st->mem_err, st->mem_w0, st->zero,
                         st->ai_zero, &st->exc[i_subfr],
                         st->h1, xn, res, st->error);
      }
      else
      { // MR475
         subframePreProc(*usedMode, gamma1, gamma1_12k2,
                         gamma2, A, Aq, &st->speech[i_subfr],
                         st->mem_err, mem_w0_save, st->zero,
                         st->ai_zero, &st->exc[i_subfr],
                         st->h1, xn, res, st->error);

         // save impulse response (modified in cbsearch)
         if (evenSubfr != 0)
         {
             Copy (st->h1, h1_sf0, L_SUBFR);
         }
      }

      // copy the LP residual (res2 is modified in the CL LTP search)
      Copy (res, res2, L_SUBFR);

       *-----------------------------------------------------------------*
       * - Closed-loop LTP search                                        *
       *-----------------------------------------------------------------*
      cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1,
             &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1,
             &T0, &T0_frac, &gain_pit, gCoeff, &ana,
             &gp_limit);

      // update LTP lag history
      if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0))
      {
         st->old_lags[1] = T0;
      }

      if ((sub(subfrNr, 3) == 0) && (st->ol_gain_flg[1] > 0))
      {
         st->old_lags[0] = T0;
      }

       *-----------------------------------------------------------------*
       * - Inovative codebook search (find index and gain)               *
       *-----------------------------------------------------------------*
      cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2,
               code, y2, &ana, *usedMode, subfrNr);

       *------------------------------------------------------*
       * - Quantization of gains.                             *
       *------------------------------------------------------*
      gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code,
                xn, xn2,  y1, y2, gCoeff, evenSubfr, gp_limit,
                &gain_pit_sf0, &gain_code_sf0,
                &gain_pit, &gain_code, &ana);

      // update gain history
      update_gp_clipping(st->tonStabSt, gain_pit);

      if (sub(*usedMode, MR475) != 0)
      {
         // Subframe Post Porcessing
         subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                          gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn,
                          st->mem_err, st->mem_w0, st->exc, &st->sharp);
      }
      else
      {
         if (evenSubfr != 0)
         {
            i_subfr_sf0 = i_subfr;
            Copy(xn, xn_sf0, L_SUBFR);
            Copy(y2, y2_sf0, L_SUBFR);
            Copy(code, code_sf0, L_SUBFR);
            T0_sf0 = T0;
            T0_frac_sf0 = T0_frac;

            // Subframe Post Porcessing
            subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                             gain_code, Aq, synth, xn, code, y1, y2,
                             mem_syn_save, st->mem_err, mem_w0_save,
                             st->exc, &st->sharp);
            st->sharp = sharp_save;
         }
         else
         {
            // update both subframes for the MR475

            // Restore states for the MR475 mode
            Copy(mem_err_save, st->mem_err, M);

            // re-build excitation for sf 0
            Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0,
                         L_SUBFR, 1);
            Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR);

            Aq -= MP1;
            subframePostProc(st->speech, *usedMode, i_subfr_sf0,
                             gain_pit_sf0, gain_code_sf0, Aq,
                             synth, xn_sf0, code_sf0, y1, y2_sf0,
                             st->mem_syn, st->mem_err, st->mem_w0, st->exc,
                             &sharp_save); // overwrites sharp_save
            Aq += MP1;

            // re-run pre-processing to get xn right (needed by postproc)
            // (this also reconstructs the unsharpened h1 for sf 1)
            subframePreProc(*usedMode, gamma1, gamma1_12k2,
                            gamma2, A, Aq, &st->speech[i_subfr],
                            st->mem_err, st->mem_w0, st->zero,
                            st->ai_zero, &st->exc[i_subfr],
                            st->h1, xn, res, st->error);

            // re-build excitation sf 1 (changed if lag < L_SUBFR)
            Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1);
            Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR);

            subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                             gain_code, Aq, synth, xn, code, y1, y2,
                             st->mem_syn, st->mem_err, st->mem_w0,
                             st->exc, &st->sharp);
         }
      }

      A += MP1;    // interpolated LPC parameters for next subframe
      Aq += MP1;
   }

   Copy(&st->old_exc[L_FRAME], &st->old_exc[0], PIT_MAX + L_INTERPOL);

the_end:

    *--------------------------------------------------*
    * Update signal for next frame.                    *
    *--------------------------------------------------*
   Copy(&st->old_wsp[L_FRAME], &st->old_wsp[0], PIT_MAX);

   Copy(&st->old_speech[L_FRAME], &st->old_speech[0], L_TOTAL - L_FRAME);

   return 0;
}
------------------------------------------------------------------------------
 RESOURCES USED [optional]

 When the code is written for a specific target processor the
 the resources used should be documented below.

 HEAP MEMORY USED: x bytes

 STACK MEMORY USED: x bytes

 CLOCK CYCLES: (cycle count equation for this function) + (variable
                used to represent cycle count for each subroutine
                called)
     where: (cycle count variable) = cycle count for [subroutine
                                     name]

------------------------------------------------------------------------------
 CAUTION [optional]
 [State any special notes, constraints or cautions for users of this function]

------------------------------------------------------------------------------
*/

Word16 cod_amr(
    cod_amrState *st,          /* i/o : State struct                   */
    enum Mode mode,            /* i   : AMR mode                       */
    Word16 new_speech[],       /* i   : speech input (L_FRAME)         */
    Word16 ana[],              /* o   : Analysis parameters            */
    enum Mode *usedMode,       /* o   : used mode                      */
    Word16 synth[]            /* o   : Local synthesis                */
)
{
    /* LPC coefficients */
    Word16 A_t[(MP1) * 4];      /* A(z) unquantized for the 4 subframes */
    Word16 Aq_t[(MP1) * 4];     /* A(z)   quantized for the 4 subframes */
    Word16 *A, *Aq;             /* Pointer on A_t and Aq_t              */
    Word16 lsp_new[M];

    /* Other vectors */
    Word16 xn[L_SUBFR];         /* Target vector for pitch search       */
    Word16 xn2[L_SUBFR];        /* Target vector for codebook search    */
    Word16 code[L_SUBFR];       /* Fixed codebook excitation            */
    Word16 y1[L_SUBFR];         /* Filtered adaptive excitation         */
    Word16 y2[L_SUBFR];         /* Filtered fixed codebook excitation   */
    Word16 gCoeff[6];           /* Correlations between xn, y1, & y2:   */
    Word16 res[L_SUBFR];        /* Short term (LPC) prediction residual */
    Word16 res2[L_SUBFR];       /* Long term (LTP) prediction residual  */

    /* Vector and scalars needed for the MR475 */
    Word16 xn_sf0[L_SUBFR];     /* Target vector for pitch search       */
    Word16 y2_sf0[L_SUBFR];     /* Filtered codebook innovation         */
    Word16 code_sf0[L_SUBFR];   /* Fixed codebook excitation            */
    Word16 h1_sf0[L_SUBFR];     /* The impulse response of sf0          */
    Word16 mem_syn_save[M];     /* Filter memory                        */
    Word16 mem_w0_save[M];      /* Filter memory                        */
    Word16 mem_err_save[M];     /* Filter memory                        */
    Word16 sharp_save;          /* Sharpening                           */
    Word16 evenSubfr;           /* Even subframe indicator              */
    Word16 T0_sf0 = 0;          /* Integer pitch lag of sf0             */
    Word16 T0_frac_sf0 = 0;     /* Fractional pitch lag of sf0          */
    Word16 i_subfr_sf0 = 0;     /* Position in exc[] for sf0            */
    Word16 gain_pit_sf0;        /* Quantized pitch gain for sf0         */
    Word16 gain_code_sf0;       /* Quantized codebook gain for sf0      */

    /* Scalars */
    Word16 i_subfr, subfrNr;
    Word16 T_op[L_FRAME/L_FRAME_BY2];
    Word16 T0, T0_frac;
    Word16 gain_pit, gain_code;

    /* Flags */
    Word16 lsp_flag = 0;        /* indicates resonance in LPC filter    */
    Word16 gp_limit;            /* pitch gain limit value               */
    Word16 vad_flag;            /* VAD decision flag                    */
    Word16 compute_sid_flag;    /* SID analysis  flag                   */
    Flag   *pOverflow = &(st->overflow);     /* Overflow flag            */

    memcpy(st->new_speech, new_speech, L_FRAME*sizeof(Word16));

    *usedMode = mode;

    /* DTX processing */
    if (st->dtx)
    {
        /* Find VAD decision */
#ifdef  VAD2
        vad_flag = vad2(st->new_speech,    st->vadSt, pOverflow);
        vad_flag = vad2(st->new_speech + 80, st->vadSt, pOverflow) || vad_flag;
#else
        vad_flag = vad1(st->vadSt, st->new_speech, pOverflow);
#endif

        /* NB! usedMode may change here */
        compute_sid_flag = tx_dtx_handler(st->dtx_encSt,
                                          vad_flag,
                                          usedMode, pOverflow);
    }
    else
    {
        compute_sid_flag = 0;
    }

    /*------------------------------------------------------------------------*
    *  - Perform LPC analysis:                                               *
    *       * autocorrelation + lag windowing                                *
    *       * Levinson-durbin algorithm to find a[]                          *
    *       * convert a[] to lsp[]                                           *
    *       * quantize and code the LSPs                                     *
    *       * find the interpolated LSPs and convert to a[] for all          *
    *         subframes (both quantized and unquantized)                     *
    *------------------------------------------------------------------------*/

    /* LP analysis */
    lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t, pOverflow);

    /* From A(z) to lsp. LSP quantization and interpolation */
    lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana, pOverflow);

    /* Buffer lsp's and energy */
    dtx_buffer(st->dtx_encSt,
               lsp_new,
               st->new_speech, pOverflow);

    /* Check if in DTX mode */

    if (*usedMode == MRDTX)
    {
        dtx_enc(st->dtx_encSt,
                compute_sid_flag,
                st->lspSt->qSt,
                &(st->gainQuantSt->gc_predSt),
                &ana, pOverflow);

        memset(st->old_exc, 0,   sizeof(Word16)*(PIT_MAX + L_INTERPOL));
        memset(st->mem_w0,  0,   sizeof(Word16)*M);
        memset(st->mem_err, 0,   sizeof(Word16)*M);
        memset(st->zero,    0,   sizeof(Word16)*L_SUBFR);
        memset(st->hvec,    0,   sizeof(Word16)*L_SUBFR);    /* set to zero "h1[-L_SUBFR..-1]" */
        /* Reset lsp states */
        lsp_reset(st->lspSt);

        memcpy(st->lspSt->lsp_old,   lsp_new, M*sizeof(Word16));
        memcpy(st->lspSt->lsp_old_q, lsp_new, M*sizeof(Word16));

        /* Reset clLtp states */
        cl_ltp_reset(st->clLtpSt);
        st->sharp = SHARPMIN;
    }
    else
    {
        /* check resonance in the filter */
        lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old, pOverflow);
    }

    /*----------------------------------------------------------------------*
    * - Find the weighted input speech w_sp[] for the whole speech frame   *
    * - Find the open-loop pitch delay for first 2 subframes               *
    * - Set the range for searching closed-loop pitch in 1st subframe      *
    * - Find the open-loop pitch delay for last 2 subframes                *
    *----------------------------------------------------------------------*/

#ifdef VAD2
    if (st->dtx)
    {
        st->vadSt->L_Rmax = 0;
        st->vadSt->L_R0 = 0;
    }
#endif

    for (subfrNr = 0, i_subfr = 0;
            subfrNr < L_FRAME / L_FRAME_BY2;
            subfrNr++, i_subfr += L_FRAME_BY2)
    {
        /* Pre-processing on 80 samples */
        pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech,
                st->mem_w, st->wsp, pOverflow);

        if ((mode != MR475) && (mode != MR515))
        {
            /* Find open loop pitch lag for two subframes */
            ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr],
                   &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr,
                   st->dtx, pOverflow);
        }
    }

    if ((mode == MR475) || (mode == MR515))
    {
        /* Find open loop pitch lag for ONE FRAME ONLY */
        /* search on 160 samples */

        ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0],
               st->old_lags, st->ol_gain_flg, 1, st->dtx, pOverflow);
        T_op[1] = T_op[0];
    }

#ifdef VAD2
    if (st->dtx)
    {
        LTP_flag_update(st->vadSt, (Word16) mode, pOverflow);
    }
#endif

#ifndef VAD2
    /* run VAD pitch detection */
    if (st->dtx)
    {
        vad_pitch_detection(st->vadSt, T_op, pOverflow);
    }
#endif

    if (*usedMode == MRDTX)
    {
        goto the_end;
    }

    /*------------------------------------------------------------------------*
    *          Loop for every subframe in the analysis frame                 *
    *------------------------------------------------------------------------*
    *  To find the pitch and innovation parameters. The subframe size is     *
    *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
    *     - find the weighted LPC coefficients                               *
    *     - find the LPC residual signal res[]                               *
    *     - compute the target signal for pitch search                       *
    *     - compute impulse response of weighted synthesis filter (h1[])     *
    *     - find the closed-loop pitch parameters                            *
    *     - encode the pitch dealy                                           *
    *     - update the impulse response h1[] by including fixed-gain pitch   *
    *     - find target vector for codebook search                           *
    *     - codebook search                                                  *
    *     - encode codebook address                                          *
    *     - VQ of pitch and codebook gains                                   *
    *     - find synthesis speech                                            *
    *     - update states of weighting filter                                *
    *------------------------------------------------------------------------*/

    A = A_t;      /* pointer to interpolated LPC parameters */
    Aq = Aq_t;    /* pointer to interpolated quantized LPC parameters */

    evenSubfr = 0;
    subfrNr = -1;
    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
    {
        subfrNr++;
        evenSubfr = 1 - evenSubfr;

        /* Save states for the MR475 mode */

        if ((evenSubfr != 0) && (*usedMode == MR475))
        {
            memcpy(mem_syn_save, st->mem_syn, M*sizeof(Word16));
            memcpy(mem_w0_save, st->mem_w0, M*sizeof(Word16));
            memcpy(mem_err_save, st->mem_err, M*sizeof(Word16));

            sharp_save = st->sharp;
        }

        /*-----------------------------------------------------------------*
        * - Preprocessing of subframe                                     *
        *-----------------------------------------------------------------*/

        if (*usedMode != MR475)
        {
            subframePreProc(*usedMode, gamma1, gamma1_12k2,
                            gamma2, A, Aq, &st->speech[i_subfr],
                            st->mem_err, st->mem_w0, st->zero,
                            st->ai_zero, &st->exc[i_subfr],
                            st->h1, xn, res, st->error);
        }
        else
        { /* MR475 */
            subframePreProc(*usedMode, gamma1, gamma1_12k2,
                            gamma2, A, Aq, &st->speech[i_subfr],
                            st->mem_err, mem_w0_save, st->zero,
                            st->ai_zero, &st->exc[i_subfr],
                            st->h1, xn, res, st->error);

            /* save impulse response (modified in cbsearch) */

            if (evenSubfr != 0)
            {
                memcpy(h1_sf0, st->h1, L_SUBFR*sizeof(Word16));

            }
        }

        /* copy the LP residual (res2 is modified in the CL LTP search)    */
        memcpy(res2, res, L_SUBFR*sizeof(Word16));

        /*-----------------------------------------------------------------*
        * - Closed-loop LTP search                                        *
        *-----------------------------------------------------------------*/
        cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1,
               &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1,
               &T0, &T0_frac, &gain_pit, gCoeff, &ana,
               &gp_limit, pOverflow);

        /* update LTP lag history */

        if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0))
        {
            st->old_lags[1] = T0;
        }

        if ((subfrNr == 3) && (st->ol_gain_flg[1] > 0))
        {
            st->old_lags[0] = T0;
        }

        /*-----------------------------------------------------------------*
        * - Inovative codebook search (find index and gain)               *
        *-----------------------------------------------------------------*/
        cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2,
                 code, y2, &ana, *usedMode, subfrNr, pOverflow);

        /*------------------------------------------------------*
        * - Quantization of gains.                             *
        *------------------------------------------------------*/
        gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code,
                  xn, xn2,  y1, y2, gCoeff, evenSubfr, gp_limit,
                  &gain_pit_sf0, &gain_code_sf0,
                  &gain_pit, &gain_code, &ana, pOverflow);

        /* update gain history */
        update_gp_clipping(st->tonStabSt, gain_pit, pOverflow);

        if (*usedMode != MR475)
        {
            /* Subframe Post Porcessing */
            subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                             gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn,
                             st->mem_err, st->mem_w0, st->exc, &st->sharp, pOverflow);
        }
        else
        {

            if (evenSubfr != 0)
            {
                i_subfr_sf0 = i_subfr;

                memcpy(xn_sf0, xn, L_SUBFR*sizeof(Word16));
                memcpy(y2_sf0, y2, L_SUBFR*sizeof(Word16));
                memcpy(code_sf0, code, L_SUBFR*sizeof(Word16));

                T0_sf0 = T0;
                T0_frac_sf0 = T0_frac;

                /* Subframe Post Porcessing */
                subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                                 gain_code, Aq, synth, xn, code, y1, y2,
                                 mem_syn_save, st->mem_err, mem_w0_save,
                                 st->exc, &st->sharp, pOverflow);
                st->sharp = sharp_save;
            }
            else
            {
                /* update both subframes for the MR475 */

                /* Restore states for the MR475 mode */
                memcpy(st->mem_err, mem_err_save, M*sizeof(Word16));

                /* re-build excitation for sf 0 */
                Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0,
                             L_SUBFR, 1, pOverflow);
                Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR);

                Aq -= MP1;
                subframePostProc(st->speech, *usedMode, i_subfr_sf0,
                                 gain_pit_sf0, gain_code_sf0, Aq,
                                 synth, xn_sf0, code_sf0, y1, y2_sf0,
                                 st->mem_syn, st->mem_err, st->mem_w0, st->exc,
                                 &sharp_save, pOverflow); /* overwrites sharp_save */
                Aq += MP1;

                /* re-run pre-processing to get xn right (needed by postproc) */
                /* (this also reconstructs the unsharpened h1 for sf 1)       */
                subframePreProc(*usedMode, gamma1, gamma1_12k2,
                                gamma2, A, Aq, &st->speech[i_subfr],
                                st->mem_err, st->mem_w0, st->zero,
                                st->ai_zero, &st->exc[i_subfr],
                                st->h1, xn, res, st->error);

                /* re-build excitation sf 1 (changed if lag < L_SUBFR) */
                Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1, pOverflow);
                Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR);

                subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                                 gain_code, Aq, synth, xn, code, y1, y2,
                                 st->mem_syn, st->mem_err, st->mem_w0,
                                 st->exc, &st->sharp, pOverflow);
            }
        }

        A += MP1;    /* interpolated LPC parameters for next subframe */
        Aq += MP1;
    }

    memcpy(&st->old_exc[0], &st->old_exc[L_FRAME], (PIT_MAX + L_INTERPOL)*sizeof(Word16));

the_end:

    /*--------------------------------------------------*
    * Update signal for next frame.                    *
    *--------------------------------------------------*/

    memcpy(&st->old_wsp[0], &st->old_wsp[L_FRAME], PIT_MAX*sizeof(Word16));
    memcpy(&st->old_speech[0], &st->old_speech[L_FRAME], (L_TOTAL - L_FRAME)*sizeof(Word16));

    return(0);
}

redpajama_set_name: RedPajamaGithub