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 }