153a5a1b3Sopenharmony_ci/* Copyright (C) 2007 Psi Systems, Inc.
253a5a1b3Sopenharmony_ci   Author:  Jean-Marc Valin
353a5a1b3Sopenharmony_ci   File: os_support_custom.h
453a5a1b3Sopenharmony_ci   Memory Allocation overrides to allow user control rather than C alloc/free.
553a5a1b3Sopenharmony_ci
653a5a1b3Sopenharmony_ci   Redistribution and use in source and binary forms, with or without
753a5a1b3Sopenharmony_ci   modification, are permitted provided that the following conditions
853a5a1b3Sopenharmony_ci   are met:
953a5a1b3Sopenharmony_ci
1053a5a1b3Sopenharmony_ci   - Redistributions of source code must retain the above copyright
1153a5a1b3Sopenharmony_ci   notice, this list of conditions and the following disclaimer.
1253a5a1b3Sopenharmony_ci
1353a5a1b3Sopenharmony_ci   - Redistributions in binary form must reproduce the above copyright
1453a5a1b3Sopenharmony_ci   notice, this list of conditions and the following disclaimer in the
1553a5a1b3Sopenharmony_ci   documentation and/or other materials provided with the distribution.
1653a5a1b3Sopenharmony_ci
1753a5a1b3Sopenharmony_ci   - Neither the name of the Xiph.org Foundation nor the names of its
1853a5a1b3Sopenharmony_ci   contributors may be used to endorse or promote products derived from
1953a5a1b3Sopenharmony_ci   this software without specific prior written permission.
2053a5a1b3Sopenharmony_ci
2153a5a1b3Sopenharmony_ci   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2253a5a1b3Sopenharmony_ci   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2353a5a1b3Sopenharmony_ci   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2453a5a1b3Sopenharmony_ci   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
2553a5a1b3Sopenharmony_ci   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2653a5a1b3Sopenharmony_ci   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2753a5a1b3Sopenharmony_ci   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2853a5a1b3Sopenharmony_ci   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2953a5a1b3Sopenharmony_ci   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3053a5a1b3Sopenharmony_ci   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3153a5a1b3Sopenharmony_ci   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3253a5a1b3Sopenharmony_ci*/
3353a5a1b3Sopenharmony_ci
3453a5a1b3Sopenharmony_ci#ifdef MANUAL_ALLOC
3553a5a1b3Sopenharmony_ci
3653a5a1b3Sopenharmony_ci/* To avoid changing the Speex call model, this file relies on four static variables
3753a5a1b3Sopenharmony_ci   The user main creates two linear buffers, and initializes spxGlobalHeap/ScratchPtr
3853a5a1b3Sopenharmony_ci   to point to the start of the two buffers, and initializes spxGlobalHeap/ScratchEnd
3953a5a1b3Sopenharmony_ci   to point to the first address following the last byte of the two buffers.
4053a5a1b3Sopenharmony_ci
4153a5a1b3Sopenharmony_ci   This mechanism allows, for example, data caching for multichannel applications,
4253a5a1b3Sopenharmony_ci   where the Speex state is swapped from a large slow memory to a small fast memory
4353a5a1b3Sopenharmony_ci   each time the codec runs.
4453a5a1b3Sopenharmony_ci
4553a5a1b3Sopenharmony_ci   Persistent data is allocated in spxGlobalHeap (instead of calloc), while scratch
4653a5a1b3Sopenharmony_ci   data is allocated in spxGlobalScratch.
4753a5a1b3Sopenharmony_ci*/
4853a5a1b3Sopenharmony_ci
4953a5a1b3Sopenharmony_ciextern char *spxGlobalHeapPtr, *spxGlobalHeapEnd;
5053a5a1b3Sopenharmony_ciextern char *spxGlobalScratchPtr, *spxGlobalScratchEnd;
5153a5a1b3Sopenharmony_ci
5253a5a1b3Sopenharmony_ci/* Make sure that all structures are aligned to largest type */
5353a5a1b3Sopenharmony_ci#define BLOCK_MASK      (sizeof(long double)-1)
5453a5a1b3Sopenharmony_ciextern inline void speex_warning(const char *str);
5553a5a1b3Sopenharmony_ci
5653a5a1b3Sopenharmony_ci#define OVERRIDE_SPEEX_ALLOC
5753a5a1b3Sopenharmony_cistatic inline void *speex_alloc (int size)
5853a5a1b3Sopenharmony_ci{
5953a5a1b3Sopenharmony_ci    void *ptr;
6053a5a1b3Sopenharmony_ci
6153a5a1b3Sopenharmony_ci    ptr = (void *) (((int)spxGlobalHeapPtr + BLOCK_MASK) & ~BLOCK_MASK);  //Start on 8 boundary
6253a5a1b3Sopenharmony_ci
6353a5a1b3Sopenharmony_ci    spxGlobalHeapPtr = (char *)((int)ptr + size);	// Update pointer to next free location
6453a5a1b3Sopenharmony_ci
6553a5a1b3Sopenharmony_ci    if (spxGlobalHeapPtr > spxGlobalHeapEnd )
6653a5a1b3Sopenharmony_ci    {
6753a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
6853a5a1b3Sopenharmony_ci	    fprintf (stderr, "insufficient space for persistent alloc request %d bytes\n", size);
6953a5a1b3Sopenharmony_ci#endif
7053a5a1b3Sopenharmony_ci       return 0;
7153a5a1b3Sopenharmony_ci    }
7253a5a1b3Sopenharmony_ci
7353a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
7453a5a1b3Sopenharmony_ci    fprintf (stderr, "Persist Allocated %d chars at %x, %d remaining\n", size, ptr, ((int)spxGlobalHeapEnd - (int)spxGlobalHeapPtr));
7553a5a1b3Sopenharmony_ci#endif
7653a5a1b3Sopenharmony_ci    memset(ptr, 0, size);
7753a5a1b3Sopenharmony_ci    return ptr;
7853a5a1b3Sopenharmony_ci}
7953a5a1b3Sopenharmony_ci
8053a5a1b3Sopenharmony_ci#define OVERRIDE_SPEEX_ALLOC_SCRATCH
8153a5a1b3Sopenharmony_cistatic inline void *speex_alloc_scratch (int size)
8253a5a1b3Sopenharmony_ci{
8353a5a1b3Sopenharmony_ci    void *ptr;
8453a5a1b3Sopenharmony_ci
8553a5a1b3Sopenharmony_ci    ptr = (void *) (((int)spxGlobalScratchPtr + BLOCK_MASK) & ~BLOCK_MASK);  //Start on 8 boundary
8653a5a1b3Sopenharmony_ci
8753a5a1b3Sopenharmony_ci    spxGlobalScratchPtr = (char *)((int)ptr + size);	// Update pointer to next free location
8853a5a1b3Sopenharmony_ci
8953a5a1b3Sopenharmony_ci    if (spxGlobalScratchPtr > spxGlobalScratchEnd )
9053a5a1b3Sopenharmony_ci    {
9153a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
9253a5a1b3Sopenharmony_ci	    fprintf (stderr, "insufficient space for scratch alloc request %d bytes\n", size);
9353a5a1b3Sopenharmony_ci#endif
9453a5a1b3Sopenharmony_ci       return 0;
9553a5a1b3Sopenharmony_ci    }
9653a5a1b3Sopenharmony_ci
9753a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
9853a5a1b3Sopenharmony_ci    fprintf (stderr, "Scratch Allocated %d chars at %x, %d remaining\n", size, ptr, ((int)spxGlobalScratchEnd - (int)spxGlobalScratchPtr));
9953a5a1b3Sopenharmony_ci#endif
10053a5a1b3Sopenharmony_ci    memset(ptr, 0, size);
10153a5a1b3Sopenharmony_ci    return ptr;
10253a5a1b3Sopenharmony_ci}
10353a5a1b3Sopenharmony_ci
10453a5a1b3Sopenharmony_ci#define OVERRIDE_SPEEX_REALLOC
10553a5a1b3Sopenharmony_cistatic inline void *speex_realloc (void *ptr, int size)
10653a5a1b3Sopenharmony_ci{
10753a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
10853a5a1b3Sopenharmony_ci   speex_warning("realloc attempted, not allowed");
10953a5a1b3Sopenharmony_ci#endif
11053a5a1b3Sopenharmony_ci   return 0;
11153a5a1b3Sopenharmony_ci}
11253a5a1b3Sopenharmony_ci
11353a5a1b3Sopenharmony_ci#define OVERRIDE_SPEEX_FREE
11453a5a1b3Sopenharmony_cistatic inline void speex_free (void *ptr)
11553a5a1b3Sopenharmony_ci{
11653a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
11753a5a1b3Sopenharmony_ci   speex_warning("at speex_free");
11853a5a1b3Sopenharmony_ci#endif
11953a5a1b3Sopenharmony_ci}
12053a5a1b3Sopenharmony_ci#define OVERRIDE_SPEEX_FREE_SCRATCH
12153a5a1b3Sopenharmony_cistatic inline void speex_free_scratch (void *ptr)
12253a5a1b3Sopenharmony_ci{
12353a5a1b3Sopenharmony_ci#ifdef VERBOSE_ALLOC
12453a5a1b3Sopenharmony_ci   speex_warning("at speex_free_scratch");
12553a5a1b3Sopenharmony_ci#endif
12653a5a1b3Sopenharmony_ci}
12753a5a1b3Sopenharmony_ci
12853a5a1b3Sopenharmony_ci#endif    /* !MANUAL_ALLOC */
129