Mercurial > hg > svgui
comparison layer/WaveformLayer.cpp @ 1474:36ad3cdabf55 by-id
Further layer updates for ModelById
author | Chris Cannam |
---|---|
date | Tue, 02 Jul 2019 14:08:44 +0100 |
parents | f2525e6cbdf1 |
children | 1ccb64bfb22b |
comparison
equal
deleted
inserted
replaced
1473:886c1cd48f9d | 1474:36ad3cdabf55 |
---|---|
39 using std::vector; | 39 using std::vector; |
40 | 40 |
41 | 41 |
42 WaveformLayer::WaveformLayer() : | 42 WaveformLayer::WaveformLayer() : |
43 SingleColourLayer(), | 43 SingleColourLayer(), |
44 m_model(nullptr), | |
45 m_gain(1.0f), | 44 m_gain(1.0f), |
46 m_autoNormalize(false), | 45 m_autoNormalize(false), |
47 m_showMeans(true), | 46 m_showMeans(true), |
48 m_channelMode(SeparateChannels), | 47 m_channelMode(SeparateChannels), |
49 m_channel(-1), | 48 m_channel(-1), |
62 | 61 |
63 const ZoomConstraint * | 62 const ZoomConstraint * |
64 WaveformLayer::getZoomConstraint() const | 63 WaveformLayer::getZoomConstraint() const |
65 { | 64 { |
66 auto model = ModelById::get(m_model); | 65 auto model = ModelById::get(m_model); |
67 if (model) return m_model->getZoomConstraint(); | 66 if (model) return model->getZoomConstraint(); |
68 else return nullptr; | 67 else return nullptr; |
69 } | 68 } |
70 | 69 |
71 void | 70 void |
72 WaveformLayer::setModel(ModelId modelId) | 71 WaveformLayer::setModel(ModelId modelId) |
112 PropertyList list = SingleColourLayer::getProperties(); | 111 PropertyList list = SingleColourLayer::getProperties(); |
113 list.push_back("Scale"); | 112 list.push_back("Scale"); |
114 list.push_back("Gain"); | 113 list.push_back("Gain"); |
115 list.push_back("Normalize Visible Area"); | 114 list.push_back("Normalize Visible Area"); |
116 | 115 |
117 if (m_model && m_model->getChannelCount() > 1 && m_channel == -1) { | 116 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); |
117 if (model && model->getChannelCount() > 1 && m_channel == -1) { | |
118 list.push_back("Channels"); | 118 list.push_back("Channels"); |
119 } | 119 } |
120 | 120 |
121 return list; | 121 return list; |
122 } | 122 } |
339 | 339 |
340 int | 340 int |
341 WaveformLayer::getCompletion(LayerGeometryProvider *) const | 341 WaveformLayer::getCompletion(LayerGeometryProvider *) const |
342 { | 342 { |
343 int completion = 100; | 343 int completion = 100; |
344 if (!m_model || !m_model->isOK()) return completion; | 344 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); |
345 if (m_model->isReady(&completion)) return 100; | 345 if (!model || !model->isOK()) return completion; |
346 if (model->isReady(&completion)) return 100; | |
346 return completion; | 347 return completion; |
347 } | 348 } |
348 | 349 |
349 bool | 350 bool |
350 WaveformLayer::getValueExtents(double &min, double &max, | 351 WaveformLayer::getValueExtents(double &min, double &max, |
377 int | 378 int |
378 WaveformLayer::getChannelArrangement(int &min, int &max, | 379 WaveformLayer::getChannelArrangement(int &min, int &max, |
379 bool &merging, bool &mixing) | 380 bool &merging, bool &mixing) |
380 const | 381 const |
381 { | 382 { |
382 if (!m_model || !m_model->isOK()) return 0; | 383 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); |
383 | 384 if (!model || !model->isOK()) return 0; |
384 int channels = m_model->getChannelCount(); | 385 |
386 int channels = model->getChannelCount(); | |
385 if (channels == 0) return 0; | 387 if (channels == 0) return 0; |
386 | 388 |
387 int rawChannels = channels; | 389 int rawChannels = channels; |
388 | 390 |
389 if (m_channel == -1) { | 391 if (m_channel == -1) { |
422 bool | 424 bool |
423 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v, | 425 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v, |
424 int x, int modelZoomLevel, | 426 int x, int modelZoomLevel, |
425 sv_frame_t &f0, sv_frame_t &f1) const | 427 sv_frame_t &f0, sv_frame_t &f1) const |
426 { | 428 { |
429 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); | |
430 if (!model) return false; | |
431 | |
427 sv_frame_t viewFrame = v->getFrameForX(x); | 432 sv_frame_t viewFrame = v->getFrameForX(x); |
428 if (viewFrame < 0) { | 433 if (viewFrame < 0) { |
429 f0 = 0; | 434 f0 = 0; |
430 f1 = 0; | 435 f1 = 0; |
431 return false; | 436 return false; |
442 f1 = viewFrame; | 447 f1 = viewFrame; |
443 f1 = f1 / modelZoomLevel; | 448 f1 = f1 / modelZoomLevel; |
444 f1 = f1 * modelZoomLevel; | 449 f1 = f1 * modelZoomLevel; |
445 } | 450 } |
446 | 451 |
447 return (f0 < m_model->getEndFrame()); | 452 return (f0 < model->getEndFrame()); |
448 } | 453 } |
449 | 454 |
450 float | 455 float |
451 WaveformLayer::getNormalizeGain(LayerGeometryProvider *v, int channel) const | 456 WaveformLayer::getNormalizeGain(LayerGeometryProvider *v, int channel) const |
452 { | 457 { |
458 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); | |
459 if (!model) return 0.f; | |
460 | |
453 sv_frame_t startFrame = v->getStartFrame(); | 461 sv_frame_t startFrame = v->getStartFrame(); |
454 sv_frame_t endFrame = v->getEndFrame(); | 462 sv_frame_t endFrame = v->getEndFrame(); |
455 | 463 |
456 sv_frame_t modelStart = m_model->getStartFrame(); | 464 sv_frame_t modelStart = model->getStartFrame(); |
457 sv_frame_t modelEnd = m_model->getEndFrame(); | 465 sv_frame_t modelEnd = model->getEndFrame(); |
458 | 466 |
459 sv_frame_t rangeStart, rangeEnd; | 467 sv_frame_t rangeStart, rangeEnd; |
460 | 468 |
461 if (startFrame < modelStart) rangeStart = modelStart; | 469 if (startFrame < modelStart) rangeStart = modelStart; |
462 else rangeStart = startFrame; | 470 else rangeStart = startFrame; |
466 else rangeEnd = endFrame; | 474 else rangeEnd = endFrame; |
467 | 475 |
468 if (rangeEnd < rangeStart) rangeEnd = rangeStart; | 476 if (rangeEnd < rangeStart) rangeEnd = rangeStart; |
469 | 477 |
470 RangeSummarisableTimeValueModel::Range range = | 478 RangeSummarisableTimeValueModel::Range range = |
471 m_model->getSummary(channel, rangeStart, rangeEnd - rangeStart); | 479 model->getSummary(channel, rangeStart, rangeEnd - rangeStart); |
472 | 480 |
473 int minChannel = 0, maxChannel = 0; | 481 int minChannel = 0, maxChannel = 0; |
474 bool mergingChannels = false, mixingChannels = false; | 482 bool mergingChannels = false, mixingChannels = false; |
475 | 483 |
476 (void)getChannelArrangement(minChannel, maxChannel, | 484 (void)getChannelArrangement(minChannel, maxChannel, |
477 mergingChannels, mixingChannels); | 485 mergingChannels, mixingChannels); |
478 | 486 |
479 if (mergingChannels || mixingChannels) { | 487 if (mergingChannels || mixingChannels) { |
480 RangeSummarisableTimeValueModel::Range otherRange = | 488 RangeSummarisableTimeValueModel::Range otherRange = |
481 m_model->getSummary(1, rangeStart, rangeEnd - rangeStart); | 489 model->getSummary(1, rangeStart, rangeEnd - rangeStart); |
482 range.setMax(std::max(range.max(), otherRange.max())); | 490 range.setMax(std::max(range.max(), otherRange.max())); |
483 range.setMin(std::min(range.min(), otherRange.min())); | 491 range.setMin(std::min(range.min(), otherRange.min())); |
484 range.setAbsmean(std::min(range.absmean(), otherRange.absmean())); | 492 range.setAbsmean(std::min(range.absmean(), otherRange.absmean())); |
485 } | 493 } |
486 | 494 |
488 } | 496 } |
489 | 497 |
490 void | 498 void |
491 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const | 499 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const |
492 { | 500 { |
493 if (!m_model || !m_model->isOK()) { | 501 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); |
502 if (!model || !model->isOK()) { | |
494 return; | 503 return; |
495 } | 504 } |
496 | 505 |
497 ZoomLevel zoomLevel = v->getZoomLevel(); | 506 ZoomLevel zoomLevel = v->getZoomLevel(); |
498 | 507 |
592 | 601 |
593 int desiredBlockSize = 1; | 602 int desiredBlockSize = 1; |
594 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) { | 603 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) { |
595 desiredBlockSize = zoomLevel.level; | 604 desiredBlockSize = zoomLevel.level; |
596 } | 605 } |
597 int blockSize = m_model->getSummaryBlockSize(desiredBlockSize); | 606 int blockSize = model->getSummaryBlockSize(desiredBlockSize); |
598 | 607 |
599 sv_frame_t frame0; | 608 sv_frame_t frame0; |
600 sv_frame_t frame1; | 609 sv_frame_t frame1; |
601 sv_frame_t spare; | 610 sv_frame_t spare; |
602 | 611 |
641 if (m_middleLineHeight != 0.5) { | 650 if (m_middleLineHeight != 0.5) { |
642 paint->restore(); | 651 paint->restore(); |
643 } | 652 } |
644 | 653 |
645 if (m_aggressive) { | 654 if (m_aggressive) { |
646 if (m_model->isReady() && rect == v->getPaintRect()) { | 655 if (model->isReady() && rect == v->getPaintRect()) { |
647 m_cacheValid = true; | 656 m_cacheValid = true; |
648 m_cacheZoomLevel = zoomLevel; | 657 m_cacheZoomLevel = zoomLevel; |
649 } | 658 } |
650 paint->end(); | 659 paint->end(); |
651 delete paint; | 660 delete paint; |
658 bool mixingOrMerging, | 667 bool mixingOrMerging, |
659 sv_frame_t frame0, sv_frame_t frame1, | 668 sv_frame_t frame0, sv_frame_t frame1, |
660 int blockSize, RangeVec &ranges) | 669 int blockSize, RangeVec &ranges) |
661 const | 670 const |
662 { | 671 { |
672 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); | |
673 if (!model) return; | |
674 | |
663 for (int ch = minChannel; ch <= maxChannel; ++ch) { | 675 for (int ch = minChannel; ch <= maxChannel; ++ch) { |
664 ranges.push_back({}); | 676 ranges.push_back({}); |
665 m_model->getSummaries(ch, frame0, frame1 - frame0, | 677 model->getSummaries(ch, frame0, frame1 - frame0, |
666 ranges[ch - minChannel], blockSize); | 678 ranges[ch - minChannel], blockSize); |
667 #ifdef DEBUG_WAVEFORM_PAINT | 679 #ifdef DEBUG_WAVEFORM_PAINT |
668 SVCERR << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl; | 680 SVCERR << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl; |
669 #endif | 681 #endif |
670 } | 682 } |
671 | 683 |
672 if (mixingOrMerging) { | 684 if (mixingOrMerging) { |
673 if (minChannel != 0 || maxChannel != 0) { | 685 if (minChannel != 0 || maxChannel != 0) { |
674 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels"); | 686 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels"); |
675 } else if (m_model->getChannelCount() > 1) { | 687 } else if (model->getChannelCount() > 1) { |
676 ranges.push_back({}); | 688 ranges.push_back({}); |
677 m_model->getSummaries | 689 model->getSummaries |
678 (1, frame0, frame1 - frame0, ranges[1], blockSize); | 690 (1, frame0, frame1 - frame0, ranges[1], blockSize); |
679 } | 691 } |
680 } | 692 } |
681 } | 693 } |
682 | 694 |
685 bool mixingOrMerging, | 697 bool mixingOrMerging, |
686 sv_frame_t frame0, sv_frame_t frame1, | 698 sv_frame_t frame0, sv_frame_t frame1, |
687 int oversampleBy, RangeVec &ranges) | 699 int oversampleBy, RangeVec &ranges) |
688 const | 700 const |
689 { | 701 { |
702 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); | |
703 if (!model) return; | |
704 | |
690 if (mixingOrMerging) { | 705 if (mixingOrMerging) { |
691 if (minChannel != 0 || maxChannel != 0) { | 706 if (minChannel != 0 || maxChannel != 0) { |
692 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels"); | 707 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels"); |
693 } | 708 } |
694 if (m_model->getChannelCount() > 1) { | 709 if (model->getChannelCount() > 1) { |
695 // call back on self for the individual channels with | 710 // call back on self for the individual channels with |
696 // mixingOrMerging false | 711 // mixingOrMerging false |
697 getOversampledRanges | 712 getOversampledRanges |
698 (0, 1, false, frame0, frame1, oversampleBy, ranges); | 713 (0, 1, false, frame0, frame1, oversampleBy, ranges); |
699 return; | 714 return; |
702 | 717 |
703 // These frame values, tail length, etc variables are at the model | 718 // These frame values, tail length, etc variables are at the model |
704 // sample rate, not the oversampled rate | 719 // sample rate, not the oversampled rate |
705 | 720 |
706 sv_frame_t tail = 16; | 721 sv_frame_t tail = 16; |
707 sv_frame_t startFrame = m_model->getStartFrame(); | 722 sv_frame_t startFrame = model->getStartFrame(); |
708 sv_frame_t endFrame = m_model->getEndFrame(); | 723 sv_frame_t endFrame = model->getEndFrame(); |
709 | 724 |
710 sv_frame_t rf0 = frame0 - tail; | 725 sv_frame_t rf0 = frame0 - tail; |
711 if (rf0 < startFrame) { | 726 if (rf0 < startFrame) { |
712 rf0 = 0; | 727 rf0 = 0; |
713 } | 728 } |
722 return; | 737 return; |
723 } | 738 } |
724 | 739 |
725 for (int ch = minChannel; ch <= maxChannel; ++ch) { | 740 for (int ch = minChannel; ch <= maxChannel; ++ch) { |
726 floatvec_t oversampled = WaveformOversampler::getOversampledData | 741 floatvec_t oversampled = WaveformOversampler::getOversampledData |
727 (m_model, ch, frame0, frame1 - frame0, oversampleBy); | 742 (*model, ch, frame0, frame1 - frame0, oversampleBy); |
728 RangeSummarisableTimeValueModel::RangeBlock rr; | 743 RangeSummarisableTimeValueModel::RangeBlock rr; |
729 for (float v: oversampled) { | 744 for (float v: oversampled) { |
730 RangeSummarisableTimeValueModel::Range r; | 745 RangeSummarisableTimeValueModel::Range r; |
731 r.sample(v); | 746 r.sample(v); |
732 rr.push_back(r); | 747 rr.push_back(r); |
754 int blockSize, | 769 int blockSize, |
755 sv_frame_t frame0, | 770 sv_frame_t frame0, |
756 sv_frame_t frame1) | 771 sv_frame_t frame1) |
757 const | 772 const |
758 { | 773 { |
774 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); | |
775 if (!model) return; | |
776 | |
759 int x0 = rect.left(); | 777 int x0 = rect.left(); |
760 int y0 = rect.top(); | 778 int y0 = rect.top(); |
761 | 779 |
762 int x1 = rect.right(); | 780 int x1 = rect.right(); |
763 int y1 = rect.bottom(); | 781 int y1 = rect.bottom(); |
775 QColor midColour = baseColour; | 793 QColor midColour = baseColour; |
776 | 794 |
777 if (midColour == Qt::black) { | 795 if (midColour == Qt::black) { |
778 midColour = Qt::gray; | 796 midColour = Qt::gray; |
779 } else if (v->hasLightBackground()) { | 797 } else if (v->hasLightBackground()) { |
780 midColour = midColour.light(150); | 798 midColour = midColour.lighter(150); |
781 } else { | 799 } else { |
782 midColour = midColour.light(50); | 800 midColour = midColour.lighter(50); |
783 } | 801 } |
784 | 802 |
785 double gain = m_effectiveGains[ch]; | 803 double gain = m_effectiveGains[ch]; |
786 | 804 |
787 int m = (h / channels) / 2; | 805 int m = (h / channels) / 2; |
1049 double penWidth = 1.0; | 1067 double penWidth = 1.0; |
1050 if (v->getZoomLevel().zone == ZoomLevel::FramesPerPixel) { | 1068 if (v->getZoomLevel().zone == ZoomLevel::FramesPerPixel) { |
1051 penWidth = 0.0; | 1069 penWidth = 0.0; |
1052 } | 1070 } |
1053 | 1071 |
1054 if (m_model->isReady()) { | 1072 if (model->isReady()) { |
1055 paint->setPen(QPen(baseColour, penWidth)); | 1073 paint->setPen(QPen(baseColour, penWidth)); |
1056 } else { | 1074 } else { |
1057 paint->setPen(QPen(midColour, penWidth)); | 1075 paint->setPen(QPen(midColour, penWidth)); |
1058 } | 1076 } |
1059 paint->drawPath(waveformPath); | 1077 paint->drawPath(waveformPath); |
1152 QString | 1170 QString |
1153 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const | 1171 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const |
1154 { | 1172 { |
1155 int x = pos.x(); | 1173 int x = pos.x(); |
1156 | 1174 |
1157 if (!m_model || !m_model->isOK()) return ""; | 1175 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); |
1176 if (!model || !model->isOK()) return ""; | |
1158 | 1177 |
1159 ZoomLevel zoomLevel = v->getZoomLevel(); | 1178 ZoomLevel zoomLevel = v->getZoomLevel(); |
1160 | 1179 |
1161 int desiredBlockSize = 1; | 1180 int desiredBlockSize = 1; |
1162 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) { | 1181 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) { |
1163 desiredBlockSize = zoomLevel.level; | 1182 desiredBlockSize = zoomLevel.level; |
1164 } | 1183 } |
1165 | 1184 |
1166 int blockSize = m_model->getSummaryBlockSize(desiredBlockSize); | 1185 int blockSize = model->getSummaryBlockSize(desiredBlockSize); |
1167 | 1186 |
1168 sv_frame_t f0, f1; | 1187 sv_frame_t f0, f1; |
1169 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return ""; | 1188 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return ""; |
1170 | 1189 |
1171 QString text; | 1190 QString text; |
1172 | 1191 |
1173 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate()); | 1192 RealTime rt0 = RealTime::frame2RealTime(f0, model->getSampleRate()); |
1174 RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate()); | 1193 RealTime rt1 = RealTime::frame2RealTime(f1, model->getSampleRate()); |
1175 | 1194 |
1176 if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) { | 1195 if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) { |
1177 text += tr("Time:\t%1 - %2") | 1196 text += tr("Time:\t%1 - %2") |
1178 .arg(rt0.toText(true).c_str()) | 1197 .arg(rt0.toText(true).c_str()) |
1179 .arg(rt1.toText(true).c_str()); | 1198 .arg(rt1.toText(true).c_str()); |
1190 if (channels == 0) return ""; | 1209 if (channels == 0) return ""; |
1191 | 1210 |
1192 for (int ch = minChannel; ch <= maxChannel; ++ch) { | 1211 for (int ch = minChannel; ch <= maxChannel; ++ch) { |
1193 | 1212 |
1194 RangeSummarisableTimeValueModel::RangeBlock ranges; | 1213 RangeSummarisableTimeValueModel::RangeBlock ranges; |
1195 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize); | 1214 model->getSummaries(ch, f0, f1 - f0, ranges, blockSize); |
1196 | 1215 |
1197 if (ranges.empty()) continue; | 1216 if (ranges.empty()) continue; |
1198 | 1217 |
1199 RangeSummarisableTimeValueModel::Range range = ranges[0]; | 1218 RangeSummarisableTimeValueModel::Range range = ranges[0]; |
1200 | 1219 |
1390 } | 1409 } |
1391 | 1410 |
1392 int | 1411 int |
1393 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const | 1412 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const |
1394 { | 1413 { |
1414 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested | |
1415 // replacement (horizontalAdvance) was only added in Qt 5.11 | |
1416 // which is too new for us | |
1417 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
1418 | |
1395 if (m_scale == LinearScale) { | 1419 if (m_scale == LinearScale) { |
1396 return paint.fontMetrics().width("0.0") + 13; | 1420 return paint.fontMetrics().width("0.0") + 13; |
1397 } else { | 1421 } else { |
1398 return std::max(paint.fontMetrics().width(tr("0dB")), | 1422 return std::max(paint.fontMetrics().width(tr("0dB")), |
1399 paint.fontMetrics().width(Strings::minus_infinity)) + 13; | 1423 paint.fontMetrics().width(Strings::minus_infinity)) + 13; |
1401 } | 1425 } |
1402 | 1426 |
1403 void | 1427 void |
1404 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const | 1428 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const |
1405 { | 1429 { |
1406 if (!m_model || !m_model->isOK()) { | 1430 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model); |
1431 if (!model || !model->isOK()) { | |
1407 return; | 1432 return; |
1408 } | 1433 } |
1409 | 1434 |
1410 int channels = 0, minChannel = 0, maxChannel = 0; | 1435 int channels = 0, minChannel = 0, maxChannel = 0; |
1411 bool mergingChannels = false, mixingChannels = false; | 1436 bool mergingChannels = false, mixingChannels = false; |