diff --git a/changes b/changes
index 7aa6076e0589e353b61e6340115812205f4696ba..0f0b29e1a6a791bd8afc460b4b0a55c01de58b0a 100644
--- a/changes
+++ b/changes
@@ -1,6 +1,10 @@
 1.5.1 alpha2
-     - simple metronome and menu for configuring tempo, quantization, etc.
+     - detecting duration (rhythm) of sound along with its pitch
+     - simple metronome and its menu for configuring parameters
+     - added bandoneon and saxophone views
+     - audio plays different sounds (piano, bandoneon, sax)
      - real support for transposing instruments
+     - more stuff ported to QML
 
 1.5.0 alpha1
      - added support for rhythms to the score
@@ -10,6 +14,12 @@
      - many improvements of user interface
      - option for enable/disable animations
 
+1.4.4
+     - German translation is complete
+     - support for marking more frets on the fingerboard
+    BUGS FIXES
+     - fixed annoying crash on entering settings when 'other' instrument was used
+
 1.4.3
     ANDROID
      - attempt to fix random crashes related to audio input
diff --git a/src/libs/core/tglobals.cpp b/src/libs/core/tglobals.cpp
index 196f441eba488a36cd1883d5afd828b598092204..859e1ccb14b1b479c86d5fd23045f73e3f4eb105 100755
--- a/src/libs/core/tglobals.cpp
+++ b/src/libs/core/tglobals.cpp
@@ -253,6 +253,9 @@ void Tglobals::setMarkedFrets(const QString& frets) {
 
 
 /* ------------------ Sound switches ------------------ */
+bool Tglobals::audioInEnabled() const { return A->INenabled; }
+void Tglobals::setAudioInEnabled(bool inEnabled) { A->INenabled = inEnabled; }
+
 QString Tglobals::inDevName() const { return A->INdevName; }
 void Tglobals::setInDevName(const QString& inName) { A->INdevName = inName; }
 
@@ -283,6 +286,14 @@ void Tglobals::setSkipStillerVal(qreal ssv) { A->skipStillerVal = ssv; }
 bool Tglobals::useFilter() const { return A->equalLoudness; }
 void Tglobals::setUseFilter(bool use) { A->equalLoudness = use; }
 
+bool Tglobals::audioOutEnabled() const { return A->OUTenabled; }
+void Tglobals::setAudioOutEnabled(bool outEnabled) { A->OUTenabled = outEnabled; }
+
+QString Tglobals::outDevName() const { return A->OUTdevName; }
+void Tglobals::setOutDevName(const QString& odn) { A->OUTdevName = odn; }
+
+bool Tglobals::forwardInput() const { return A->forwardInput; }
+void Tglobals::setForwardInput(bool fi) { A->forwardInput = fi; }
 
 
 void Tglobals::setGuitarParams(int fretNr, int stringNr) {
diff --git a/src/libs/core/tglobals.h b/src/libs/core/tglobals.h
index 5e115ddf97970164589260d8e0a5862634bb216a..106dbee98e2aaa1ef36e18f380f084d03d9f4307 100644
--- a/src/libs/core/tglobals.h
+++ b/src/libs/core/tglobals.h
@@ -82,6 +82,7 @@ class NOOTKACORE_EXPORT Tglobals : public QObject
   Q_PROPERTY(QString markedFrets READ markedFrets WRITE setMarkedFrets);
 
   /* Sound switches */
+  Q_PROPERTY(bool audioInEnabled READ audioInEnabled WRITE setAudioInEnabled)
   Q_PROPERTY(int audioInstrument READ audioInstrument WRITE setAudioInstrument)
   Q_PROPERTY(QString inDevName READ inDevName WRITE setInDevName);
   Q_PROPERTY(qreal minDuration READ minDuration WRITE setMinDuration)
@@ -90,6 +91,9 @@ class NOOTKACORE_EXPORT Tglobals : public QObject
   Q_PROPERTY(qreal minSplitVol READ minSplitVol WRITE setMinSplitVol)
   Q_PROPERTY(qreal skipStillerVal READ skipStillerVal WRITE setSkipStillerVal)
   Q_PROPERTY(bool useFilter READ useFilter WRITE setUseFilter)
+  Q_PROPERTY(bool audioOutEnabled READ audioOutEnabled WRITE setAudioOutEnabled)
+  Q_PROPERTY(QString outDevName READ outDevName WRITE setOutDevName);
+  Q_PROPERTY(bool forwardInput READ forwardInput WRITE setForwardInput)
 
 public:
 
@@ -184,6 +188,9 @@ public:
   void setMarkedFrets(const QString& frets);
 
   /* ------------------ Sound switches ------------------ */
+  bool audioInEnabled() const;
+  void setAudioInEnabled(bool inEnabled);
+
   int audioInstrument() const;
   void setAudioInstrument(int ai);
 
@@ -208,6 +215,15 @@ public:
   bool useFilter() const;
   void setUseFilter(bool use);
 
+  bool audioOutEnabled() const;
+  void setAudioOutEnabled(bool outEnabled);
+
+  QString outDevName() const;
+  void setOutDevName(const QString& odn);
+
+  bool forwardInput() const;
+  void setForwardInput(bool fi);
+
       /**
        * Updates key signature names according to name style and major/minor suffixes.
        * Emits @p keyNameChanged() to inform MainScore.qml
diff --git a/src/qml/settings/SoundPage.qml b/src/qml/settings/SoundPage.qml
index f52f5b1555740d47859a8deb23832b39fc169d70..bdbdec8d3fe09dbf8f24fafd03f9047c41c63d59 100644
--- a/src/qml/settings/SoundPage.qml
+++ b/src/qml/settings/SoundPage.qml
@@ -4,241 +4,345 @@
 
 import QtQuick 2.9 
 import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.3
 
 import "../"
 
 
-Flickable {
-  clip: true
-  contentHeight: audioCol.height
-  contentWidth: width
+Column {
+  spacing: nootkaWindow.fontSize
+  width: parent.width; height: parent.height
 
-  Column {
-    id: audioCol
+  ListView {
+    id: headList
+    orientation: ListView.Horizontal
+    spacing: nootkaWindow.fontSize
     width: parent.width
 
-    TcheckBox {
-      id: enableInChB
-      text: qsTr("enable pitch detection")
-      anchors.horizontalCenter: parent.horizontalCenter
-      checked: true
+    model: ListModel {
+      ListElement { head: QT_TR_NOOP("listening") }
+      ListElement { head: QT_TR_NOOP("playing") }
     }
 
-    Column {
-      enabled: enableInChB.checked
-      width: parent.width
-      spacing: nootkaWindow.fontSize
+    delegate: Button {
+      text: qsTranslate("TscoreSettings", head)
+      onClicked: { stack.currentIndex = index; headList.currentIndex = index }
+      highlighted: index === stack.currentIndex
+      Component.onCompleted: headList.height = Math.max(height, headList.height)
+    }
+  }
 
-      Tile {
-        description: qsTr("Be sure your input device (microphone, webcam, instrument, etc.) is plugged in, properly configured, and working.")
-        Row {
-          spacing: nootkaWindow.fontSize
-          anchors.horizontalCenter: parent.horizontalCenter
-          TlabelText { text: qsTr("input device") }
-          ComboBox {
-            id: inDevCombo
-            width: nootkaWindow.fontSize * 20
-            model: SOUND.inputDevices()
-            delegate: ItemDelegate { text: modelData }
-          }
-          TcheckBox {
-            visible: false // TODO
-            id:jackChB
-            text: "JACK"
-            anchors.verticalCenter: parent.verticalCenter
-          }
-        }
-      }
+  StackLayout {
+    id: stack
+    height: parent.height - headList.height - nootkaWindow.fontSize
+    width: parent.width
+    currentIndex: -1
 
-      Tile {
-        description: qsTr("Only sounds longer than the selected time will be pitch-detected.<br>Selecting a longer minimum note duration helps avoid capturing fret noise or other unexpected sounds but decreases responsiveness.")
-        Row {
-          spacing: nootkaWindow.fontSize
-          anchors.horizontalCenter: parent.horizontalCenter
-          TlabelText { text: qsTr("minimum note duration") }
-          SpinBox {
-            id: minDurSpin
-            from: 50; to: 1000
-            stepSize: 10
-            editable: true
-          }
-          TlabelText { text: qsTr("[milliseconds]") }
-        }
-      }
+    Tflickable { // "listening" page
+      contentHeight: inCol.height
+      contentWidth: width
 
-      Tile {
-        description: qsTr("Minimum volume of a sound to be pitch-detected")
-        Row {
-          spacing: nootkaWindow.fontSize
-          anchors.horizontalCenter: parent.horizontalCenter
-          Text { text: qsTr("minimum volume"); anchors.verticalCenter: parent.verticalCenter; color: enabled ? activPal.text : disdPal.text }
-          Slider {
-            anchors.verticalCenter: parent.verticalCenter
-            width: Math.min(nootkaWindow.fontSize * 15, parent.parent.width / 3)
-            from: 10; to: 80
-            value: volSpin.value
-            onValueChanged: volSpin.value = value
-            stepSize: 5
-          }
-          SpinBox {
-            id: volSpin
-            from: 10; to: 80
-            value: GLOB.minVolume * 100
-            editable: true
-          }
-          TlabelText { text: "%" }
-        }
-      }
+      Column {
+        id: inCol
+        width: parent.width
 
-      Tile {
-        enabled: false // TODO
-        description: qsTr("The base frequency of <i>middle a</i>.<br>Detection of the proper pitch of notes is relative to this value. This also affects the pitch of played sounds.")
-        Column {
-          width: parent.width
-          Row {
-            spacing: nootkaWindow.fontSize
-            anchors.horizontalCenter: parent.horizontalCenter
-            TlabelText { text: qsTr("middle A") }
-            Text { // staff
-              height: nootkaWindow.fontSize * 4.5
-              y: nootkaWindow.fontSize * -1.6
-              font { pixelSize: nootkaWindow.fontSize * 2.5; family: "scorek" }
-              text: "\ue014\ue014\ue014\ue014"
-              color: enabled ? activPal.text : disdPal.text
-              Text { // clef
-                x: nootkaWindow.fontSize / 4
-                y: nootkaWindow.fontSize * -0.6
-                color: parent.color
-                font: parent.font
-                text: "\ue050"
-              }
-              Text { // note
-                color: parent.color
-                font: parent.font
-                x: nootkaWindow.fontSize * 2.7
-                y: nootkaWindow.fontSize * -0.9
-                text: "\ue1d7"
-              }
-            }
-            SpinBox {
-              id: freqSpin
-              anchors.verticalCenter: parent.verticalCenter;
-              from: 391; to: 493 // in range of two semitones up and down around middle A (440Hz)
-              value: 440
-              editable: true
-            }
-            TlabelText { text: qsTr("[Hz]") }
-          }
+        TcheckBox {
+          id: enableInChB
+          text: qsTr("enable pitch detection")
+          anchors.horizontalCenter: parent.horizontalCenter
+          checked: true
         }
-      }
 
-      Frame { // advanced settings
-        width: parent.width * 0.99
-        anchors.horizontalCenter: parent.horizontalCenter
-        background: Rectangle {
-          color: "transparent"
-          border.color: "red"
-          radius: nootkaWindow.fontSize / 2
-        }
         Column {
+          enabled: enableInChB.checked
           width: parent.width
           spacing: nootkaWindow.fontSize
-          Switch {
-            id: advSwitch
-            text: qsTr("Advanced")
-            checked: false
-          }
+
           Tile {
-            visible: advSwitch.checked
+            description: qsTr("Be sure your input device (microphone, webcam, instrument, etc.) is plugged in, properly configured, and working.")
             Row {
-              anchors.horizontalCenter: parent.horizontalCenter
               spacing: nootkaWindow.fontSize
-              TlabelText { text: qsTr("pitch detection mode") }
+              anchors.horizontalCenter: parent.horizontalCenter
+              TlabelText { text: qsTr("input device") }
               ComboBox {
-                id: methodCombo
+                id: inDevCombo
                 width: nootkaWindow.fontSize * 20
-                model: ["MPM", "autocorrelation", "MPM + modified cepstrum"]
+                model: SOUND.inputDevices()
                 delegate: ItemDelegate { text: modelData }
               }
+              TcheckBox {
+                visible: false // TODO
+                id: jackInChB
+                text: "JACK"
+                anchors.verticalCenter: parent.verticalCenter
+              }
             }
           }
+
           Tile {
-            visible: advSwitch.checked
-            description: qsTr("Helps to properly detect the same notes repeated quickly on the guitar.")
+            description: qsTr("Only sounds longer than the selected time will be pitch-detected.<br>Selecting a longer minimum note duration helps avoid capturing fret noise or other unexpected sounds but decreases responsiveness.")
             Row {
-              anchors.horizontalCenter: parent.horizontalCenter
               spacing: nootkaWindow.fontSize
-              TcheckBox {
-                id: splitVolChB
-                text: qsTr("split when volume rise")
-              }
+              anchors.horizontalCenter: parent.horizontalCenter
+              TlabelText { text: qsTr("minimum note duration") }
               SpinBox {
-                id: splitVolSpin
-                from: 5; to: 50
-                enabled: splitVolChB.checked
+                id: minDurSpin
+                from: 50; to: 1000
+                stepSize: 10
                 editable: true
               }
-              TlabelText { text: "%" }
+              TlabelText { text: qsTr("[milliseconds]") }
             }
           }
+
           Tile {
-            visible: advSwitch.checked
-            description: qsTr("Skips stiller sounds, below given percent of average volume. It prevents detecting of harmonics on classical or acoustic guitar but requires playing with similar strength.")
+            description: qsTr("Minimum volume of a sound to be pitch-detected")
             Row {
-              anchors.horizontalCenter: parent.horizontalCenter
               spacing: nootkaWindow.fontSize
-              TcheckBox {
-                id: skipStillerChB
-                text: qsTr("skip stiller than")
+              anchors.horizontalCenter: parent.horizontalCenter
+              Text { text: qsTr("minimum volume"); anchors.verticalCenter: parent.verticalCenter; color: enabled ? activPal.text : disdPal.text }
+              Slider {
+                anchors.verticalCenter: parent.verticalCenter
+                width: Math.min(nootkaWindow.fontSize * 15, parent.parent.width / 3)
+                from: 10; to: 80
+                value: volSpin.value
+                onValueChanged: volSpin.value = value
+                stepSize: 5
               }
               SpinBox {
-                id: skipStillerSpin
-                from: 10; to: 95
-                enabled: skipStillerChB.checked
+                id: volSpin
+                from: 10; to: 80
+                value: Math.ceil(GLOB.minVolume * 100)
                 editable: true
               }
               TlabelText { text: "%" }
             }
           }
+
+          Tile {
+            enabled: false // TODO
+            description: qsTr("The base frequency of <i>middle a</i>.<br>Detection of the proper pitch of notes is relative to this value. This also affects the pitch of played sounds.")
+            Column {
+              width: parent.width
+              Row {
+                spacing: nootkaWindow.fontSize
+                anchors.horizontalCenter: parent.horizontalCenter
+                TlabelText { text: qsTr("middle A") }
+                Text { // staff
+                  height: nootkaWindow.fontSize * 4.5
+                  y: nootkaWindow.fontSize * -1.6
+                  font { pixelSize: nootkaWindow.fontSize * 2.5; family: "scorek" }
+                  text: "\ue014\ue014\ue014\ue014"
+                  color: enabled ? activPal.text : disdPal.text
+                  Text { // clef
+                    x: nootkaWindow.fontSize / 4
+                    y: nootkaWindow.fontSize * -0.6
+                    color: parent.color
+                    font: parent.font
+                    text: "\ue050"
+                  }
+                  Text { // note
+                    color: parent.color
+                    font: parent.font
+                    x: nootkaWindow.fontSize * 2.7
+                    y: nootkaWindow.fontSize * -0.9
+                    text: "\ue1d7"
+                  }
+                }
+                SpinBox {
+                  id: freqSpin
+                  anchors.verticalCenter: parent.verticalCenter;
+                  from: 391; to: 493 // in range of two semitones up and down around middle A (440Hz)
+                  value: 440
+                  editable: true
+                }
+                TlabelText { text: qsTr("[Hz]") }
+              }
+            }
+          }
+
+          Frame { // advanced settings
+            width: parent.width * 0.99
+            anchors.horizontalCenter: parent.horizontalCenter
+            background: Rectangle {
+              color: "transparent"
+              border.color: enabled ? "red" : disdPal.text
+              radius: nootkaWindow.fontSize / 2
+            }
+            Column {
+              width: parent.width
+              spacing: nootkaWindow.fontSize
+              Switch {
+                id: advSwitch
+                text: qsTr("Advanced")
+                checked: false
+              }
+              Tile {
+                visible: advSwitch.checked
+                Row {
+                  anchors.horizontalCenter: parent.horizontalCenter
+                  spacing: nootkaWindow.fontSize
+                  TlabelText { text: qsTr("pitch detection mode") }
+                  ComboBox {
+                    id: methodCombo
+                    width: nootkaWindow.fontSize * 20
+                    model: ["MPM", "autocorrelation", "MPM + modified cepstrum"]
+                    delegate: ItemDelegate { text: modelData }
+                  }
+                }
+              }
+              Tile {
+                visible: advSwitch.checked
+                description: qsTr("Helps to properly detect the same notes repeated quickly on the guitar.")
+                Row {
+                  anchors.horizontalCenter: parent.horizontalCenter
+                  spacing: nootkaWindow.fontSize
+                  TcheckBox {
+                    id: splitVolChB
+                    anchors.verticalCenter: parent.verticalCenter
+                    text: qsTr("split when volume rise")
+                  }
+                  SpinBox {
+                    id: splitVolSpin
+                    from: 5; to: 50
+                    enabled: splitVolChB.checked
+                    editable: true
+                  }
+                  TlabelText { text: "%" }
+                }
+              }
+              Tile {
+                visible: advSwitch.checked
+                description: qsTr("Skips stiller sounds, below given percent of average volume. It prevents detecting of harmonics on classical or acoustic guitar but requires playing with similar strength.")
+                Row {
+                  anchors.horizontalCenter: parent.horizontalCenter
+                  spacing: nootkaWindow.fontSize
+                  TcheckBox {
+                    id: skipStillerChB
+                    anchors.verticalCenter: parent.verticalCenter
+                    text: qsTr("skip stiller than")
+                  }
+                  SpinBox {
+                    id: skipStillerSpin
+                    from: 10; to: 95
+                    enabled: skipStillerChB.checked
+                    editable: true
+                  }
+                  TlabelText { text: "%" }
+                }
+              }
+              Tile {
+                visible: advSwitch.checked
+                description: qsTr("It is rather necessary for mic input but may be switched off for an instrument plugged line-in with less noise.")
+                TcheckBox {
+                  id: noiseFilterChB
+                  anchors.horizontalCenter: parent.horizontalCenter
+                  text: qsTr("noise filter")
+                }
+              }
+            }
+          }
+
+        }
+      }
+
+    }
+
+    Tflickable { // "playing" page
+      contentHeight: outCol.height
+      contentWidth: width
+      Column {
+        id: outCol
+        width: parent.width
+        spacing: nootkaWindow.fontSize
+
+        TcheckBox {
+          id: enableOutChB
+          text: qsTr("play sound")
+          anchors.horizontalCenter: parent.horizontalCenter
+          checked: true
+        }
+
+        Column {
+          enabled: enableOutChB.checked
+          width: parent.width
+          spacing: nootkaWindow.fontSize
+
+          Row {
+            spacing: nootkaWindow.fontSize
+            anchors.horizontalCenter: parent.horizontalCenter
+            TlabelText { text: qsTr("output device") }
+            ComboBox {
+              id: outDevCombo
+              width: nootkaWindow.fontSize * 20
+              model: SOUND.outputDevices()
+              delegate: ItemDelegate { text: modelData }
+            }
+            TcheckBox {
+              visible: false // TODO
+              id: jackOutChB
+              text: "JACK"
+              anchors.verticalCenter: parent.verticalCenter
+            }
+          }
           Tile {
-            visible: advSwitch.checked
-            description: qsTr("It is rather necessary for mic input but may be switched off for an instrument plugged line-in with less noise.")
+            description: qsTr("All sounds captured by audio input will be forwarded directly to output device.")
             TcheckBox {
-              id: noiseFilterChB
+              id: forwardInChB
               anchors.horizontalCenter: parent.horizontalCenter
-              text: qsTr("noise filter")
+              text: qsTr("forward input to output")
             }
           }
         }
       }
-
     }
   }
 
-  ScrollBar.vertical: ScrollBar { active: !Noo.isAndroid() }
-
   Component.onCompleted: {
-    inDevCombo.currentIndex = inDevCombo.find(SOUND.currentInDevName())
-    minDurSpin.value = GLOB.minDuration * 1000
+    if (inDevCombo.currentIndex === -1)
+      inDevCombo.model = qsTr("no devices found")
+    else
+      inDevCombo.currentIndex = inDevCombo.find(SOUND.currentInDevName())
+    minDurSpin.value = Math.ceil(GLOB.minDuration * 1000)
     methodCombo.currentIndex = GLOB.detectionMethod
     splitVolChB.checked = GLOB.minSplitVol > 0
     splitVolSpin.value = GLOB.minSplitVol
     skipStillerChB.checked = GLOB.skipStillerVal > 0
     skipStillerSpin.value = GLOB.skipStillerVal
     noiseFilterChB.checked = GLOB.useFilter
+    enableInChB.checked = GLOB.audioInEnabled
+
+    if (outDevCombo.currentIndex === -1)
+      outDevCombo.model = qsTr("no devices found")
+    else
+      outDevCombo.currentIndex = outDevCombo.find(SOUND.currentOutDevName())
+    forwardInChB.checked = GLOB.forwardInput
+    enableOutChB.checked = GLOB.audioOutEnabled
   }
 
   function save() {
-    GLOB.inDevName = inDevCombo.currentText
-    GLOB.minDuration = minDurSpin.value / 1000.0
-    GLOB.minVolume = volSpin.value / 100.0
-    GLOB.detectionMethod = methodCombo.currentIndex
-    GLOB.minSplitVol= splitVolChB.checked ? splitVolSpin.value : 0
-    GLOB.skipStillerVal = skipStillerChB.checked ? skipStillerSpin.value : 0
-    GLOB.useFilter = noiseFilterChB.checked
+    if (enableInChB.checked) {
+      GLOB.inDevName = inDevCombo.currentText
+      GLOB.minDuration = minDurSpin.value / 1000.0
+      GLOB.minVolume = volSpin.value / 100.0
+      GLOB.detectionMethod = methodCombo.currentIndex
+      GLOB.minSplitVol = splitVolChB.checked ? splitVolSpin.value : 0
+      GLOB.skipStillerVal = skipStillerChB.checked ? skipStillerSpin.value : 0
+      GLOB.useFilter = noiseFilterChB.checked
+    }
+    GLOB.audioInEnabled = enableInChB.checked
+
+    if (enableOutChB.checked) {
+      GLOB.outDevName = outDevCombo.currentText
+      GLOB.forwardInput = forwardInChB.checked
+    }
+    GLOB.audioOutEnabled = enableOutChB.checked
+    SOUND.acceptSettings()
   }
 
   function defaults() {
+    enableInChB.checked = true
+    inDevCombo.currentIndex = 0
     minDurSpin.value = 150
     volSpin.value = 40
     freqSpin.value = 440
@@ -248,5 +352,9 @@ Flickable {
     skipStillerChB.checked = true
     skipStillerSpin.value = 80
     noiseFilterChB.checked = true
+
+    enableOutChB.checked = true
+    outDevCombo.currentIndex = 0
+    forwardInChB.checked = false
   }
 }