mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 07:16:25 +02:00
note: I'm not sure what exactly causes naming conflict - importing QtMultimedia in ForceLoad.qml, or the fact of existance of Audio.qml, but starting with Qt 5.10.0 'Audio' already exists in global scope
634 lines
20 KiB
QML
634 lines
20 KiB
QML
//
|
|
// AudioScope.qml
|
|
//
|
|
// Created by Luis Cuenca on 11/22/2017
|
|
// Copyright 2017 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
import QtQuick 2.5
|
|
import QtQuick.Controls 1.4
|
|
import "styles-uit"
|
|
import "controls-uit" as HifiControlsUit
|
|
|
|
Item {
|
|
id: root
|
|
width: parent.width
|
|
height: parent.height
|
|
|
|
property var _scopeInputData
|
|
property var _scopeOutputLeftData
|
|
property var _scopeOutputRightData
|
|
|
|
property var _triggerInputData
|
|
property var _triggerOutputLeftData
|
|
property var _triggerOutputRightData
|
|
|
|
property var _triggerValues: QtObject{
|
|
property int x: parent.width/2
|
|
property int y: parent.height/3
|
|
}
|
|
|
|
property var _triggered: false
|
|
property var _steps
|
|
property var _refreshMs: 32
|
|
property var _framesPerSecond: AudioScope.getFramesPerSecond()
|
|
property var _isFrameUnits: true
|
|
|
|
property var _holdStart: QtObject{
|
|
property int x: 0
|
|
property int y: 0
|
|
}
|
|
|
|
property var _holdEnd: QtObject{
|
|
property int x: 0
|
|
property int y: 0
|
|
}
|
|
|
|
property var _timeBeforeHold: 300
|
|
property var _pressedTime: 0
|
|
property var _isPressed: false
|
|
|
|
property var _recOpacity : 0.0
|
|
property var _recSign : 0.05
|
|
|
|
property var _outputLeftState: false
|
|
property var _outputRightState: false
|
|
|
|
property var _wavFilePath: ""
|
|
|
|
function isHolding() {
|
|
return (_pressedTime > _timeBeforeHold);
|
|
}
|
|
|
|
function updateMeasureUnits() {
|
|
timeButton.text = _isFrameUnits ? "Display Frames" : "Milliseconds";
|
|
fiveLabel.text = _isFrameUnits ? "5" : "" + (Math.round(1000 * 5.0/_framesPerSecond));
|
|
twentyLabel.text = _isFrameUnits ? "20" : "" + (Math.round(1000 * 20.0/_framesPerSecond));
|
|
fiftyLabel.text = _isFrameUnits ? "50" : "" + (Math.round(1000 * 50.0/_framesPerSecond));
|
|
}
|
|
|
|
function collectScopeData() {
|
|
if (inputCh.checked) {
|
|
_scopeInputData = AudioScope.scopeInput;
|
|
}
|
|
if (outputLeftCh.checked) {
|
|
_scopeOutputLeftData = AudioScope.scopeOutputLeft;
|
|
}
|
|
if (outputRightCh.checked) {
|
|
_scopeOutputRightData = AudioScope.scopeOutputRight;
|
|
}
|
|
}
|
|
|
|
function collectTriggerData() {
|
|
if (inputCh.checked) {
|
|
_triggerInputData = AudioScope.triggerInput;
|
|
}
|
|
if (outputLeftCh.checked) {
|
|
_triggerOutputLeftData = AudioScope.triggerOutputLeft;
|
|
}
|
|
if (outputRightCh.checked) {
|
|
_triggerOutputRightData = AudioScope.triggerOutputRight;
|
|
}
|
|
}
|
|
|
|
function setRecordingLabelOpacity(opacity) {
|
|
_recOpacity = opacity;
|
|
recCircle.opacity = _recOpacity;
|
|
recText.opacity = _recOpacity;
|
|
}
|
|
|
|
function updateRecordingLabel() {
|
|
_recOpacity += _recSign;
|
|
if (_recOpacity > 1.0 || _recOpacity < 0.0) {
|
|
_recOpacity = _recOpacity > 1.0 ? 1.0 : 0.0;
|
|
_recSign *= -1;
|
|
}
|
|
setRecordingLabelOpacity(_recOpacity);
|
|
}
|
|
|
|
function pullFreshValues() {
|
|
if (AudioScriptingInterface.getRecording()) {
|
|
updateRecordingLabel();
|
|
}
|
|
|
|
if (!AudioScope.getPause()) {
|
|
if (!_triggered) {
|
|
collectScopeData();
|
|
}
|
|
}
|
|
if (inputCh.checked || outputLeftCh.checked || outputRightCh.checked) {
|
|
mycanvas.requestPaint();
|
|
}
|
|
}
|
|
|
|
function startRecording() {
|
|
_wavFilePath = (new Date()).toISOString(); // yyyy-mm-ddThh:mm:ss.sssZ
|
|
_wavFilePath = _wavFilePath.replace(/[\-:]|\.\d*Z$/g, "").replace("T", "-") + ".wav";
|
|
// Using controller recording default directory
|
|
_wavFilePath = Recording.getDefaultRecordingSaveDirectory() + _wavFilePath;
|
|
if (!AudioScriptingInterface.startRecording(_wavFilePath)) {
|
|
Messages.sendMessage("Hifi-Notifications", JSON.stringify({message:"Error creating: "+_wavFilePath}));
|
|
updateRecordingUI(false);
|
|
}
|
|
}
|
|
|
|
function stopRecording() {
|
|
AudioScriptingInterface.stopRecording();
|
|
setRecordingLabelOpacity(0.0);
|
|
Messages.sendMessage("Hifi-Notifications", JSON.stringify({message:"Saved: "+_wavFilePath}));
|
|
}
|
|
|
|
function updateRecordingUI(isRecording) {
|
|
if (!isRecording) {
|
|
recordButton.text = "Record";
|
|
recordButton.color = hifi.buttons.black;
|
|
outputLeftCh.checked = _outputLeftState;
|
|
outputRightCh.checked = _outputRightState;
|
|
} else {
|
|
recordButton.text = "Stop";
|
|
recordButton.color = hifi.buttons.red;
|
|
_outputLeftState = outputLeftCh.checked;
|
|
_outputRightState = outputRightCh.checked;
|
|
outputLeftCh.checked = true;
|
|
outputRightCh.checked = true;
|
|
}
|
|
}
|
|
|
|
function toggleRecording() {
|
|
if (AudioScriptingInterface.getRecording()) {
|
|
updateRecordingUI(false);
|
|
stopRecording();
|
|
} else {
|
|
updateRecordingUI(true);
|
|
startRecording();
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
interval: _refreshMs; running: true; repeat: true
|
|
onTriggered: pullFreshValues()
|
|
}
|
|
|
|
Canvas {
|
|
id: mycanvas
|
|
anchors.fill:parent
|
|
|
|
onPaint: {
|
|
|
|
function displayMeasureArea(ctx) {
|
|
|
|
ctx.fillStyle = Qt.rgba(0.1, 0.1, 0.1, 1);
|
|
ctx.fillRect(_holdStart.x, 0, _holdEnd.x - _holdStart.x, height);
|
|
|
|
ctx.lineWidth = "2";
|
|
ctx.strokeStyle = "#555555";
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(_holdStart.x, 0);
|
|
ctx.lineTo(_holdStart.x, height);
|
|
ctx.moveTo(_holdEnd.x, 0);
|
|
ctx.lineTo(_holdEnd.x, height);
|
|
|
|
ctx.moveTo(_holdStart.x, _holdStart.y);
|
|
ctx.lineTo(_holdEnd.x, _holdStart.y);
|
|
ctx.moveTo(_holdEnd.x, _holdEnd.y);
|
|
ctx.lineTo(_holdStart.x, _holdEnd.y);
|
|
|
|
ctx.stroke();
|
|
}
|
|
|
|
function displayTrigger(ctx, lineWidth, color) {
|
|
var crossSize = 3;
|
|
var holeSize = 2;
|
|
|
|
ctx.lineWidth = lineWidth;
|
|
ctx.strokeStyle = color;
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(_triggerValues.x - (crossSize + holeSize), _triggerValues.y);
|
|
ctx.lineTo(_triggerValues.x - holeSize, _triggerValues.y);
|
|
ctx.moveTo(_triggerValues.x + holeSize, _triggerValues.y);
|
|
ctx.lineTo(_triggerValues.x + (crossSize + holeSize), _triggerValues.y);
|
|
|
|
ctx.moveTo(_triggerValues.x, _triggerValues.y - (crossSize + holeSize));
|
|
ctx.lineTo(_triggerValues.x, _triggerValues.y - holeSize);
|
|
ctx.moveTo(_triggerValues.x, _triggerValues.y + holeSize);
|
|
ctx.lineTo(_triggerValues.x, _triggerValues.y + (crossSize + holeSize));
|
|
|
|
ctx.stroke();
|
|
}
|
|
|
|
function displayBackground(ctx, datawidth, steps, lineWidth, color) {
|
|
var verticalPadding = 100;
|
|
|
|
ctx.strokeStyle = color;
|
|
ctx.lineWidth = lineWidth;
|
|
|
|
ctx.moveTo(0, height/2);
|
|
ctx.lineTo(datawidth, height/2);
|
|
|
|
var gap = datawidth/steps;
|
|
for (var i = 0; i < steps; i++) {
|
|
ctx.moveTo(i*gap + 1, verticalPadding);
|
|
ctx.lineTo(i*gap + 1, height-verticalPadding);
|
|
}
|
|
ctx.moveTo(datawidth-1, verticalPadding);
|
|
ctx.lineTo(datawidth-1, height-verticalPadding);
|
|
|
|
ctx.stroke();
|
|
}
|
|
|
|
function drawScope(ctx, data, width, color) {
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = color;
|
|
ctx.lineWidth = width;
|
|
var x = 0;
|
|
for (var i = 0; i < data.length-1; i++) {
|
|
ctx.moveTo(x, data[i] + height/2);
|
|
ctx.lineTo(++x, data[i+1] + height/2);
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
|
|
function getMeasurementText(dist) {
|
|
var datasize = _scopeInputData.length;
|
|
var value = 0;
|
|
if (fiveFrames.checked) {
|
|
value = (_isFrameUnits) ? 5.0*dist/datasize : (Math.round(1000 * 5.0/_framesPerSecond))*dist/datasize;
|
|
} else if (twentyFrames.checked) {
|
|
value = (_isFrameUnits) ? 20.0*dist/datasize : (Math.round(1000 * 20.0/_framesPerSecond))*dist/datasize;
|
|
} else if (fiftyFrames.checked) {
|
|
value = (_isFrameUnits) ? 50.0*dist/datasize : (Math.round(1000 * 50.0/_framesPerSecond))*dist/datasize;
|
|
}
|
|
value = Math.abs(Math.round(value*100)/100);
|
|
var measureText = "" + value + (_isFrameUnits ? " frames" : " milliseconds");
|
|
return measureText;
|
|
}
|
|
|
|
function drawMeasurements(ctx, color) {
|
|
ctx.fillStyle = color;
|
|
ctx.font = "normal 16px sans-serif";
|
|
var fontwidth = 8;
|
|
var measureText = getMeasurementText(_holdEnd.x - _holdStart.x);
|
|
if (_holdStart.x < _holdEnd.x) {
|
|
ctx.fillText("" + height/2 - _holdStart.y, _holdStart.x-40, _holdStart.y);
|
|
ctx.fillText("" + height/2 - _holdEnd.y, _holdStart.x-40, _holdEnd.y);
|
|
ctx.fillText(measureText, _holdEnd.x+10, _holdEnd.y);
|
|
} else {
|
|
ctx.fillText("" + height/2 - _holdStart.y, _holdStart.x+10, _holdStart.y);
|
|
ctx.fillText("" + height/2 - _holdEnd.y, _holdStart.x+10, _holdEnd.y);
|
|
ctx.fillText(measureText, _holdEnd.x-fontwidth*measureText.length, _holdEnd.y);
|
|
}
|
|
}
|
|
|
|
var ctx = getContext("2d");
|
|
|
|
ctx.fillStyle = Qt.rgba(0, 0, 0, 1);
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
if (isHolding()) {
|
|
displayMeasureArea(ctx);
|
|
}
|
|
|
|
var guideLinesColor = "#555555"
|
|
var guideLinesWidth = "1"
|
|
|
|
displayBackground(ctx, _scopeInputData.length, _steps, guideLinesWidth, guideLinesColor);
|
|
|
|
var triggerWidth = "3"
|
|
var triggerColor = "#EFB400"
|
|
|
|
if (AudioScope.getAutoTrigger()) {
|
|
displayTrigger(ctx, triggerWidth, triggerColor);
|
|
}
|
|
|
|
var scopeWidth = "2"
|
|
var scopeInputColor = "#00B4EF"
|
|
var scopeOutputLeftColor = "#BB0000"
|
|
var scopeOutputRightColor = "#00BB00"
|
|
|
|
if (!_triggered) {
|
|
if (inputCh.checked) {
|
|
drawScope(ctx, _scopeInputData, scopeWidth, scopeInputColor);
|
|
}
|
|
if (outputLeftCh.checked) {
|
|
drawScope(ctx, _scopeOutputLeftData, scopeWidth, scopeOutputLeftColor);
|
|
}
|
|
if (outputRightCh.checked) {
|
|
drawScope(ctx, _scopeOutputRightData, scopeWidth, scopeOutputRightColor);
|
|
}
|
|
} else {
|
|
if (inputCh.checked) {
|
|
drawScope(ctx, _triggerInputData, scopeWidth, scopeInputColor);
|
|
}
|
|
if (outputLeftCh.checked) {
|
|
drawScope(ctx, _triggerOutputLeftData, scopeWidth, scopeOutputLeftColor);
|
|
}
|
|
if (outputRightCh.checked) {
|
|
drawScope(ctx, _triggerOutputRightData, scopeWidth, scopeOutputRightColor);
|
|
}
|
|
}
|
|
|
|
if (isHolding()) {
|
|
drawMeasurements(ctx, "#eeeeee");
|
|
}
|
|
|
|
if (_isPressed) {
|
|
_pressedTime += _refreshMs;
|
|
}
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: hitbox
|
|
anchors.fill: mycanvas
|
|
hoverEnabled: true
|
|
onPressed: {
|
|
_isPressed = true;
|
|
_pressedTime = 0;
|
|
_holdStart.x = mouseX;
|
|
_holdStart.y = mouseY;
|
|
}
|
|
onPositionChanged: {
|
|
_holdEnd.x = mouseX;
|
|
_holdEnd.y = mouseY;
|
|
}
|
|
onReleased: {
|
|
if (!isHolding() && AudioScope.getAutoTrigger()) {
|
|
_triggerValues.x = mouseX
|
|
_triggerValues.y = mouseY
|
|
AudioScope.setTriggerValues(mouseX, mouseY-height/2);
|
|
}
|
|
_isPressed = false;
|
|
_pressedTime = 0;
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: activated
|
|
boxSize: 20
|
|
anchors.top: parent.top;
|
|
anchors.left: parent.left;
|
|
anchors.topMargin: 8;
|
|
anchors.leftMargin: 20;
|
|
checked: AudioScope.getVisible();
|
|
onCheckedChanged: {
|
|
AudioScope.setVisible(checked);
|
|
activelabel.text = AudioScope.getVisible() ? "On" : "Off"
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Label {
|
|
id: activelabel
|
|
text: AudioScope.getVisible() ? "On" : "Off"
|
|
anchors.top: activated.top;
|
|
anchors.left: activated.right;
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: outputLeftCh
|
|
boxSize: 20
|
|
text: "Output L"
|
|
anchors.horizontalCenter: parent.horizontalCenter;
|
|
anchors.top: parent.top;
|
|
anchors.topMargin: 8;
|
|
onCheckedChanged: {
|
|
AudioScope.setServerEcho(outputLeftCh.checked || outputRightCh.checked);
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Label {
|
|
text: "Channels";
|
|
anchors.horizontalCenter: outputLeftCh.horizontalCenter;
|
|
anchors.bottom: outputLeftCh.top;
|
|
anchors.bottomMargin: 8;
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: inputCh
|
|
boxSize: 20
|
|
text: "Input Mono"
|
|
anchors.bottom: outputLeftCh.bottom;
|
|
anchors.right: outputLeftCh.left;
|
|
anchors.rightMargin: 40;
|
|
onCheckedChanged: {
|
|
AudioScope.setLocalEcho(checked);
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: outputRightCh
|
|
boxSize: 20
|
|
text: "Output R"
|
|
anchors.bottom: outputLeftCh.bottom;
|
|
anchors.left: outputLeftCh.right;
|
|
anchors.leftMargin: 40;
|
|
onCheckedChanged: {
|
|
AudioScope.setServerEcho(outputLeftCh.checked || outputRightCh.checked);
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Button {
|
|
id: recordButton;
|
|
text: "Record";
|
|
color: hifi.buttons.black;
|
|
colorScheme: hifi.colorSchemes.dark;
|
|
anchors.right: parent.right;
|
|
anchors.bottom: parent.bottom;
|
|
anchors.rightMargin: 30;
|
|
anchors.bottomMargin: 8;
|
|
width: 95;
|
|
height: 55;
|
|
onClicked: {
|
|
toggleRecording();
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Button {
|
|
id: pauseButton;
|
|
color: hifi.buttons.black;
|
|
colorScheme: hifi.colorSchemes.dark;
|
|
anchors.right: recordButton.left;
|
|
anchors.bottom: parent.bottom;
|
|
anchors.rightMargin: 30;
|
|
anchors.bottomMargin: 8;
|
|
height: 55;
|
|
width: 95;
|
|
text: " Pause ";
|
|
onClicked: {
|
|
AudioScope.togglePause();
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: twentyFrames
|
|
boxSize: 20
|
|
anchors.left: parent.horizontalCenter;
|
|
anchors.bottom: parent.bottom;
|
|
anchors.bottomMargin: 8;
|
|
onCheckedChanged: {
|
|
if (checked){
|
|
fiftyFrames.checked = false;
|
|
fiveFrames.checked = false;
|
|
AudioScope.selectAudioScopeTwentyFrames();
|
|
_steps = 20;
|
|
AudioScope.setPause(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Label {
|
|
id:twentyLabel
|
|
anchors.left: twentyFrames.right;
|
|
anchors.verticalCenter: twentyFrames.verticalCenter;
|
|
}
|
|
|
|
HifiControlsUit.Button {
|
|
id: timeButton;
|
|
color: hifi.buttons.black;
|
|
colorScheme: hifi.colorSchemes.dark;
|
|
text: "Display Frames";
|
|
anchors.horizontalCenter: twentyFrames.horizontalCenter;
|
|
anchors.bottom: twentyFrames.top;
|
|
anchors.bottomMargin: 8;
|
|
height: 26;
|
|
onClicked: {
|
|
_isFrameUnits = !_isFrameUnits;
|
|
updateMeasureUnits();
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: fiveFrames
|
|
boxSize: 20
|
|
anchors.horizontalCenter: parent.horizontalCenter;
|
|
anchors.bottom: parent.bottom;
|
|
anchors.bottomMargin: 8;
|
|
anchors.horizontalCenterOffset: -50;
|
|
checked: true;
|
|
onCheckedChanged: {
|
|
if (checked) {
|
|
fiftyFrames.checked = false;
|
|
twentyFrames.checked = false;
|
|
AudioScope.selectAudioScopeFiveFrames();
|
|
_steps = 5;
|
|
AudioScope.setPause(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Label {
|
|
id:fiveLabel
|
|
anchors.left: fiveFrames.right;
|
|
anchors.verticalCenter: fiveFrames.verticalCenter;
|
|
}
|
|
|
|
HifiControlsUit.CheckBox {
|
|
id: fiftyFrames
|
|
boxSize: 20
|
|
anchors.horizontalCenter: parent.horizontalCenter;
|
|
anchors.bottom: parent.bottom;
|
|
anchors.bottomMargin: 8;
|
|
anchors.horizontalCenterOffset: 70;
|
|
onCheckedChanged: {
|
|
if (checked) {
|
|
twentyFrames.checked = false;
|
|
fiveFrames.checked = false;
|
|
AudioScope.selectAudioScopeFiftyFrames();
|
|
_steps = 50;
|
|
AudioScope.setPause(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Label {
|
|
id:fiftyLabel
|
|
anchors.left: fiftyFrames.right;
|
|
anchors.verticalCenter: fiftyFrames.verticalCenter;
|
|
}
|
|
|
|
HifiControlsUit.Switch {
|
|
id: triggerSwitch;
|
|
height: 26;
|
|
anchors.left: parent.left;
|
|
anchors.bottom: parent.bottom;
|
|
anchors.leftMargin: 75;
|
|
anchors.bottomMargin: 8;
|
|
labelTextOff: "Off";
|
|
labelTextOn: "On";
|
|
onCheckedChanged: {
|
|
if (!checked) AudioScope.setPause(false);
|
|
AudioScope.setPause(false);
|
|
AudioScope.setAutoTrigger(checked);
|
|
AudioScope.setTriggerValues(_triggerValues.x, _triggerValues.y-root.height/2);
|
|
}
|
|
}
|
|
|
|
HifiControlsUit.Label {
|
|
text: "Trigger";
|
|
anchors.left: triggerSwitch.left;
|
|
anchors.leftMargin: -15;
|
|
anchors.bottom: triggerSwitch.top;
|
|
}
|
|
|
|
Rectangle {
|
|
id: recordIcon;
|
|
width:110;
|
|
height:40;
|
|
anchors.right: parent.right;
|
|
anchors.top: parent.top;
|
|
anchors.topMargin: 8;
|
|
color: "transparent"
|
|
|
|
Text {
|
|
id: recText
|
|
text: "REC"
|
|
color: "red"
|
|
font.pixelSize: 30;
|
|
anchors.left: recCircle.right;
|
|
anchors.leftMargin: 10;
|
|
opacity: _recOpacity;
|
|
y: -8;
|
|
}
|
|
|
|
Rectangle {
|
|
id: recCircle;
|
|
width: 25;
|
|
height: 25;
|
|
radius: width*0.5
|
|
opacity: _recOpacity;
|
|
color: "red";
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
_steps = AudioScope.getFramesPerScope();
|
|
AudioScope.setTriggerValues(_triggerValues.x, _triggerValues.y-root.height/2);
|
|
activated.checked = true;
|
|
inputCh.checked = true;
|
|
updateMeasureUnits();
|
|
}
|
|
|
|
Connections {
|
|
target: AudioScope
|
|
onPauseChanged: {
|
|
if (!AudioScope.getPause()) {
|
|
pauseButton.text = "Pause";
|
|
pauseButton.color = hifi.buttons.black;
|
|
AudioScope.setTriggered(false);
|
|
_triggered = false;
|
|
} else {
|
|
pauseButton.text = "Continue";
|
|
pauseButton.color = hifi.buttons.blue;
|
|
}
|
|
}
|
|
onTriggered: {
|
|
_triggered = true;
|
|
collectTriggerData();
|
|
AudioScope.setPause(true);
|
|
}
|
|
}
|
|
}
|