comparison layer/SpectrogramLayer.cpp @ 1059:e1c2dcc7790e spectrogram-minor-refactor

A couple more helper functions
author Chris Cannam
date Wed, 15 Jun 2016 08:52:07 +0100
parents 9a13bc339fa9
children 5eb4d79334b9
comparison
equal deleted inserted replaced
1058:9a13bc339fa9 1059:e1c2dcc7790e
2408 return move(vector<float>(col.data() + minbin, 2408 return move(vector<float>(col.data() + minbin,
2409 col.data() + minbin + bincount)); 2409 col.data() + minbin + bincount));
2410 } 2410 }
2411 2411
2412 void 2412 void
2413 SpectrogramLayer::scaleColumn(vector<float> &col) 2413 SpectrogramLayer::scaleColumn(vector<float> &col) const
2414 { 2414 {
2415 if (m_normalization != NormalizeColumns && 2415 if (m_normalization != NormalizeColumns &&
2416 m_normalization != NormalizeHybrid) { 2416 m_normalization != NormalizeHybrid) {
2417 float scale = 2.f / float(m_fftSize); 2417 float scale = 2.f / float(m_fftSize);
2418 int n = int(col.size()); 2418 int n = int(col.size());
2435 vector<float> 2435 vector<float>
2436 SpectrogramLayer::distributeColumn(const vector<float> &in, 2436 SpectrogramLayer::distributeColumn(const vector<float> &in,
2437 int h, 2437 int h,
2438 const vector<double> &binfory, 2438 const vector<double> &binfory,
2439 int minbin, 2439 int minbin,
2440 bool interpolate) 2440 bool interpolate) const
2441 { 2441 {
2442 vector<float> out(h, 0.f); 2442 vector<float> out(h, 0.f);
2443 int bins = int(in.size()); 2443 int bins = int(in.size());
2444 2444
2445 for (int y = 0; y < h; ++y) { 2445 for (int y = 0; y < h; ++y) {
2463 2463
2464 if (other < 0 || other >= bins) { 2464 if (other < 0 || other >= bins) {
2465 other = bin; 2465 other = bin;
2466 } 2466 }
2467 2467
2468 if (m_binDisplay == PeakBins) { 2468 double prop = 1.0 - fabs(dist);
2469 2469
2470 if (is_peak(in, bin)) { 2470 double v0 = in[bin];
2471 out[y] = in[bin]; 2471 double v1 = in[other];
2472 } else if (other != bin && is_peak(in, other)) {
2473 out[y] = in[other];
2474 }
2475 2472
2476 } else { 2473 out[y] = float(prop * v0 + (1.0 - prop) * v1);
2477
2478 double prop = 1.0 - fabs(dist);
2479
2480 double v0 = in[bin];
2481 double v1 = in[other];
2482
2483 out[y] = float(prop * v0 + (1.0 - prop) * v1);
2484 }
2485 2474
2486 } else { // not interpolating this one 2475 } else { // not interpolating this one
2487 2476
2488 int by0 = int(sy0 + 0.0001); 2477 int by0 = int(sy0 + 0.0001);
2489 int by1 = int(sy1 + 0.0001); 2478 int by1 = int(sy1 + 0.0001);
2490 if (by1 < by0 + 1) by1 = by0 + 1; 2479 if (by1 < by0 + 1) by1 = by0 + 1;
2491 2480
2492 for (int bin = by0; bin < by1; ++bin) { 2481 for (int bin = by0; bin < by1; ++bin) {
2493 2482
2494 if (m_binDisplay == PeakBins && !is_peak(in, bin)) {
2495 continue;
2496 }
2497
2498 float value = in[bin]; 2483 float value = in[bin];
2499 2484
2500 if (value > out[y] || m_colourScale == PhaseColourScale) { 2485 if (value > out[y] || m_colourScale == PhaseColourScale) {
2501 out[y] = value; 2486 out[y] = value;
2502 } 2487 }
2509 2494
2510 void 2495 void
2511 SpectrogramLayer::recordColumnExtents(const vector<float> &col, 2496 SpectrogramLayer::recordColumnExtents(const vector<float> &col,
2512 int sx, // column index, for m_columnMags 2497 int sx, // column index, for m_columnMags
2513 MagnitudeRange &overallMag, 2498 MagnitudeRange &overallMag,
2514 bool &overallMagChanged) 2499 bool &overallMagChanged) const
2515 { 2500 {
2516 //!!! this differs from previous logic when in peak mode - as the
2517 //!!! zeros between peaks are now sampled, where they were not
2518 //!!! before
2519
2520 if (!in_range_for(sx, m_columnMags)) { 2501 if (!in_range_for(sx, m_columnMags)) {
2521 throw logic_error("sx out of range for m_columnMags"); 2502 throw logic_error("sx out of range for m_columnMags");
2522 } 2503 }
2523 MagnitudeRange mr; 2504 MagnitudeRange mr;
2524 for (auto v: col) { 2505 for (auto v: col) {
2528 if (overallMag.sample(mr)) { 2509 if (overallMag.sample(mr)) {
2529 overallMagChanged = true; 2510 overallMagChanged = true;
2530 } 2511 }
2531 } 2512 }
2532 2513
2514 vector<float>
2515 SpectrogramLayer::peakPickColumn(const vector<float> &in) const
2516 {
2517 if (m_binDisplay != PeakBins) return in;
2518
2519 vector<float> out(in.size(), 0.f);
2520
2521 for (int i = 0; in_range_for(i, in); ++i) {
2522 if (is_peak(in, i)) {
2523 out[i] = in[i];
2524 }
2525 }
2526
2527 return move(out);
2528 }
2529
2530 vector<float>
2531 SpectrogramLayer::applyDisplayGain(const vector<float> &in) const
2532 {
2533 if (m_gain == 1.0) return in;
2534
2535 vector<float> out;
2536 out.reserve(in.size());
2537 for (auto v: in) {
2538 out.push_back(v * m_gain);
2539 }
2540 return move(out);
2541 }
2542
2533 // order: 2543 // order:
2534 // get column -> scale -> distribute/interpolate -> record extents -> normalise -> apply display gain 2544 // get column -> scale -> distribute/interpolate -> record extents -> normalise -> peak pick -> apply display gain
2535 2545
2536 int 2546 int
2537 SpectrogramLayer::paintDrawBuffer(LayerGeometryProvider *v, 2547 SpectrogramLayer::paintDrawBuffer(LayerGeometryProvider *v,
2538 int w, 2548 int w,
2539 int h, 2549 int h,