Tartini/en

De Wiki LOGre
< Tartini
Révision de 28 avril 2016 à 22:17 par A427 (discuter | contributions) (Bugs)

(diff) ← Version précédente | Voir la version courante (diff) | Version suivante → (diff)
Aller à : navigation, rechercher
Language: Français  • English

Introduction

Tartini is a musical analysis software written by a PhD student from the New Zealand Otago university.
The last version of this software dates back from 2008 and didn't evolve since then.
Since that time, numerous versions of Qt and Qwt( the libraries it is based on ) have been released.
Our goal is to try and continue to make the software to evolve in order to cope with these libraries evolution

Tartini version 1.2.0 Windows screenshot

Contributors

Environment

OS

  • Linux : Kubuntu 14.04
  • Linux/virtualbox : debian etch/lenny

Development tools

Libraries

Continuous integration

Source code

Virtual Environment (virtualbox)

The virtual environment (virtualbox) allows to test tartini on ancient systems, eg: debian etch

Procedure :

  • Install virtualbox (virtualbox.org) and create a new debian

virtual machine

  • download an installation CD of debian etch and install it in the virtual machine
  • once inside the virtual debian, modify the /etc/sources.list
  • then as root :
    • # apt-get update
    • # apt-get install build-essential linux-headers-`uname -r`
  • finally insert the virtualbox extensions CD and launch as root :
    • # VBoxLinuxAdditions.run
  • now the mouse, screen and shared clipboard are better managed

Progress

Version 1.2.0 status

This is the last available official version

  • Linux : source code available, based on Qt 4.2.3 and Qwt 5.x
  • Windows : also available in binary format
  • MacOs : also available in binary format for PowerPC

Windows version seems to work correctly.
There are some issues when compiling under Linux with gcc 4.8.4:

  • Missing includes
  • Incomplete link due to missing libraries, non-specified in .pro file
  • Segfault on recording due to a negative index used during an array access

The linux version has been tested on some distributions :

Distribution QT Qwt FFTW
debian 4.0 (etch) 32 bits 4.2.1 5.0.1 3.2.2
debian 5.0 (lenny) 32 bits 4.4.3 5.0.1 3.2.2
debian 5.0 (lenny) 64 bits 4.4.3 5.0.1 3.2.2
Kubuntu 14.04 64 bits 4.8.5 5.2.3-1 3.3.3-7ubuntu3

Bugs

  • These bugs appear with the file 'on_the_run.wav'
  • For debian the tartini version is github.com/nsauzede/tartini.git b8a4f
Id Bug debian 4.0 32 bits debian 5.0 32 bits debian 5.0 64 bits Kubuntu 14.04 64 bits
1 SegFault prevAnalysis NO  ???  ??? YES
2 SegFault Harmonic stack opening NO  ???  ??? YES
3 SegFault Harmonic cycle navigation NO  ???  ??? YES

Bug 1

It happens as a segfault at line 497 of the file general/mytransforms.cpp.

