annotate thread/BlockAllocator.h @ 321:f1e6be2de9a5

A threshold (delta) is added in the peak picking parameters structure (PPickParams). It is used as an offset when computing the smoothed detection function. A constructor for the structure PPickParams is also added to set the parameters to 0 when a structure instance is created. Hence programmes using the peak picking parameter structure and which do not set the delta parameter (e.g. QM Vamp note onset detector) won't be affected by the modifications. Functions modified: - dsp/onsets/PeakPicking.cpp - dsp/onsets/PeakPicking.h - dsp/signalconditioning/DFProcess.cpp - dsp/signalconditioning/DFProcess.h
author mathieub <mathieu.barthet@eecs.qmul.ac.uk>
date Mon, 20 Jun 2011 19:01:48 +0100
parents 4a5aea3dae81
children 701233f8ed41
rev   line source
c@313 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@313 2
c@313 3 /*
c@313 4 QM DSP Library
c@313 5
c@313 6 Centre for Digital Music, Queen Mary, University of London.
c@313 7
c@313 8 This file is derived from the FSB Allocator by Juha Nieminen. The
c@313 9 underlying method is unchanged, but the class has been refactored
c@313 10 to permit multiple separate allocators (e.g. one per thread)
c@313 11 rather than use a single global one (and to fit house style).
c@313 12
c@313 13 Copyright (c) 2008 Juha Nieminen
c@313 14
c@313 15 Permission is hereby granted, free of charge, to any person obtaining a copy
c@313 16 of this software and associated documentation files (the "Software"), to deal
c@313 17 in the Software without restriction, including without limitation the rights
c@313 18 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
c@313 19 copies of the Software, and to permit persons to whom the Software is
c@313 20 furnished to do so, subject to the following conditions:
c@313 21
c@313 22 The above copyright notice and this permission notice shall be included in
c@313 23 all copies or substantial portions of the Software.
c@313 24
c@313 25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
c@313 26 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
c@313 27 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
c@313 28 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
c@313 29 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
c@313 30 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
c@313 31 THE SOFTWARE.
c@313 32 */
c@313 33
c@313 34 #ifndef _BLOCK_ALLOCATOR_H_
c@313 35 #define _BLOCK_ALLOCATOR_H_
c@313 36
c@313 37 #include <cstdlib>
c@313 38
c@313 39 /**
c@313 40 * BlockAllocator is a simple allocator for fixed-size (usually small)
c@313 41 * chunks of memory. The size of an element is specified in the
c@313 42 * BlockAllocator constructor, and the functions allocate() and
c@313 43 * deallocate() are used to obtain and release a single element at a
c@313 44 * time.
c@313 45 *
c@313 46 * BlockAllocator may be an appropriate class to use in situations
c@313 47 * involving a very large number of allocations and deallocations of
c@313 48 * simple, identical objects across multiple threads (a hard situation
c@313 49 * for a generic system malloc implementation to handle well). Retain
c@313 50 * one BlockAllocator per thread (the class itself is not
c@313 51 * thread-safe), and ensure that each thread uses its own allocator
c@313 52 * exclusively.
c@313 53 *
c@313 54 * BlockAllocator is based on Juha Nieminen's more general
c@313 55 * FSBAllocator.
c@313 56 */
c@313 57 class BlockAllocator
c@313 58 {
c@313 59 public:
c@313 60 typedef std::size_t data_t;
c@313 61
c@313 62 BlockAllocator(int elementSize) : m_sz(elementSize) { }
c@313 63
c@313 64 void *
c@313 65 allocate()
c@313 66 {
c@313 67 if (m_freelist.empty()) {
c@313 68 m_freelist.push_back(m_blocks.data.size());
c@313 69 m_blocks.data.push_back(Block(this));
c@313 70 }
c@313 71
c@313 72 const data_t index = m_freelist.back();
c@313 73 Block &block = m_blocks.data[index];
c@313 74 void *retval = block.allocate(index);
c@313 75 if (block.isFull()) m_freelist.pop_back();
c@313 76
c@313 77 return retval;
c@313 78 }
c@313 79
c@313 80 void
c@313 81 deallocate(void *ptr)
c@313 82 {
c@313 83 if (!ptr) return;
c@313 84
c@313 85 data_t *unitPtr = (data_t *)ptr;
c@313 86 const data_t blockIndex = unitPtr[elementSizeInDataUnits()];
c@313 87 Block& block = m_blocks.data[blockIndex];
c@313 88
c@313 89 if (block.isFull()) m_freelist.push_back(blockIndex);
c@313 90 block.deallocate(unitPtr);
c@313 91 }
c@313 92
c@313 93 private:
c@313 94 inline data_t elementsPerBlock() const {
c@313 95 return 512;
c@313 96 }
c@313 97 inline data_t dataSize() const {
c@313 98 return sizeof(data_t);
c@313 99 }
c@313 100 inline data_t elementSizeInDataUnits() const {
c@313 101 return (m_sz + (dataSize() - 1)) / dataSize();
c@313 102 }
c@313 103 inline data_t unitSizeInDataUnits() const {
c@313 104 return elementSizeInDataUnits() + 1;
c@313 105 }
c@313 106 inline data_t blockSizeInDataUnits() const {
c@313 107 return elementsPerBlock() * unitSizeInDataUnits();
c@313 108 }
c@313 109
c@313 110 class Block
c@313 111 {
c@313 112 public:
c@313 113 Block(BlockAllocator *a) :
c@313 114 m_a(a),
c@313 115 m_block(0),
c@313 116 m_firstFreeUnit(data_t(-1)),
c@313 117 m_allocated(0),
c@313 118 m_end(0)
c@313 119 {}
c@313 120
c@313 121 ~Block() {
c@313 122 delete[] m_block;
c@313 123 }
c@313 124
c@313 125 bool isFull() const {
c@313 126 return m_allocated == m_a->elementsPerBlock();
c@313 127 }
c@313 128
c@313 129 void clear() {
c@313 130 delete[] m_block;
c@313 131 m_block = 0;
c@313 132 m_firstFreeUnit = data_t(-1);
c@313 133 }
c@313 134
c@313 135 void *allocate(data_t index) {
c@313 136
c@313 137 if (m_firstFreeUnit == data_t(-1)) {
c@313 138
c@313 139 if (!m_block) {
c@313 140 m_block = new data_t[m_a->blockSizeInDataUnits()];
c@313 141 m_end = 0;
c@313 142 }
c@313 143
c@313 144 data_t *retval = m_block + m_end;
c@313 145 m_end += m_a->unitSizeInDataUnits();
c@313 146 retval[m_a->elementSizeInDataUnits()] = index;
c@313 147 ++m_allocated;
c@313 148 return retval;
c@313 149
c@313 150 } else {
c@313 151
c@313 152 data_t *retval = m_block + m_firstFreeUnit;
c@313 153 m_firstFreeUnit = *retval;
c@313 154 ++m_allocated;
c@313 155 return retval;
c@313 156 }
c@313 157 }
c@313 158
c@313 159 void deallocate(data_t *ptr) {
c@313 160
c@313 161 *ptr = m_firstFreeUnit;
c@313 162 m_firstFreeUnit = ptr - m_block;
c@313 163
c@313 164 if (--m_allocated == 0) clear();
c@313 165 }
c@313 166
c@313 167 private:
c@313 168 const BlockAllocator *m_a;
c@313 169 data_t *m_block;
c@313 170 data_t m_firstFreeUnit;
c@313 171 data_t m_allocated;
c@313 172 data_t m_end;
c@313 173 };
c@313 174
c@313 175 struct Blocks
c@313 176 {
c@313 177 std::vector<Block> data;
c@313 178
c@313 179 Blocks() {
c@313 180 data.reserve(1024);
c@313 181 }
c@313 182 };
c@313 183
c@313 184 const int m_sz;
c@313 185 Blocks m_blocks;
c@313 186 std::vector<data_t> m_freelist;
c@313 187 };
c@313 188
c@313 189 #endif