|
libGDF
|
00001 // 00002 // This file is part of libGDF. 00003 // 00004 // libGDF is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation, either version 3 of 00007 // the License, or (at your option) any later version. 00008 // 00009 // libGDF is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with libGDF. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // Copyright 2010 Martin Billinger 00018 00019 #include "GDF/RecordBuffer.h" 00020 #include "GDF/Record.h" 00021 #include "GDF/GDFHeaderAccess.h" 00022 #include "GDF/tools.h" 00023 //#include <iostream> 00024 00025 namespace gdf 00026 { 00027 RecordBuffer::RecordBuffer( const GDFHeaderAccess *gdfh ) : m_gdfh(gdfh) 00028 { 00029 m_pool = NULL; 00030 } 00031 00032 //=================================================================================================== 00033 //=================================================================================================== 00034 00035 RecordBuffer::~RecordBuffer( ) 00036 { 00037 clearBuffers( ); 00038 if( m_pool ) 00039 delete m_pool; 00040 } 00041 00042 //=================================================================================================== 00043 //=================================================================================================== 00044 00045 void RecordBuffer::clearBuffers( ) 00046 { 00047 if( m_pool ) 00048 { 00049 std::list<Record*>::iterator it = m_records.begin( ); 00050 for( ; it != m_records.end(); it++ ) 00051 m_pool->push( *it ); 00052 00053 it = m_records_full.begin( ); 00054 for( ; it != m_records_full.end(); it++ ) 00055 m_pool->push( *it ); 00056 } 00057 00058 m_records.clear( ); 00059 m_records_full.clear( ); 00060 00061 m_num_full = 0; 00062 } 00063 00064 //=================================================================================================== 00065 //=================================================================================================== 00066 00067 void RecordBuffer::reset( ) 00068 { 00069 size_t M = m_gdfh->getMainHeader_readonly( ).get_num_signals( ); 00070 clearBuffers( ); 00071 m_channelhead.resize( M ); 00072 for( size_t i=0; i<M; i++ ) 00073 m_channelhead[i] =m_records.begin( ); 00074 if( m_pool ) 00075 delete m_pool; 00076 m_pool = new PointerPool<Record>( Record(m_gdfh) ); 00077 } 00078 00079 //=================================================================================================== 00080 //=================================================================================================== 00081 00082 void RecordBuffer::handleChannelFull( const size_t channel_idx ) 00083 { 00084 //std::cout << "Channel Full" << std::endl; 00085 Record *r = *m_channelhead[channel_idx]; 00086 m_channelhead[channel_idx]++; 00087 if( r->isFull() ) 00088 handleRecordFull( ); 00089 } 00090 00091 //=================================================================================================== 00092 //=================================================================================================== 00093 00094 void RecordBuffer::handleRecordFull( ) 00095 { 00096 //std::cout << "Record Full" << std::endl; 00097 m_records_full.push_back( m_records.front() ); 00098 m_records.pop_front( ); 00099 m_num_full++; 00100 00101 std::list<RecordFullHandler*>::iterator it = m_recfull_callbacks.begin( ); 00102 for( ; it != m_recfull_callbacks.end(); it++ ) 00103 (*it)->triggerRecordFull( m_records_full.back() ); 00104 } 00105 00106 //=================================================================================================== 00107 //=================================================================================================== 00108 00109 void RecordBuffer::registerRecordFullCallback( RecordFullHandler *h ) 00110 { 00111 m_recfull_callbacks.push_back( h ); 00112 } 00113 00114 //=================================================================================================== 00115 //=================================================================================================== 00116 00117 void RecordBuffer::unregisterRecordFullCallback( RecordFullHandler *h ) 00118 { 00119 m_recfull_callbacks.remove( h ); 00120 } 00121 00122 //=================================================================================================== 00123 //=================================================================================================== 00124 00125 void RecordBuffer::addSamplePhys( const size_t channel_idx, const double value ) 00126 { 00127 Channel *ch = getValidChannel( channel_idx ); 00128 ch->addSamplePhys( value ); 00129 if( ch->getFree( ) == 0 ) 00130 handleChannelFull( channel_idx ); 00131 } 00132 00133 //=================================================================================================== 00134 //=================================================================================================== 00135 00136 void RecordBuffer::blitSamplesPhys( const size_t channel_idx, const double *values, size_t num ) 00137 { 00138 size_t i = 0; 00139 while( i<num ) 00140 { 00141 Channel *ch = getValidChannel( channel_idx ); 00142 size_t n = std::min( num-i, ch->getFree( ) ); 00143 ch->blitSamplesPhys( &values[i], n ); 00144 if( ch->getFree( ) == 0 ) 00145 handleChannelFull( channel_idx ); 00146 i += n; 00147 } 00148 } 00149 00150 //=================================================================================================== 00151 //=================================================================================================== 00152 00153 void RecordBuffer::addRecord( Record *r ) 00154 { 00155 if( getNumPartialRecords( ) > 0 ) 00156 throw exception::invalid_operation( "RecordBuffer::addRecord called, but buffer contains partial records." ); 00157 m_records_full.push_back( r ); 00158 m_num_full++; 00159 00160 std::list<RecordFullHandler*>::iterator it = m_recfull_callbacks.begin( ); 00161 for( ; it != m_recfull_callbacks.end(); it++ ) 00162 (*it)->triggerRecordFull( m_records_full.back() ); 00163 } 00164 00165 //=================================================================================================== 00166 //=================================================================================================== 00167 00168 Record *RecordBuffer::acquireRecord( ) 00169 { 00170 return m_pool->pop( ); 00171 } 00172 00173 //=================================================================================================== 00174 //=================================================================================================== 00175 00176 std::list< Record* >::iterator RecordBuffer::createNewRecord( ) 00177 { 00178 Record *r = m_pool->pop( ); 00179 r->clear( ); 00180 m_records.push_back( r ); 00181 std::list< Record* >::iterator it = m_records.end( ); 00182 it--; 00183 return it; 00184 } 00185 00186 //=================================================================================================== 00187 //=================================================================================================== 00188 00189 Record *RecordBuffer::getFirstFullRecord( ) 00190 { 00191 if( m_num_full > 0 ) 00192 return m_records_full.front( ); 00193 else 00194 return NULL; 00195 } 00196 00197 //=================================================================================================== 00198 //=================================================================================================== 00199 00200 void RecordBuffer::removeFirstFullRecord( ) 00201 { 00202 m_pool->push( m_records_full.front() ); 00203 m_records_full.pop_front( ); 00204 m_num_full--; 00205 } 00206 00207 //=================================================================================================== 00208 //=================================================================================================== 00209 00210 Channel *RecordBuffer::getValidChannel( const size_t channel_idx ) 00211 { 00212 if( channel_idx >= m_channelhead.size( ) ) 00213 throw exception::nonexistent_channel_access( "channel "+boost::lexical_cast<std::string>(channel_idx) +"does not exist" ); 00214 00215 if( m_channelhead[channel_idx] == m_records.end() ) 00216 { 00217 if( m_records.size() > 0 ) 00218 { 00219 if( m_records.back()->getChannel(channel_idx)->getFree( ) == 0 ) 00220 m_channelhead[channel_idx] = createNewRecord( ); 00221 else 00222 throw exception::corrupt_recordbuffer( "DOOM is upon us!" ); 00223 } 00224 else 00225 { 00226 // list was empty: set all channel heads to the new record. 00227 std::list< Record* >::iterator r = createNewRecord( ); 00228 for( size_t i=0; i<m_channelhead.size(); i++ ) 00229 m_channelhead[i] = r; 00230 } 00231 } 00232 00233 return (*m_channelhead[channel_idx])->getChannel( channel_idx ); 00234 } 00235 00236 //=================================================================================================== 00237 //=================================================================================================== 00238 00239 size_t RecordBuffer::getNumFreeAlloc( const size_t channel_idx ) 00240 { 00241 size_t num = 0; 00242 getValidChannel( channel_idx ); 00243 std::list< Record* >::iterator it = m_channelhead[channel_idx]; 00244 while( it != m_records.end() ) 00245 { 00246 num += (*it)->getChannel( channel_idx )->getFree( ); 00247 it ++; 00248 } 00249 return num; 00250 } 00251 00252 //=================================================================================================== 00253 //=================================================================================================== 00254 00255 void RecordBuffer::flood( ) 00256 { 00257 while( getNumPartialRecords( ) > 0 ) 00258 { 00259 m_records.front( )->fill( ); 00260 handleRecordFull( ); 00261 } 00262 00263 for( size_t i=0; i<m_channelhead.size(); i++ ) 00264 m_channelhead[i] =m_records.begin( ); 00265 } 00266 00267 //=================================================================================================== 00268 //=================================================================================================== 00269 00270 }