void IFFT::transform (Matrix< std::complex<ssi_real_t> > *src, Matrix<ssi_real_t> *dst) { // SSI_ASSERT that: // - src has 1 row and dim * rfft columns // - dst has nfft rows and dim colums if (!(src->rows == 1 && src->cols == dim * rfft)) { ssi_err ("input matrix is %ux%u, but should be %ux%u", src->rows, src->cols, 1, dim * rfft); } if (!(dst->rows == nfft && dst->cols >= dim)) { ssi_err ("input matrix is %ux%u, but should be %ux%u", dst->rows, dst->cols, nfft, dim); } transform (src->data, dst->data); }
void Statistics::transform_enter(ssi_stream_t &stream_in, ssi_stream_t &stream_out, ssi_size_t xtra_stream_in_num /*= 0*/, ssi_stream_t xtra_stream_in[] /*= 0*/) { if (xtra_stream_in_num > 0){ ssi_err("x-tra streams not supported."); } if (_options.getSelection().empty()){ ssi_err("no statistical function enabled."); } _dim = stream_in.dim; _res = new ssi_real_t[_dim * _options.getSelection().size()]; _running_stats = new running_stat_t[_dim]; provide_temp_array(stream_in.num_real); }
double OSMelspec::specScaleTransfInv(double x, OSMelspec::SPECTSCALE scale, double param) { // following code taken from openSMILE 1.0.1, melspec.cpp // http://opensmile.sourceforge.net/ switch(scale) { case LOG: return exp(x * log(param)); // param = logScaleBase case SEMITONE: return param * pow(2.0, x/12.0); // param = firstNote case BARK: { // Bark scale according to : H. Traunmüller (1990) "Analytical expressions for the tonotopic sensory scale" J. Acoust. Soc. Am. 88: 97-100. double z0 = (x+0.53)/26.81; if (z0 != 1.0) return (1960.0 * z0)/(1.0-z0); else return 0.0; } case BARK_SCHROED: return 600.0 * sinh(x/6.0); //return 0.0; case BARK_SPEEX: ssi_err ("SPECTSCALE_BARK_SPEEX: inversion not yet implemented"); case MEL : // Mel scale according to: L.L. Beranek (1949) Acoustic Measurements, New York: Wiley. return 700.0*(exp(x/1127.0)-1.0); case LINEAR: default: return x; } return x; }
void Window::RegisterWindowClass() { _hParent = GetConsoleWindow(); _hInstance = ::GetModuleHandle(NULL); WNDCLASS wndcls; BOOL result = ::GetClassInfo((HINSTANCE) _hInstance, _wClassName, &wndcls); if (result == 0) { WNDCLASSEX wClass; wClass.cbSize = sizeof(WNDCLASSEX); wClass.style = 0; wClass.lpfnWndProc = WindowProc; wClass.cbClsExtra = 0; wClass.cbWndExtra = 0; wClass.hInstance = (HINSTANCE) _hInstance; wClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wClass.hCursor = LoadCursor(NULL, IDC_ARROW); wClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wClass.lpszMenuName = NULL; wClass.lpszClassName = _wClassName; wClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&wClass)) { PrintLastError(); ssi_err("window registration failed"); } } }
void VideoPainter::consume_enter (ssi_size_t stream_in_num, ssi_stream_t stream_in[]) { if (_video_format.framesPerSecond != stream_in[0].sr) { _video_format.framesPerSecond = stream_in[0].sr; ssi_wrn ("sample rate has been adjusted"); } if (ssi_video_size (_video_format) != stream_in[0].byte) { ssi_err ("input stream doesn't match video format"); } if (stream_in[0].dim != 1) { ssi_wrn ("supports only one dimension"); } _plot = new PaintVideo (_video_format, _options.flip, _options.scale, _options.mirror, _options.maxValue); _plot_id = _painter->AddCanvas (_options.name); _painter->AddObject (_plot_id, _plot); if (_options.move[0] != 0) { if (_options.move[1] != 0) { _painter->Move (_plot_id, _options.move[2], _options.move[3], _options.move[4] < 0 ? _video_format.widthInPixels : _options.move[4], _options.move[5] < 0 ? _video_format.heightInPixels : _options.move[5], true); } else { _painter->Move (_plot_id, _options.move[2], _options.move[3], _options.move[4] < 0 ? _video_format.widthInPixels : _options.move[4], _options.move[5] < 0 ? _video_format.heightInPixels : _options.move[5]); } } if (_options.arrange[0] != 0) { _painter->Arrange (_options.arrange[1], _options.arrange[2], _options.arrange[3], _options.arrange[4], _options.arrange[5], _options.arrange[6]); } }
bool MyFusion::train (ssi_size_t n_models, IModel **models, ISamples &samples) { if (samples.getSize () == 0) { ssi_wrn ("empty sample list"); return false; } if (isTrained ()) { ssi_wrn ("already trained"); return false; } ssi_size_t n_streams = samples.getStreamSize (); if (n_streams != n_models) { ssi_err ("#models (%u) differs from #streams (%u)", n_models, n_streams); } for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { if (!models[n_model]->isTrained ()) { models[n_model]->train (samples, n_model); } } _is_trained = true; return true; }
bool FileReader::connect () { if (!_provider) { ssi_wrn ("provider not set"); return false; } if (!prepare_file ()) { ssi_err ("an error occured while reading file (%s)", _file_stream_in.getDataFile ()->getPath ()); } _stopped = false; // set providing=true to read first chunk _is_providing = true; ssi_msg (SSI_LOG_LEVEL_BASIC, "start 'path=%s'", _options.path); if (ssi_log_level >= SSI_LOG_LEVEL_BASIC) { ssi_print (" sample rate\t= %.2lf Hz\n\ sample dim\t\t= %u\n\ sample bytes\t= %u\n\ sample number\t= %u\n\ stream length\t= %.2fs\n", _stream.sr, _stream.dim, _stream.byte, _sample_number_total, _sample_number_total/_stream.sr); }
ISMergeDim::ISMergeDim (ISamples *samples) : _samples (*samples), _dim (0), _n_streams (samples->getStreamSize ()) { for(ssi_size_t nstrms = 0; nstrms < _n_streams; nstrms++){ _dim += _samples.get(0)->streams[nstrms]->dim; } ssi_sample_create (_sample_out, 1, 0, 0, 0, 0); _sample_out.streams[0] = &_stream; // determine aligned bytes ssi_size_t byte = _samples.get(0)->streams[0]->byte; for (ssi_size_t i = 1; i < _n_streams; i++) { if (byte != _samples.get(0)->streams[i]->byte) { ssi_err ("number of bytes must be equal in all streams"); } } //create aligned streams ssi_stream_init (_stream, 0, _dim, byte, _samples.getStream (0).type, _samples.getStream (0).sr); ssi_stream_init (_stream_ref, 0, _dim, byte, _samples.getStream (0).type, _samples.getStream (0).sr); }
ssi_sample_t &SampleList::operator[] (ssi_size_t index) { if (index >= getSize ()) { ssi_err ("index out of range"); } return *_samples[index]; }
const ssi_char_t *StringList::get (ssi_size_t index) const { if (index >= size ()) { ssi_err ("index (%u) out of boundary (%u)", index, size ()); } return _strings[index]; }
void FileReader::run () { if (_stopped) { ::Sleep (100); return; } if (_is_providing) { if (_file_stream_in.read (_stream) == FileStreamIn::READ_ERROR) { ssi_err ("an error occured while reading file (%s)", _file_stream_in.getDataFile ()->getPath ()); } } _is_providing = _provider->provide (_stream.ptr, _stream.num); if (!_is_providing) { ::Sleep (100); return; } SSI_DBG (SSI_LOG_LEVEL_DEBUG, "read %u samples", _stream.num); if (!_timer) { _timer = new Timer (_options.block); } if (++_step_counter >= _max_steps) { if (_options.loop) { if (!prepare_file ()) { ssi_err ("an error occured while reading file (%s)", _file_stream_in.getDataFile ()->getPath ()); } ssi_msg (SSI_LOG_LEVEL_DETAIL, "loop 'path=%s'", _options.path); } else { ssi_msg (SSI_LOG_LEVEL_DETAIL, "release 'path=%s'", _options.path); _stopped = true; _interrupted = false; _event.release (); } } _timer->wait (); }
void Evaluation::evalSplit (Trainer *trainer, ISamples &samples, ssi_real_t split) { if (split <= 0 || split >= 1) { ssi_err ("split must be a value between 0 and 1"); } _trainer = trainer; destroy_conf_mat (); init_conf_mat (samples); ssi_size_t *indices = new ssi_size_t[samples.getSize ()]; ssi_size_t *indices_count_lab = new ssi_size_t[samples.getClassSize ()]; ssi_size_t indices_count_all; indices_count_all = 0; for (ssi_size_t j = 0; j < samples.getClassSize (); j++) { indices_count_lab[j] = 0; } ssi_size_t label; ssi_size_t label_size; for (ssi_size_t j = 0; j < samples.getSize (); j++) { label = samples.get (j)->class_id; label_size = samples.getSize (label); if (++indices_count_lab[label] <= ssi_cast (ssi_size_t, label_size * split + 0.5f)) { indices[indices_count_all++] = j; } } SampleList strain; SampleList stest; // split off samples ModelTools::SelectSampleList (samples, strain, stest, indices_count_all, indices); _n_total = stest.getSize (); _result_vec = new ssi_size_t[2*_n_total]; _result_vec_ptr = _result_vec; // train with remaining samples _trainer->release (); if (_preproc_mode) { _trainer->setPreprocMode (_preproc_mode, _n_streams_refs, _stream_refs); } else if (_fselmethod) { _trainer->setSelection (strain, _fselmethod, _pre_fselmethod, _n_pre_feature); } _trainer->train (strain); // test with remaining samples eval_h (stest); delete[] indices; delete[] indices_count_lab; }
bool FileReader::disconnect () { ssi_msg(SSI_LOG_LEVEL_BASIC, "stop reading from '%s'", _options.path); delete _timer; _timer = 0; ssi_stream_destroy(_stream); if (!_file_stream_in.close()) { ssi_err("could not close stream '%s'", _options.path); } return true; }
void MatrixOps<T>::Print (File *file, const Matrix<T> *const matrix) { bool status; if (file->getMode () == File::ASCII) { file->setType (ssi_gettype<T> (matrix->data[0])); status = file->write (matrix->data, matrix->cols, matrix->cols * matrix->rows); } else { status = file->write (matrix->data, sizeof (T), matrix->cols * matrix->rows); } if (!status) { ssi_err ("Print failed ()"); } }
MvgMedianHelper::MvgMedianHelper (ssi_size_t nwin) : _mpos (0), _nwin (nwin), _ndim (0), _vals (0), _order (0), _pointer (0) { if (nwin < 3) { ssi_err ("window size is too small, '%u' < '3'", nwin); } _mpos = _nwin / 2; _pointer = _nwin-1; _vals = new ssi_real_t[_nwin]; _order = new ssi_size_t[_nwin]; }
void Statistics::calculate(ssi_stream_t &stream_in) { ssi_real_t * in_ptr = ssi_pcast(ssi_real_t, stream_in.ptr); for (ssi_size_t d_i = 0; d_i < _dim; d_i++) { for (ssi_size_t num_i = 0; num_i < stream_in.num; num_i++){ _tmp_arr[d_i][num_i] = in_ptr[d_i*stream_in.num + num_i]; } } calculate_running_stats(stream_in.num); std::vector<stat_fn> stat_fns = _options.getSelection(); for (ssi_size_t d_i = 0; d_i < _dim; d_i++) { for (ssi_size_t f_i = 0; f_i < stat_fns.size(); f_i++){ ssi_size_t r_idx = d_i * ssi_size_t (stat_fns.size()) + f_i; switch (stat_fns[f_i]) { case STAT_KURTOSIS: _res[r_idx] = calculateKurtosis(d_i); break; case STAT_SKEWNESS: _res[r_idx] = calculateSkewness(d_i); break; case STAT_MEAN: _res[r_idx] = calculateMean(d_i); break; case STAT_STDDEV: _res[r_idx] = calculateStandardDeviation(d_i); break; case STAT_VARIANCE: _res[r_idx] = calculateVariance(d_i); break; case STAT_NUMBER_VALS: _res[r_idx] = calulateNumberVals(d_i); break; default: ssi_err("stat_fn not implemented"); } } } }
void PythonImageConsumer::setMetaData(ssi_size_t size, const void *meta) { if (sizeof(_format_in) != size) { ssi_err("meta data does not describe image format"); } if (!_helper) { initHelper(); } memcpy(&_format_in, meta, size); _has_meta_data = true; ssi_msg(SSI_LOG_LEVEL_BASIC, "format of input image '%dx%dx%dx%d'", _format_in.widthInPixels, _format_in.heightInPixels, _format_in.numOfChannels, _format_in.depthInBitsPerChannel / 8) _helper->setImageFormatIn(_format_in); };
void TupleEventSender::consume_enter (ssi_size_t stream_in_num, ssi_stream_t stream_in[]) { if (stream_in[0].type != SSI_REAL) { ssi_err ("type '%s' not supported", SSI_TYPE_NAMES[stream_in[0].type]); } ssi_size_t dim = stream_in[0].dim; _n_tuple = 0; if (_options.mean) _n_tuple++; if (_options.var) _n_tuple++; if (_options.minval) _n_tuple++; if (_options.maxval) _n_tuple++; ssi_event_adjust(_event, _n_tuple * sizeof(ssi_event_tuple_t) * dim); ssi_event_tuple_t *dst = ssi_pcast(ssi_event_tuple_t, _event.ptr); if (_options.mean) { ssi_size_t id = Factory::AddString("mean"); for (ssi_size_t i = 0; i < dim; i++) { dst++->id = id; } } if (_options.var) { ssi_size_t id = Factory::AddString("var"); for (ssi_size_t i = 0; i < dim; i++) { dst++->id = id; } } if (_options.minval) { ssi_size_t id = Factory::AddString("min"); for (ssi_size_t i = 0; i < dim; i++) { dst++->id = id; } } if (_options.maxval) { ssi_size_t id = Factory::AddString("max"); for (ssi_size_t i = 0; i < dim; i++) { dst++->id = id; } } }
Chain::Chain (const ssi_char_t *file) : _n_filters (0), _filters (0), _n_features (0), _features (0), _feature_dim_out (0), _stream_tmp (0), //_file (0), _parsed (false), _meta_size (0), _meta_data (0) { _xmlpipe = ssi_create (XMLPipeline, 0, false); if (file && file[0] != '\0') { if (!parse (file)) { ssi_err ("could not parse chain '%s'", file); } } }
void SampleList::setFeatureNames (unsigned int number, char **names) { if (_samples.empty () || number == getFeatureSize ()) { ssi_err ("number of features (%d) not compatible to sample list (%d)", number, getFeatureSize ()); } if (_feature_names) { for (unsigned int i = 0; i < _n_features; i++) { delete[] _feature_names[i]; } delete[] _feature_names; } _n_features = number; _feature_names = new char *[_n_features]; for (unsigned int i = 0; i < _n_features; i++) { _feature_names[i] = new char[strlen (names[i]) + 1]; ssi_strcpy (_feature_names[i], names[i]); } }
void MapEventSender::consume_enter (ssi_size_t stream_in_num, ssi_stream_t stream_in[]) { if (stream_in[0].type != SSI_REAL) { ssi_err ("type '%s' not supported", SSI_TYPE_NAMES[stream_in[0].type]); } ssi_size_t dim = stream_in[0].dim; ssi_event_adjust(_event, sizeof(ssi_event_map_t) * dim); ssi_event_map_t *dst = ssi_pcast(ssi_event_map_t, _event.ptr); ssi_char_t **keys = 0; if (_options.keys[0] != '\0') { ssi_size_t n = ssi_split_string_count(_options.keys, ','); keys = new ssi_char_t *[dim]; ssi_split_string(n, keys, _options.keys, ','); for (ssi_size_t i = n; i < dim; i++) { keys[i] = ssi_strcpy(keys[i%n]); } } ssi_char_t str[512]; if (keys) { for (ssi_size_t i = 0; i < dim; i++) { dst++->id = Factory::AddString(keys[i]); } } else { for (ssi_size_t i = 0; i < dim; i++) { ssi_sprint(str, "dim#%u", i); dst++->id = Factory::AddString(str); } } if (keys) { for (ssi_size_t i = 0; i < dim; i++) { delete[] keys[i]; } delete[] keys; keys = 0; } }
ssi_size_t Chain::calc_sample_bytes_out (ssi_size_t sample_bytes_in) { ssi_size_t result = sample_bytes_in; if (_n_filters > 0) { for (ssi_size_t i = 0; i < _n_filters; i++) { result = _filters[i]->getSampleBytesOut (result); } } if (_n_features > 0) { ssi_size_t tmp = result; result = _features[0]->getSampleBytesOut (result); for (ssi_size_t i = 1; i < _n_features; i++) { if (result != _features[i]->getSampleBytesOut (tmp)) { ssi_err ("inconsistent chain: number of bytes do not agree"); } } } return result; }
void EmoVoiceVAD::transform (ITransformer::info info, ssi_stream_t &stream_in, ssi_stream_t &stream_out, ssi_size_t xtra_stream_in_num, ssi_stream_t xtra_stream_in[]) { ssi_size_t sample_number = stream_in.num; int16_t *inblock = ssi_pcast (int16_t, stream_in.ptr); int *outblock = ssi_pcast (int, stream_out.ptr); ssi_size_t steps = (sample_number - (EMOVOICEVAD_FRAME_SIZE - EMOVOICEVAD_FRAME_STEP)) / EMOVOICEVAD_FRAME_STEP; if (steps <= 0) { ssi_err ("Input vector too short (%d)", EMOVOICEVAD_FRAME_SIZE); } for (ssi_size_t i = 0; i < steps; i++) { *outblock++ = dsp_vad_calc((dsp_sample_t *)voice, (dsp_vad_t *)vad, (dsp_sample_t *)(inblock + i*EMOVOICEVAD_FRAME_STEP)); } }
bool SimpleFusion::train (ssi_size_t n_models, IModel **models, ISamples &samples) { if (samples.getSize () == 0) { ssi_wrn ("empty sample list"); return false; } if (isTrained ()) { ssi_wrn ("already trained"); return false; } ssi_size_t n_streams = samples.getStreamSize (); if (n_streams != 1 && n_streams != n_models) { ssi_err ("#models (%u) differs from #streams (%u)", n_models, n_streams); } if (samples.hasMissingData ()) { ISMissingData samples_h (&samples); for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { if (!models[n_model]->isTrained ()) { samples_h.setStream(n_streams == 1 ? 0 : n_model); models[n_model]->train (samples_h, n_model); } } } else { for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { if (!models[n_model]->isTrained ()) { models[n_model]->train(samples, n_streams == 1 ? 0 : n_model); } } } _is_trained = true; return true; }
bool FFMPEGReader::connect () { if (!isStream(_options.url) && !ssi_exists(_options.url)) { ssi_err("file not found '%s'", _options.url); return false; } if (!_client) { _client = new FFMPEGReaderClient(this); } if (!(_video_provider||_audio_provider)) { ssi_wrn ("provider not set"); return false; }; FFMPEGReaderClient::SetLogLevel (ssi_log_level); if (_mode != MODE::AUDIO) { _video_buffer = new FFMPEGVideoBuffer (_options.buffer, _video_format.framesPerSecond, ssi_video_size (_video_format)); _video_buffer->reset (); } if (_mode != MODE::VIDEO) { if (_mode == MODE::AUDIOVIDEO) { _audio_buffer = new FFMPEGAudioBuffer (_options.buffer, _audio_channel.stream.sr, 1.0/_video_format.framesPerSecond); } else { _audio_buffer = new FFMPEGAudioBuffer (_options.buffer, _audio_channel.stream.sr, _options.ablock); } _audio_buffer->reset (); } _client->start(); _wait_event.block(); return true; };
ssi_sample_t *ISFlatSample::next() { ssi_sample_t *tmp = _samples->next(); if (!tmp) { return 0; } for (ssi_size_t i = 0; i < _n_streams; i++) { _streams[i].ptr = tmp->streams[i]->ptr; if (_streams[i].dim > tmp->streams[i]->dim * tmp->streams[i]->num) { ssi_err("dimension mismatch '%u > %u'", _streams[i].dim, tmp->streams[i]->dim * tmp->streams[i]->num); } } _sample_out.user_id = tmp->user_id; _sample_out.class_id = tmp->class_id; _sample_out.score = tmp->score; _sample_out.time = tmp->time; return &_sample_out; }
FileAnnotationWriter::FileAnnotationWriter(const ssi_char_t *filename, const ssi_char_t *label, const ssi_char_t *tier) : _file(0), _label(0), _tier(0), _meta(0), _time(0), _duration(0), _filename(0) { if (filename) { FilePath fp(filename); if (ssi_strcmp(fp.getExtension(), ".csv")) { _filename = ssi_strcpy(filename); } else { _filename = ssi_strcat(filename, ".csv"); } _file = fopen(_filename, "w"); if (_file == 0) { ssi_err("could not open file %s", _filename); return; } } else { _file = stdout; } if (label) { _label = ssi_strcpy(label); } if (tier) { _tier = ssi_strcpy(tier); } _meta = new ssi_char_t[2056]; }
SSI_INLINE void ISMergeDim::align () { static ssi_size_t count = 0; _sample_out.class_id = _sample_in.class_id; _sample_out.user_id = _sample_in.user_id; _sample_out.score = _sample_in.score; _sample_out.time = _sample_in.time; if (_samples.hasMissingData ()) { for(ssi_size_t i = 0; i < _n_streams; i++) { if (_sample_in.streams[i]->num == 0) { _stream.num = 0; return; } } } ssi_size_t num = _sample_in.streams[0]->num; for(ssi_size_t i = 1; i < _n_streams; i++) { if (_sample_in.streams[i]->num != num) { ssi_err ("streams differ in #frames differ (%u != %u)", num, _sample_in.streams[i]->num); } } ssi_stream_adjust (_stream, num); ssi_byte_t *ptr = _stream.ptr; for (ssi_size_t j = 0; j < num; j++) { for(ssi_size_t i = 0; i < _n_streams; i++){ ssi_size_t tot = _sample_in.streams[i]->byte * _sample_in.streams[i]->dim; memcpy(ptr, _sample_in.streams[i]->ptr + j*tot, tot); ptr += tot; } } }
bool SimpleFusion::forward (ssi_size_t n_models, IModel **models, ssi_size_t n_streams, ssi_stream_t **streams, ssi_size_t n_probs, ssi_real_t *probs, ssi_real_t &confidence) { bool found_data = false; ssi_real_t **tmp_probs = new ssi_real_t *[n_models]; ssi_real_t tmp_confidence = 0.0f; ssi_stream_t *stream = 0; for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { stream = streams[n_streams == 1 ? 0 : n_model]; if (stream->num > 0) { tmp_probs[n_model] = new ssi_real_t[n_probs]; models[n_model]->forward (*stream, n_probs, tmp_probs[n_model], tmp_confidence); confidence += tmp_confidence; found_data = true; } else { tmp_probs[n_model] = 0; } } confidence /= n_models; if (found_data) { switch (_options.method) { case SimpleFusion::MAXIMUM: { for (ssi_size_t n_class = 0; n_class < n_probs; n_class++) { probs[n_class] = FLT_MIN; for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { if (tmp_probs[n_model] && probs[n_class] < tmp_probs[n_model][n_class]) { probs[n_class] = tmp_probs[n_model][n_class]; } } } break; } case SimpleFusion::SUM: { for (ssi_size_t n_class = 0; n_class < n_probs; n_class++) { probs[n_class] = 0; for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { if (tmp_probs[n_model]) { probs[n_class] += tmp_probs[n_model][n_class]; } } } break; } case SimpleFusion::PRODUCT: { for (ssi_size_t n_class = 0; n_class < n_probs; n_class++) { probs[n_class] = 1.0f; for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { if (tmp_probs[n_model]) { probs[n_class] *= tmp_probs[n_model][n_class]; } } } break; } default: ssi_err ("invalid fusion method '%u'", _options.method); } } for (ssi_size_t n_model = 0; n_model < n_models; n_model++) { delete[] tmp_probs[n_model]; } delete[] tmp_probs; return found_data; }
ssi_stream_t SampleList::getStream (ssi_size_t index) { if (index >= _n_streams) { ssi_err ("index '%u' exceeds #streams '%u'", index, _n_streams); } return _streams[index]; }