//calc the periodDiff
      if(chunk > 0
// && prevAnalysisData->highestCorrelationIndex!=-1
) {
/* Line 497 */        float prevPeriod = prevAnalysisData->periodEstimates[prevAnalysisData->getHighestCorrelationIndex()];

The field highestCorrelationIndex of prevAnalysisData equals to -1 and the array analysisData.periodEstimates is empty
By comparing with the execution on Debian 4 that doesn't crash we can see that the values are the same but in Debian 4 this doesn't cause trouble to the std lib that give back 0 for prevPeriod
The initial patch consisted in testing the index value as well as that from the chunk but if we want to get the same behaviour than the one got on Debian 4 we better patch this way:

      if(chunk > 0
// && prevAnalysisData->highestCorrelationIndex!=-1
) {
        float prevPeriod = prevAnalysisData->getHighestCorrelationIndex() != -1 ? prevAnalysisData->periodEstimates[prevAnalysisData->getHighestCorrelationIndex()] : 0;

highestCorrelationIndex of prevAnalysisData is -1 and the array analysisData.periodEstimates is empty because the samples are compared to a cutoff value and in this case they are all below the threshold.

Bug 2

It happens as a segfault at line 129 of file widgets/hstack/hstackwidget.cpp.

        int m = MIN(data->harmonicAmpNoCutOff.size(), (unsigned) numHarmonics);
        for (j = 0; j < m;j++)
        {
/* 129 */ if (!isinf(data->harmonicAmpRelative[j]))
          {
            points[j].setPoint(i+2,toInt(scaleX*(float)i),-toInt((-top + data->harmonicAmpNoCutOff[j])*scaleY)); 
          }

j has a value above the size of the vector harmonicAmpRelative which triggers the crash.
By looking the code more closely we can see that the boundaries of the loop are defined by the size of the vector harmonicAmpNoCutOff and that the points are traced from the data from that same vector. We hence deduce that the test should be done on that vector and not on harmonicAmpRelative
Once the correction done the data display in the widget without crash

        int m = MIN(data->harmonicAmpNoCutOff.size(), (unsigned) numHarmonics);
        for (j = 0; j < m;j++)
        {
/* 129 */ if (!isinf(data->harmonicAmpNoCutOff[j]))
          {
            points[j].setPoint(i+2,toInt(scaleX*(float)i),-toInt((-top + data->harmonicAmpNoCutOff[j])*scaleY)); 
          }


Bug 3

It happens as a segfault at line 117 of file widgets/hcircle/hcirclewidget.cpp.

		for (i = 0; i < numHarmonics; i++)
		{
/* 117 */			if (data->harmonicFreq[i] > nextoctave)
			{
				octave = nextoctave;
				nextoctave = octave * 2;
			}
			if (data->harmonicAmpNoCutOff[i] > MAX(threshold, lowestValue))			
			{
				double angle = (data->harmonicFreq[i] - octave) / (nextoctave - octave) * 2 * PI;
				double size = height()*zoom*(data->harmonicAmpNoCutOff[i]-lowestValue);

i has a value above the size of the vector harmonicFreq which triggers the crash.
By looking more closely we can see that the loop is done on the number of harmonics (numHarmonics) without taking into account the size of vectors harmonicAmpNoCutOff and harmonicFreq which BTW have the same size by construction
By modifying the code to iterate on the minimum size of the vectors and of numHarmonics there is no more array boundaries overflow and everything is functioning normally.

	  int m = MIN(data->getHarmonicAmpNoCutOffSize(), (unsigned) numHarmonics);
	  assert(data->getHarmonicAmpNoCutOffSize() == data->getHarmonicFreqSize());
	  for (i = 0; i < m; i++)
	    {
	      if (data->getHarmonicFreqAt(i) > nextoctave)
		{
		  octave = nextoctave;
		  nextoctave = octave * 2;
		}
	      if (data->getHarmonicAmpNoCutOffAt(i) > MAX(threshold, lowestValue))			
		{
		  double angle = (data->getHarmonicFreqAt(i) - octave) / (nextoctave - octave) * 2 * PI;
		  double size = height()*zoom*(data->getHarmonicAmpNoCutOffAt(i) - lowestValue);
		  double size1 = height()*zoom*(MAX(threshold, lowestValue)-lowestValue);
		  int x1 = toInt(sin(angle)*size1);
		  int y1 = toInt(-cos(angle)*size1);

Changes

External modifications integrated

  • Search for modifications done here and there by various people ( mostly to succeed compile the linux version)
  • Fetch all Debian patches available in the repository Tartini-debian in order to integrate them in the code
    • Build patches
    • Useless files removal
    • Work around the negative index bug by adding a test
    • Memory leaks fix
  • Fetch the partial german translation from the repository Tartini de Guildenstern

Our modifications

  • Usage of Travis CI for continuous integration
  • Started french translation : Work in progress
  • Port from Qwt 5.x to Qwt 6.x : Work in progress in a dedicated branch
  • Remaining Qt3 code cleanup : Work in progress