// tonalisa - software to look at overtone-structures // Copyright (C) 2016 Dominik Schmidt-Philipp // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Controls 1.2 import QtQuick.Dialogs 1.2 import QtQml 2.2 import art.freakaria.ton 1.0 Window { id: root visible: true width:900;height:400 Rectangle { anchors.fill:parent color:Qt.hsla(.5,0,1,.5) } Item { id:buffer property var spectrumR0: [] property var spectrumR1: [] property var spectrumF0: [110, 1, 220, 0.5, 330, 0.25, 440, 0.125, 550, 0.1, 660, 0.1, 770, 0.1, 880, 0.1] property var spectrumF1: [] property var gridTunedStep:9 property var gridPitch:440 property var gridLowest:27 property var gridHighest:8000 property var grid:[0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100] onGridChanged: { keyboard.calculate_spectrum() } onSpectrumR0Changed:{spectrumR1 = spectrumR0 } onSpectrumF0Changed:{ dissonanceCalculator.prepare_spectrum() } } Item { width: 300//Math.min(parent.width, parent.height) height:300//Math.min(parent.width, parent.height) SpiralView { id:spiral anchors.fill:parent paintAxes:true paintGrid:true fBase:27.5 // sub kontra A octaves:8 gridTunedStep:buffer.gridTunedStep gridPitch:buffer.gridPitch gridLowest:buffer.gridLowest gridHighest:buffer.gridHighest grid:buffer.grid peaks:buffer.spectrumF0 } } Item { x:300;y:300 width:600; height:100 Keyboard { id:keyboard transpose:-2 inSpectrum:buffer.spectrumR0 onInSpectrumChanged: { calculate_spectrum() } } SpinBox { id:keyTranspose minimumValue: -5 maximumValue: 8 value:-2 onValueChanged: { keyboard.transpose = value keyboard.calculate_spectrum() } anchors.right:parent.right } } Item { x:0;y:300 width:300;height:100 Rectangle { anchors.fill:parent color:"#fff" Column { Row { id:spiralDisplayOptions spacing:5 CheckBox { text:qsTr("Raster") onCheckedChanged: { spiral.paintGrid=checked } checked:true } CheckBox { text:qsTr("Spirale") onCheckedChanged: { spiral.paintAxes=checked } checked:true } } Row { id:harmonicGenerator spacing:5 SpinBox { id:nPartials onValueChanged: parent.update_spectrum() minimumValue: 1 maximumValue: 81 } CheckBox { id:filterEven text:qsTr("nur ungerade Teiltöne") onCheckedChanged:parent.update_spectrum() } SpinBox { id:inharmonicity onValueChanged: parent.update_spectrum() minimumValue:-999 maximumValue:999 value:0 } function update_spectrum() { var y=[] var log2=Math.log(2) for(var i=1;i<=nPartials.value;i++) { if(filterEven.checked && ((i%2)==0)) continue; y.push(Math.pow(2+(inharmonicity.value/1000),Math.log(i)/log2)) //y.push(i) y.push(1/i) } buffer.spectrumR0 = y } } Row { id:gridGenerator spacing:5 Text { text:qsTr("Raster: von") } TextInput { text:"27" onEditingFinished:{buffer.gridLowest = text } validator: IntValidator{bottom:0; top:10000} selectByMouse:true } Text { text:qsTr("bis") } TextInput { text:"8000" onEditingFinished:{buffer.gridHighest= text } validator: IntValidator{bottom:0; top:20000} selectByMouse:true } Text { text:qsTr("Stimmton") } TextInput { text:"440" onEditingFinished:{buffer.gridPitch = text } validator: IntValidator{bottom:0; top:10000} selectByMouse:true } } } Row { id:mainMenu spacing:1 anchors.bottom:parent.bottom Button { text:qsTr("AUDIO") onClicked: { audioWindow.visible=true } } Button { text:qsTr("CDC-5") onClicked: { cdc5Window.visible=true } } Button { text:qsTr("Skalen") onClicked: { scaleWindow.visible=true } } Button { text:qsTr("DB") onClicked: { databaseWindow.visible=true } width:50 } } } } Cartesian { id: cartesian x:300; y:0 height: 283; width: 600 fillColor:"#fff" leftHz:55 rightHz:8000 logx:logToggle.checked paintGrid:cartesianGridToggle.checked paintFFT:audioWindow.visible gridTunedStep:buffer.gridTunedStep gridPitch:buffer.gridPitch gridLowest:buffer.gridLowest gridHighest:buffer.gridHighest grid:buffer.grid peaks:buffer.spectrumF0 fftData: audio.audio.spectrum sampleRate:audio.audio.sampleRate pointerFreq:spiral.pointerFreq pointerAmp:spiral.pointerAmp Rectangle { width:4;height:4;radius:2; color:"red"; x: parent.pointerPos.x y: parent.pointerPos.y } MouseArea { anchors.fill: parent hoverEnabled: true function getFreqAmp(x,y){ var result = {"freq":0.0,"amp":0.0} result.freq=(parent.rightHz-parent.leftHz)/parent.width * x + parent.leftHz result.amp=Math.pow(10,y/parent.height*parent.dbFloor/20) return result; } onPositionChanged: { var pos = getFreqAmp(mouseX,mouseY); spiral.pointerFreq = pos.freq spiral.pointerAmp = pos.amp } } } Item { id:cartesianOptions width:600;height:20 x:300;y:283 Row { spacing:5 CheckBox{ id:logToggle text:qsTr("logarithmische Achse") } CheckBox { id:cartesianGridToggle text:qsTr("Raster") checked:true } } Item { anchors.right:parent.right width:120; height:17 Row { spacing:5 Text {text:qsTr("zeige")} TextInput { text:"55" onEditingFinished:{cartesian.leftHz = text } validator: IntValidator{bottom:0; top:10000} selectByMouse:true focus:true } Text { text:qsTr("bis") } TextInput { text:"8000" onEditingFinished:{cartesian.rightHz = text } validator: IntValidator{bottom:81; top:20000} selectByMouse:true focus:true } Text { text:qsTr("Hz") } } } } Window { id:scaleWindow title:qsTr("Skalen") visible:true width:170;height:400 ScaleBrowser { id:scales anchors.fill:parent } } Window { id:audioWindow title:qsTr("Audio Analyse") visible:false width:700;height:200 // onVisibleChanged: {} AudioSegment { id:audio anchors.fill:parent } } Window { id:databaseWindow title:qsTr("Datenbank") visible:false width:200;height:300 SpectrumBrowser { id:spectra anchors.fill:parent } } Window { id:cdc5Window title:qsTr("Dissonanz Berechnungen") visible:false width:600;height:300 property var grundton:440 onGrundtonChanged: { dissonanceCalculator.prepare_spectrum() } Row { anchors.bottom:parent.bottom height:17 spacing:5 Text { text:qsTr("Grundton "+buffer.spectrumF0[0]+"Hz | ") } Text { text:qsTr("Maximal darstellbare Rauhigkeit") } TextInput { text:"0.5" onEditingFinished:{dissonanceCurve.maxDissonance = text } validator: DoubleValidator{bottom:0.000001; top:20;decimals:5} selectByMouse:true focus:true } } Dissonance { id:dissonanceCalculator function prepare_spectrum() { if (cdc5Window.visible) { var f=[]; var a=[]; for(var i=0;i