Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1:ab83c415a6cd
* Backed out partially complete changes to make the spectrogram only
store results up to the requested max frequency. The speed improvement
was minimal at the expense of annoyance when changing frequency limit,
and although it did save memory, it wasn't yet reliable and fixing it
is not a high enough priority.
author | Chris Cannam |
---|---|
date | Tue, 10 Jan 2006 17:04:02 +0000 |
parents | 2a4f26e85b4c |
children | 37b110168acf |
comparison
equal
deleted
inserted
replaced
0:2a4f26e85b4c | 1:ab83c415a6cd |
---|---|
40 m_colourScale(dBColourScale), | 40 m_colourScale(dBColourScale), |
41 m_colourScheme(DefaultColours), | 41 m_colourScheme(DefaultColours), |
42 m_frequencyScale(LinearFrequencyScale), | 42 m_frequencyScale(LinearFrequencyScale), |
43 m_cache(0), | 43 m_cache(0), |
44 m_cacheInvalid(true), | 44 m_cacheInvalid(true), |
45 m_maxCachedFrequency(0), | |
46 m_pixmapCache(0), | 45 m_pixmapCache(0), |
47 m_pixmapCacheInvalid(true), | 46 m_pixmapCacheInvalid(true), |
48 m_fillThread(0), | 47 m_fillThread(0), |
49 m_updateTimer(0), | 48 m_updateTimer(0), |
50 m_lastFillExtent(0), | 49 m_lastFillExtent(0), |
461 SpectrogramLayer::setMaxFrequency(size_t mf) | 460 SpectrogramLayer::setMaxFrequency(size_t mf) |
462 { | 461 { |
463 if (m_maxFrequency == mf) return; | 462 if (m_maxFrequency == mf) return; |
464 | 463 |
465 m_mutex.lock(); | 464 m_mutex.lock(); |
466 | 465 // don't need to invalidate main cache here |
467 // don't need to invalidate main cache here... | |
468 | |
469 m_pixmapCacheInvalid = true; | 466 m_pixmapCacheInvalid = true; |
470 | 467 |
471 m_maxFrequency = mf; | 468 m_maxFrequency = mf; |
472 emit layerParametersChanged(); | 469 emit layerParametersChanged(); |
473 | 470 |
474 m_mutex.unlock(); | 471 m_mutex.unlock(); |
475 | |
476 // ... but we do still need to do this, in case m_maxFrequency | |
477 // now > m_maxCachedFrequency | |
478 fillCache(); | |
479 } | 472 } |
480 | 473 |
481 size_t | 474 size_t |
482 SpectrogramLayer::getMaxFrequency() const | 475 SpectrogramLayer::getMaxFrequency() const |
483 { | 476 { |
729 if (lock) m_mutex.lock(); | 722 if (lock) m_mutex.lock(); |
730 bool interrupted = false; | 723 bool interrupted = false; |
731 | 724 |
732 for (size_t i = 0; i < m_windowSize / 2; ++i) { | 725 for (size_t i = 0; i < m_windowSize / 2; ++i) { |
733 | 726 |
734 if (int(i) >= m_cache->height()) break; | |
735 | |
736 int value = 0; | 727 int value = 0; |
737 | 728 |
738 if (m_colourScale == PhaseColourScale) { | 729 if (m_colourScale == PhaseColourScale) { |
739 | 730 |
740 double phase = atan2(-output[i][1], output[i][0]); | 731 double phase = atan2(-output[i][1], output[i][0]); |
741 value = int((phase * 128 / M_PI) + 128); | 732 value = int((phase * 128 / M_PI) + 128); |
742 | 733 |
743 } else { | 734 } else { |
735 | |
744 double mag = sqrt(output[i][0] * output[i][0] + | 736 double mag = sqrt(output[i][0] * output[i][0] + |
745 output[i][1] * output[i][1]); | 737 output[i][1] * output[i][1]); |
746 mag /= m_windowSize / 2; | 738 mag /= m_windowSize / 2; |
747 | 739 |
748 switch (m_colourScale) { | 740 switch (m_colourScale) { |
771 if (m_cacheInvalid || m_exiting) { | 763 if (m_cacheInvalid || m_exiting) { |
772 interrupted = true; | 764 interrupted = true; |
773 break; | 765 break; |
774 } | 766 } |
775 | 767 |
776 if (column < m_cache->width()) { | 768 if (column < m_cache->width() && (int)i < m_cache->height()) { |
777 m_cache->setPixel(column, i, value + 1); // 0 is "unset" | 769 m_cache->setPixel(column, i, value + 1); // 0 is "unset" |
778 } | 770 } |
779 } | 771 } |
780 | 772 |
781 if (lock) m_mutex.unlock(); | 773 if (lock) m_mutex.unlock(); |
793 | 785 |
794 bool interrupted = false; | 786 bool interrupted = false; |
795 | 787 |
796 // std::cerr << "SpectrogramLayer::CacheFillThread::run in loop" << std::endl; | 788 // std::cerr << "SpectrogramLayer::CacheFillThread::run in loop" << std::endl; |
797 | 789 |
798 if (m_layer.m_model && | 790 if (m_layer.m_model && m_layer.m_cacheInvalid) { |
799 (m_layer.m_cacheInvalid || | |
800 m_layer.m_maxFrequency > m_layer.m_maxCachedFrequency)) { | |
801 | 791 |
802 // std::cerr << "SpectrogramLayer::CacheFillThread::run: something to do" << std::endl; | 792 // std::cerr << "SpectrogramLayer::CacheFillThread::run: something to do" << std::endl; |
803 | 793 |
804 while (!m_layer.m_model->isReady()) { | 794 while (!m_layer.m_model->isReady()) { |
805 m_layer.m_condition.wait(&m_layer.m_mutex, 100); | 795 m_layer.m_condition.wait(&m_layer.m_mutex, 100); |
806 } | |
807 | |
808 size_t minFreq = 0; | |
809 if (!m_layer.m_cacheInvalid) { | |
810 minFreq = m_layer.m_maxCachedFrequency; | |
811 } | 796 } |
812 | 797 |
813 m_layer.m_cachedInitialVisibleArea = false; | 798 m_layer.m_cachedInitialVisibleArea = false; |
814 m_layer.m_cacheInvalid = false; | 799 m_layer.m_cacheInvalid = false; |
815 m_fillExtent = 0; | 800 m_fillExtent = 0; |
835 } | 820 } |
836 visibleEnd = m_layer.m_view->getEndFrame(); | 821 visibleEnd = m_layer.m_view->getEndFrame(); |
837 } | 822 } |
838 | 823 |
839 delete m_layer.m_cache; | 824 delete m_layer.m_cache; |
840 size_t bins = windowSize / 2; | |
841 if (m_layer.m_maxFrequency > 0) { | |
842 int sr = m_layer.m_model->getSampleRate(); | |
843 bins = int((double(m_layer.m_maxFrequency) * windowSize) / sr + 0.1); | |
844 if (bins > windowSize / 2) bins = windowSize / 2; | |
845 } | |
846 m_layer.m_cache = new QImage((end - start) / windowIncrement + 1, | 825 m_layer.m_cache = new QImage((end - start) / windowIncrement + 1, |
847 bins, //!!! | 826 windowSize / 2, |
848 QImage::Format_Indexed8); | 827 QImage::Format_Indexed8); |
849 | 828 |
850 m_layer.setCacheColourmap(); | 829 m_layer.setCacheColourmap(); |
851 | 830 |
852 m_layer.m_cache->fill(0); | 831 m_layer.m_cache->fill(0); |
853 m_layer.m_mutex.unlock(); | 832 m_layer.m_mutex.unlock(); |
857 | 836 |
858 fftw_complex *output = (fftw_complex *) | 837 fftw_complex *output = (fftw_complex *) |
859 fftw_malloc(windowSize * sizeof(fftw_complex)); | 838 fftw_malloc(windowSize * sizeof(fftw_complex)); |
860 | 839 |
861 fftw_plan plan = fftw_plan_dft_r2c_1d(windowSize, input, | 840 fftw_plan plan = fftw_plan_dft_r2c_1d(windowSize, input, |
862 output, FFTW_MEASURE); | 841 output, FFTW_ESTIMATE); |
863 | 842 |
864 Window<double> windower(m_layer.m_windowType, m_layer.m_windowSize); | 843 Window<double> windower(m_layer.m_windowType, m_layer.m_windowSize); |
865 | 844 |
866 if (!plan) { | 845 if (!plan) { |
867 std::cerr << "WARNING: fftw_plan(" << windowSize << ") failed!" << std::endl; | 846 std::cerr << "WARNING: fftw_plan_dft_r2c_1d(" << windowSize << ") failed!" << std::endl; |
868 fftw_free(input); | 847 fftw_free(input); |
869 fftw_free(output); | 848 fftw_free(output); |
870 m_layer.m_mutex.lock(); | 849 m_layer.m_mutex.lock(); |
871 continue; | 850 continue; |
872 } | 851 } |