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