Audacity  2.2.2
AudioIO.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  AudioIO.cpp
6 
7  Copyright 2000-2004:
8  Dominic Mazzoni
9  Joshua Haberman
10  Markus Meyer
11  Matt Brubeck
12 
13  This program is free software; you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by the Free
15  Software Foundation; either version 2 of the License, or (at your option)
16  any later version.
17 
18 ********************************************************************//****************************************************************//****************************************************************//****************************************************************//*******************************************************************/
406 
407 #include "Audacity.h"
408 #include "Experimental.h"
409 #include "AudioIO.h"
410 #include "float_cast.h"
411 
412 #include <cfloat>
413 #include <math.h>
414 #include <stdlib.h>
415 #include <algorithm>
416 
417 #ifdef __WXMSW__
418 #include <malloc.h>
419 #endif
420 
421 #ifdef HAVE_ALLOCA_H
422 #include <alloca.h>
423 #endif
424 
425 #if USE_PORTMIXER
426 #include "portmixer.h"
427 #endif
428 
429 #include <wx/log.h>
430 #include <wx/textctrl.h>
431 #include <wx/timer.h>
432 #include <wx/intl.h>
433 #include <wx/debug.h>
434 #include <wx/sstream.h>
435 #include <wx/txtstrm.h>
436 
437 #include "AudacityApp.h"
438 #include "AudacityException.h"
439 #include "Mix.h"
440 #include "MixerBoard.h"
441 #include "Resample.h"
442 #include "RingBuffer.h"
443 #include "prefs/GUISettings.h"
444 #include "Prefs.h"
445 #include "Project.h"
446 #include "TimeTrack.h"
447 #include "WaveTrack.h"
448 #include "AutoRecovery.h"
449 
450 #include "toolbars/ControlToolBar.h"
451 #include "widgets/Meter.h"
452 #include "widgets/ErrorDialog.h"
453 #include "widgets/Warning.h"
454 
455 #ifdef EXPERIMENTAL_MIDI_OUT
456  #define MIDI_SLEEP 10 /* milliseconds */
457  // how long do we think the thread that fills MIDI buffers,
458  // if it is separate from the portaudio thread,
459  // might be delayed due to other threads?
460  #ifdef USE_MIDI_THREAD
461  #define THREAD_LATENCY 10 /* milliseconds */
462  #else
463  #define THREAD_LATENCY 0 /* milliseconds */
464  #endif
465  #define ROUND(x) (int) ((x)+0.5)
466  //#include <string.h>
467  #include "../lib-src/portmidi/pm_common/portmidi.h"
468  #include "../lib-src/portaudio-v19/src/common/pa_util.h"
469  #include "NoteTrack.h"
470 #endif
471 
472 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
473  #define LOWER_BOUND 0.0
474  #define UPPER_BOUND 1.0
475 #endif
476 
477 using std::max;
478 using std::min;
479 
480 std::unique_ptr<AudioIO> ugAudioIO;
482 
483 DEFINE_EVENT_TYPE(EVT_AUDIOIO_PLAYBACK);
484 DEFINE_EVENT_TYPE(EVT_AUDIOIO_CAPTURE);
485 DEFINE_EVENT_TYPE(EVT_AUDIOIO_MONITOR);
486 
487 // static
492 wxArrayLong AudioIO::mCachedCaptureRates;
493 wxArrayLong AudioIO::mCachedSampleRates;
494 double AudioIO::mCachedBestRateIn = 0.0;
496 
497 enum {
498  // This is the least positive latency we can
499  // specify to Pm_OpenOutput, 1 ms, which prevents immediate
500  // scheduling of events:
502 };
503 
504 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
505 
506 #include "tracks/ui/Scrubbing.h"
507 
508 #ifdef __WXGTK__
509  // Might #define this for a useful thing on Linux
510  #undef REALTIME_ALSA_THREAD
511 #else
512  // never on the other operating systems
513  #undef REALTIME_ALSA_THREAD
514 #endif
515 
516 #ifdef REALTIME_ALSA_THREAD
517 #include "pa_linux_alsa.h"
518 #endif
519 
520 
521 /*
522 This work queue class, with the aid of the playback ring
523 buffers, coordinates three threads during scrub play:
524 
525 The UI thread which specifies scrubbing intervals to play,
526 
527 The Audio thread which consumes those specifications a first time
528 and fills the ring buffers with samples for play,
529 
530 The PortAudio thread which consumes from the ring buffers, then
531 also consumes a second time from this queue,
532 to figure out how to update mTime
533 
534 -- which the UI thread, in turn, uses to redraw the play head indicator
535 in the right place.
536 
537 Audio produces samples for PortAudio, which consumes them, both in
538 approximate real time. The UI thread might go idle and so the others
539 might catch up, emptying the queue and causing scrub to go silent.
540 The UI thread will not normally outrun the others -- because InitEntry()
541 limits the real time duration over which each enqueued interval will play.
542 So a small, fixed queue size should be adequate.
543 */
545 {
546  ScrubQueue(double t0, double t1, wxLongLong startClockMillis,
547  double rate, long maxDebt,
548  const ScrubbingOptions &options)
549  : mTrailingIdx(0)
550  , mMiddleIdx(1)
551  , mLeadingIdx(1)
552  , mRate(rate)
553  , mLastScrubTimeMillis(startClockMillis)
554  , mUpdating()
555  , mMaxDebt { maxDebt }
556  {
557  const auto s0 = std::max(options.minSample, std::min(options.maxSample,
558  sampleCount(lrint(t0 * mRate))
559  ));
560  const auto s1 = sampleCount(lrint(t1 * mRate));
561  Duration dd { *this };
562  auto actualDuration = std::max(sampleCount{1}, dd.duration);
563  auto success = mEntries[mMiddleIdx].Init(nullptr,
564  s0, s1, actualDuration, options);
565  if (success)
566  ++mLeadingIdx;
567  else {
568  // If not, we can wait to enqueue again later
569  dd.Cancel();
570  }
571 
572  // So the play indicator starts out unconfused:
573  {
574  Entry &entry = mEntries[mTrailingIdx];
575  entry.mS0 = entry.mS1 = s0;
576  entry.mPlayed = entry.mDuration = 1;
577  }
578  }
580 
581  double LastTimeInQueue() const
582  {
583  // Needed by the main thread sometimes
584  wxMutexLocker locker(mUpdating);
585  const Entry &previous = mEntries[(mLeadingIdx + Size - 1) % Size];
586  return previous.mS1.as_double() / mRate;
587  }
588 
589  // This is for avoiding deadlocks while starting a scrub:
590  // Audio stream needs to be unblocked
591  void Nudge()
592  {
593  wxMutexLocker locker(mUpdating);
594  mNudged = true;
595  mAvailable.Signal();
596  }
597 
598  bool Producer(double end, const ScrubbingOptions &options)
599  {
600  // Main thread indicates a scrubbing interval
601 
602  // MAY ADVANCE mLeadingIdx, BUT IT NEVER CATCHES UP TO mTrailingIdx.
603 
604  wxMutexLocker locker(mUpdating);
605  bool result = true;
606  unsigned next = (mLeadingIdx + 1) % Size;
607  if (next != mTrailingIdx)
608  {
609  auto current = &mEntries[mLeadingIdx];
610  auto previous = &mEntries[(mLeadingIdx + Size - 1) % Size];
611 
612  // Use the previous end as NEW start.
613  const auto s0 = previous->mS1;
614  Duration dd { *this };
615  const auto &origDuration = dd.duration;
616  if (origDuration <= 0)
617  return false;
618 
619  auto actualDuration = origDuration;
620  const sampleCount s1 ( options.enqueueBySpeed
621  ? s0.as_double() +
622  lrint(origDuration.as_double() * end) // end is a speed
623  : lrint(end * mRate) // end is a time
624  );
625  auto success =
626  current->Init(previous, s0, s1, actualDuration, options);
627  if (success)
628  mLeadingIdx = next;
629  else {
630  dd.Cancel();
631  return false;
632  }
633 
634  // Fill up the queue with some silence if there was trimming
635  wxASSERT(actualDuration <= origDuration);
636  if (actualDuration < origDuration) {
637  next = (mLeadingIdx + 1) % Size;
638  if (next != mTrailingIdx) {
639  previous = &mEntries[(mLeadingIdx + Size - 1) % Size];
640  current = &mEntries[mLeadingIdx];
641  current->InitSilent(*previous, origDuration - actualDuration);
642  mLeadingIdx = next;
643  }
644  else
645  // Oops, can't enqueue the silence -- so do what?
646  ;
647  }
648 
649  mAvailable.Signal();
650  return result;
651  }
652  else
653  {
654  // ??
655  // Queue wasn't long enough. Write side (UI thread)
656  // has overtaken the trailing read side (PortAudio thread), despite
657  // my comments above! We lose some work requests then.
658  // wxASSERT(false);
659  return false;
660  }
661  }
662 
663  void Transformer(sampleCount &startSample, sampleCount &endSample,
664  sampleCount &duration,
665  Maybe<wxMutexLocker> &cleanup)
666  {
667  // Audio thread is ready for the next interval.
668 
669  // MAY ADVANCE mMiddleIdx, WHICH MAY EQUAL mLeadingIdx, BUT DOES NOT PASS IT.
670 
671  bool checkDebt = false;
672  if (!cleanup) {
673  cleanup.create(mUpdating);
674 
675  // Check for cancellation of work only when re-enetering the cricial section
676  checkDebt = true;
677  }
678  while(!mNudged && mMiddleIdx == mLeadingIdx)
679  mAvailable.Wait();
680 
681  mNudged = false;
682 
683  auto now = ::wxGetLocalTimeMillis();
684 
685  if (checkDebt &&
686  mLastTransformerTimeMillis >= 0 && // Not the first time for this scrub
687  mMiddleIdx != mLeadingIdx) {
688  // There is work in the queue, but if Producer is outrunning us, discard some,
689  // which may make a skip yet keep playback better synchronized with user gestures.
690  const auto interval = (now - mLastTransformerTimeMillis).ToDouble() / 1000.0;
691  //const Entry &previous = mEntries[(mMiddleIdx + Size - 1) % Size];
692  const auto deficit =
693  static_cast<long>(interval * mRate) - // Samples needed in the last time interval
694  mCredit; // Samples done in the last time interval
695  mCredit = 0;
696  mDebt += deficit;
697  auto toDiscard = mDebt - mMaxDebt;
698  while (toDiscard > 0 && mMiddleIdx != mLeadingIdx) {
699  // Cancel some debt (discard some NEW work)
700  auto &entry = mEntries[mMiddleIdx];
701  auto &dur = entry.mDuration;
702  if (toDiscard >= dur) {
703  // Discard entire queue entry
704  mDebt -= dur;
705  toDiscard -= dur;
706  dur = 0; // So Consumer() will handle abandoned entry correctly
707  mMiddleIdx = (mMiddleIdx + 1) % Size;
708  }
709  else {
710  // Adjust the start time
711  auto &start = entry.mS0;
712  const auto end = entry.mS1;
713  const auto ratio = toDiscard.as_double() / dur.as_double();
714  const sampleCount adjustment(
715  std::abs((end - start).as_long_long()) * ratio
716  );
717  if (start <= end)
718  start += adjustment;
719  else
720  start -= adjustment;
721 
722  mDebt -= toDiscard;
723  dur -= toDiscard;
724  toDiscard = 0;
725  }
726  }
727  }
728 
729  if (mMiddleIdx != mLeadingIdx) {
730  // There is still work in the queue, after cancelling debt
731  Entry &entry = mEntries[mMiddleIdx];
732  startSample = entry.mS0;
733  endSample = entry.mS1;
734  duration = entry.mDuration;
735  mMiddleIdx = (mMiddleIdx + 1) % Size;
736  mCredit += duration;
737  }
738  else {
739  // We got the shut-down signal, or we got nudged, or we discarded all the work.
740  startSample = endSample = duration = -1L;
741  }
742 
743  if (checkDebt)
745  }
746 
747  double Consumer(unsigned long frames)
748  {
749  // Portaudio thread consumes samples and must update
750  // the time for the indicator. This finds the time value.
751 
752  // MAY ADVANCE mTrailingIdx, BUT IT NEVER CATCHES UP TO mMiddleIdx.
753 
754  wxMutexLocker locker(mUpdating);
755 
756  // Mark entries as partly or fully "consumed" for
757  // purposes of mTime update. It should not happen that
758  // frames exceed the total of samples to be consumed,
759  // but in that case we just use the t1 of the latest entry.
760  while (1)
761  {
762  Entry *pEntry = &mEntries[mTrailingIdx];
763  auto remaining = pEntry->mDuration - pEntry->mPlayed;
764  if (frames >= remaining)
765  {
766  // remaining is not more than frames
767  frames -= remaining.as_size_t();
768  pEntry->mPlayed = pEntry->mDuration;
769  }
770  else
771  {
772  pEntry->mPlayed += frames;
773  break;
774  }
775  const unsigned next = (mTrailingIdx + 1) % Size;
776  if (next == mMiddleIdx)
777  break;
778  mTrailingIdx = next;
779  }
781  }
782 
783 private:
784  struct Entry
785  {
787  : mS0(0)
788  , mS1(0)
789  , mGoal(0)
790  , mDuration(0)
791  , mPlayed(0)
792  {}
793 
794  bool Init(Entry *previous, sampleCount s0, sampleCount s1,
795  sampleCount &duration /* in/out */,
796  const ScrubbingOptions &options)
797  {
798  const bool &adjustStart = options.adjustStart;
799 
800  wxASSERT(duration > 0);
801  double speed =
802  (std::abs((s1 - s0).as_long_long())) / duration.as_double();
803  bool adjustedSpeed = false;
804 
805  auto minSpeed = std::min(options.minSpeed, options.maxSpeed);
806  wxASSERT(minSpeed == options.minSpeed);
807 
808  // May change the requested speed and duration
809  if (!adjustStart && speed > options.maxSpeed)
810  {
811  // Reduce speed to the maximum selected in the user interface.
812  speed = options.maxSpeed;
813  mGoal = s1;
814  adjustedSpeed = true;
815  }
816  else if (!adjustStart &&
817  previous &&
818  previous->mGoal >= 0 &&
819  previous->mGoal == s1)
820  {
821  // In case the mouse has not moved, and playback
822  // is catching up to the mouse at maximum speed,
823  // continue at no less than maximum. (Without this
824  // the final catch-up can make a slow scrub interval
825  // that drops the pitch and sounds wrong.)
826  minSpeed = options.maxSpeed;
827  mGoal = s1;
828  adjustedSpeed = true;
829  }
830  else
831  mGoal = -1;
832 
833  if (speed < minSpeed) {
834  // Trim the duration.
835  duration = std::max(0L, lrint(speed * duration.as_double() / minSpeed));
836  speed = minSpeed;
837  adjustedSpeed = true;
838  }
839 
841  // Mixers were set up to go only so slowly, not slower.
842  // This will put a request for some silence in the work queue.
843  adjustedSpeed = true;
844  speed = 0.0;
845  }
846 
847  // May change s1 or s0 to match speed change or stay in bounds of the project
848 
849  if (adjustedSpeed && !adjustStart)
850  {
851  // adjust s1
852  const sampleCount diff = lrint(speed * duration.as_double());
853  if (s0 < s1)
854  s1 = s0 + diff;
855  else
856  s1 = s0 - diff;
857  }
858 
859  bool silent = false;
860 
861  // Adjust s1 (again), and duration, if s1 is out of bounds,
862  // or abandon if a stutter is too short.
863  // (Assume s0 is in bounds, because it equals the last scrub's s1 which was checked.)
864  if (s1 != s0)
865  {
866  auto newDuration = duration;
867  const auto newS1 = std::max(options.minSample, std::min(options.maxSample, s1));
868  if(s1 != newS1)
869  newDuration = std::max( sampleCount{ 0 },
870  sampleCount(
871  duration.as_double() * (newS1 - s0).as_double() /
872  (s1 - s0).as_double()
873  )
874  );
875  // When playback follows a fast mouse movement by "stuttering"
876  // at maximum playback, don't make stutters too short to be useful.
877  if (options.adjustStart && newDuration < options.minStutter)
878  return false;
879  else if (newDuration == 0) {
880  // Enqueue a silent scrub with s0 == s1
881  silent = true;
882  s1 = s0;
883  }
884  else if (s1 != newS1) {
885  // Shorten
886  duration = newDuration;
887  s1 = newS1;
888  }
889  }
890 
891  if (adjustStart && !silent)
892  {
893  // Limit diff because this is seeking.
894  const sampleCount diff =
895  lrint(std::min(options.maxSpeed, speed) * duration.as_double());
896  if (s0 < s1)
897  s0 = s1 - diff;
898  else
899  s0 = s1 + diff;
900  }
901 
902  mS0 = s0;
903  mS1 = s1;
904  mPlayed = 0;
905  mDuration = duration;
906  return true;
907  }
908 
909  void InitSilent(const Entry &previous, sampleCount duration)
910  {
911  mGoal = previous.mGoal;
912  mS0 = mS1 = previous.mS1;
913  mPlayed = 0;
914  mDuration = duration;
915  }
916 
917  double GetTime(double rate) const
918  {
919  return
920  (mS0.as_double() +
921  (mS1 - mS0).as_double() * mPlayed.as_double() / mDuration.as_double())
922  / rate;
923  }
924 
925  // These sample counts are initialized in the UI, producer, thread:
926  sampleCount mS0;
927  sampleCount mS1;
928  sampleCount mGoal;
929  // This field is initialized in the UI thread too, and
930  // this work queue item corresponds to exactly this many samples of
931  // playback output:
932  sampleCount mDuration;
933 
934  // The middleman Audio thread does not change these entries, but only
935  // changes indices in the queue structure.
936 
937  // This increases from 0 to mDuration as the PortAudio, consumer,
938  // thread catches up. When they are equal, this entry can be discarded:
939  sampleCount mPlayed;
940  };
941 
942  struct Duration {
943  Duration (ScrubQueue &queue_) : queue(queue_) {}
945  {
946  if(!cancelled)
948  }
949 
950  void Cancel() { cancelled = true; }
951 
953  const wxLongLong clockTime { ::wxGetLocalTimeMillis() };
954  const sampleCount duration { static_cast<long long>
955  (queue.mRate * (clockTime - queue.mLastScrubTimeMillis).ToDouble() / 1000.0)
956  };
957  bool cancelled { false };
958  };
959 
960  enum { Size = 10 };
962  unsigned mTrailingIdx;
963  unsigned mMiddleIdx;
964  unsigned mLeadingIdx;
965  const double mRate;
967 
968  wxLongLong mLastTransformerTimeMillis { -1LL };
969  sampleCount mCredit { 0 };
970  sampleCount mDebt { 0 };
971  const long mMaxDebt;
972 
973  mutable wxMutex mUpdating;
974  mutable wxCondition mAvailable { mUpdating };
975  bool mNudged { false };
976 };
977 #endif
978 
979 // return the system time as a double
980 static double streamStartTime = 0; // bias system time to small number
981 
982 static double SystemTime(bool usingAlsa)
983 {
984 #ifdef __WXGTK__
985  if (usingAlsa) {
986  struct timespec now;
987  // CLOCK_MONOTONIC_RAW is unaffected by NTP or adj-time
988  clock_gettime(CLOCK_MONOTONIC_RAW, &now);
989  //return now.tv_sec + now.tv_nsec * 0.000000001;
990  return (now.tv_sec + now.tv_nsec * 0.000000001) - streamStartTime;
991  }
992 #else
993  usingAlsa;//compiler food.
994 #endif
995 
996  return PaUtil_GetTime() - streamStartTime;
997 }
998 
999 const int AudioIO::StandardRates[] = {
1000  8000,
1001  11025,
1002  16000,
1003  22050,
1004  32000,
1005  44100,
1006  48000,
1007  88200,
1008  96000,
1009  176400,
1010  192000,
1011  352800,
1012  384000
1013 };
1015  sizeof(AudioIO::StandardRates[0]);
1016 const int AudioIO::RatesToTry[] = {
1017  8000,
1018  9600,
1019  11025,
1020  12000,
1021  15000,
1022  16000,
1023  22050,
1024  24000,
1025  32000,
1026  44100,
1027  48000,
1028  88200,
1029  96000,
1030  176400,
1031  192000,
1032  352800,
1033  384000
1034 };
1035 const int AudioIO::NumRatesToTry = sizeof(AudioIO::RatesToTry) /
1036  sizeof(AudioIO::RatesToTry[0]);
1037 
1038 int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
1039  unsigned long framesPerBuffer,
1040  const PaStreamCallbackTimeInfo *timeInfo,
1041  PaStreamCallbackFlags statusFlags, void *userData );
1042 
1044 //
1045 // class AudioThread - declaration and glue code
1046 //
1048 
1049 #ifdef __WXMAC__
1050 
1051 // On Mac OS X, it's better not to use the wxThread class.
1052 // We use our own implementation based on pthreads instead.
1053 
1054 #include <pthread.h>
1055 #include <time.h>
1056 
1057 class AudioThread {
1058  public:
1059  typedef int ExitCode;
1060  AudioThread() { mDestroy = false; mThread = NULL; }
1061  virtual ExitCode Entry();
1062  void Create() {}
1063  void Delete() {
1064  mDestroy = true;
1065  pthread_join(mThread, NULL);
1066  }
1067  bool TestDestroy() { return mDestroy; }
1068  void Sleep(int ms) {
1069  struct timespec spec;
1070  spec.tv_sec = 0;
1071  spec.tv_nsec = ms * 1000 * 1000;
1072  nanosleep(&spec, NULL);
1073  }
1074  static void *callback(void *p) {
1075  AudioThread *th = (AudioThread *)p;
1076  return (void *)th->Entry();
1077  }
1078  void Run() {
1079  pthread_create(&mThread, NULL, callback, this);
1080  }
1081  private:
1082  bool mDestroy;
1083  pthread_t mThread;
1084 
1085 };
1086 
1087 #else
1088 
1089 // The normal wxThread-derived AudioThread class for all other
1090 // platforms:
1091 class AudioThread /* not final */ : public wxThread {
1092  public:
1093  AudioThread():wxThread(wxTHREAD_JOINABLE) {}
1094  ExitCode Entry() override;
1095 };
1096 
1097 #endif
1098 
1099 #ifdef EXPERIMENTAL_MIDI_OUT
1100 class MidiThread final : public AudioThread {
1101  public:
1102  ExitCode Entry() override;
1103 };
1104 #endif
1105 
1106 
1108 //
1109 // UI Thread Context
1110 //
1112 
1114 {
1115  ugAudioIO.reset(safenew AudioIO());
1116  gAudioIO = ugAudioIO.get();
1117  gAudioIO->mThread->Run();
1118 #ifdef EXPERIMENTAL_MIDI_OUT
1119 #ifdef USE_MIDI_THREAD
1120  gAudioIO->mMidiThread->Run();
1121 #endif
1122 #endif
1123 
1124  // Make sure device prefs are initialized
1125  if (gPrefs->Read(wxT("AudioIO/RecordingDevice"), wxT("")) == wxT("")) {
1126  int i = AudioIO::getRecordDevIndex();
1127  const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
1128  if (info) {
1129  gPrefs->Write(wxT("/AudioIO/RecordingDevice"), DeviceName(info));
1130  gPrefs->Write(wxT("/AudioIO/Host"), HostName(info));
1131  }
1132  }
1133 
1134  if (gPrefs->Read(wxT("AudioIO/PlaybackDevice"), wxT("")) == wxT("")) {
1135  int i = AudioIO::getPlayDevIndex();
1136  const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
1137  if (info) {
1138  gPrefs->Write(wxT("/AudioIO/PlaybackDevice"), DeviceName(info));
1139  gPrefs->Write(wxT("/AudioIO/Host"), HostName(info));
1140  }
1141  }
1142 
1143  gPrefs->Flush();
1144 }
1145 
1147 {
1148  ugAudioIO.reset();
1149 }
1150 
1151 wxString DeviceName(const PaDeviceInfo* info)
1152 {
1153  wxString infoName = wxSafeConvertMB2WX(info->name);
1154 
1155  return infoName;
1156 }
1157 
1158 wxString HostName(const PaDeviceInfo* info)
1159 {
1160  wxString hostapiName = wxSafeConvertMB2WX(Pa_GetHostApiInfo(info->hostApi)->name);
1161 
1162  return hostapiName;
1163 }
1164 
1165 bool AudioIO::ValidateDeviceNames(const wxString &play, const wxString &rec)
1166 {
1167  const PaDeviceInfo *pInfo = Pa_GetDeviceInfo(AudioIO::getPlayDevIndex(play));
1168  const PaDeviceInfo *rInfo = Pa_GetDeviceInfo(AudioIO::getRecordDevIndex(rec));
1169 
1170  if (!pInfo || !rInfo || pInfo->hostApi != rInfo->hostApi) {
1171  return false;
1172  }
1173 
1174  return true;
1175 }
1176 
1178 {
1182  mPortStreamV19 = NULL;
1183 
1184 #ifdef EXPERIMENTAL_MIDI_OUT
1185  mMidiStream = NULL;
1186  mMidiThreadFillBuffersLoopRunning = false;
1187  mMidiThreadFillBuffersLoopActive = false;
1188  mMidiStreamActive = false;
1189  mSendMidiState = false;
1190  mIterator = NULL;
1191 
1192  mNumFrames = 0;
1193  mNumPauseFrames = 0;
1194 #endif
1195 
1196 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1197  mAILAActive = false;
1198 #endif
1199  mStreamToken = 0;
1200 
1201  mLastPaError = paNoError;
1202 
1203  mLastRecordingOffset = 0.0;
1204  mNumCaptureChannels = 0;
1205  mPaused = false;
1207 
1208  mListener = NULL;
1209  mUpdateMeters = false;
1210  mUpdatingMeters = false;
1211 
1212  mOwningProject = NULL;
1213  mInputMeter = NULL;
1214  mOutputMeter = NULL;
1215 
1216  PaError err = Pa_Initialize();
1217 
1218  if (err != paNoError) {
1219  wxString errStr = _("Could not find any audio devices.\n");
1220  errStr += _("You will not be able to play or record audio.\n\n");
1221  wxString paErrStr = LAT1CTOWX(Pa_GetErrorText(err));
1222  if (!paErrStr.IsEmpty())
1223  errStr += _("Error: ")+paErrStr;
1224  // XXX: we are in libaudacity, popping up dialogs not allowed! A
1225  // long-term solution will probably involve exceptions
1226  AudacityMessageBox(errStr, _("Error Initializing Audio"), wxICON_ERROR|wxOK);
1227 
1228  // Since PortAudio is not initialized, all calls to PortAudio
1229  // functions will fail. This will give reasonable behavior, since
1230  // the user will be able to do things not relating to audio i/o,
1231  // but any attempt to play or record will simply fail.
1232  }
1233 
1234 #ifdef EXPERIMENTAL_MIDI_OUT
1235  PmError pmErr = Pm_Initialize();
1236 
1237  if (pmErr != pmNoError) {
1238  wxString errStr =
1239  _("There was an error initializing the midi i/o layer.\n");
1240  errStr += _("You will not be able to play midi.\n\n");
1241  wxString pmErrStr = LAT1CTOWX(Pm_GetErrorText(pmErr));
1242  if (!pmErrStr.empty())
1243  errStr += _("Error: ") + pmErrStr;
1244  // XXX: we are in libaudacity, popping up dialogs not allowed! A
1245  // long-term solution will probably involve exceptions
1246  AudacityMessageBox(errStr, _("Error Initializing Midi"), wxICON_ERROR|wxOK);
1247 
1248  // Same logic for PortMidi as described above for PortAudio
1249  }
1250 
1251 #ifdef USE_MIDI_THREAD
1252  mMidiThread = std::make_unique<MidiThread>();
1253  mMidiThread->Create();
1254 #endif
1255 
1256 #endif
1257 
1258  // Start thread
1259  mThread = std::make_unique<AudioThread>();
1260  mThread->Create();
1261 
1262 #if defined(USE_PORTMIXER)
1263  mPortMixer = NULL;
1264  mPreviousHWPlaythrough = -1.0;
1266 #else
1267  mEmulateMixerOutputVol = true;
1268  mMixerOutputVol = 1.0;
1269  mInputMixerWorks = false;
1270 #endif
1271 
1273 
1274 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
1275  mScrubQueue = NULL;
1276  mScrubDuration = 0;
1277  mSilentScrub = false;
1278 #endif
1279 }
1280 
1282 {
1283 #if defined(USE_PORTMIXER)
1284  if (mPortMixer) {
1285  #if __WXMAC__
1286  if (Px_SupportsPlaythrough(mPortMixer) && mPreviousHWPlaythrough >= 0.0)
1287  Px_SetPlaythrough(mPortMixer, mPreviousHWPlaythrough);
1288  mPreviousHWPlaythrough = -1.0;
1289  #endif
1290  Px_CloseMixer(mPortMixer);
1291  mPortMixer = NULL;
1292  }
1293 #endif
1294 
1295  // FIXME: ? TRAP_ERR. Pa_Terminate probably OK if err without reporting.
1296  Pa_Terminate();
1297 
1298 #ifdef EXPERIMENTAL_MIDI_OUT
1299  Pm_Terminate();
1300 
1301  /* Delete is a "graceful" way to stop the thread.
1302  (Kill is the not-graceful way.) */
1303 
1304 #ifdef USE_MIDI_THREAD
1305  mMidiThread->Delete();
1306  mMidiThread.reset();
1307 #endif
1308 
1309 #endif
1310 
1311  /* Delete is a "graceful" way to stop the thread.
1312  (Kill is the not-graceful way.) */
1313 
1314  // This causes reentrancy issues during application shutdown
1315  // wxTheApp->Yield();
1316 
1317  mThread->Delete();
1318  mThread.reset();
1319 
1320  gAudioIO = nullptr;
1321 }
1322 
1323 void AudioIO::SetMixer(int inputSource)
1324 {
1325 #if defined(USE_PORTMIXER)
1326  int oldRecordSource = Px_GetCurrentInputSource(mPortMixer);
1327  if ( inputSource != oldRecordSource )
1328  Px_SetCurrentInputSource(mPortMixer, inputSource);
1329 #endif
1330 }
1331 void AudioIO::SetMixer(int inputSource, float recordVolume,
1332  float playbackVolume)
1333 {
1334  mMixerOutputVol = playbackVolume;
1335 
1336 #if defined(USE_PORTMIXER)
1337  PxMixer *mixer = mPortMixer;
1338 
1339  if( mixer )
1340  {
1341  float oldRecordVolume = Px_GetInputVolume(mixer);
1342  float oldPlaybackVolume = Px_GetPCMOutputVolume(mixer);
1343 
1344  SetMixer(inputSource);
1345  if( oldRecordVolume != recordVolume )
1346  Px_SetInputVolume(mixer, recordVolume);
1347  if( oldPlaybackVolume != playbackVolume )
1348  Px_SetPCMOutputVolume(mixer, playbackVolume);
1349 
1350  return;
1351  }
1352 #endif
1353 }
1354 
1355 void AudioIO::GetMixer(int *recordDevice, float *recordVolume,
1356  float *playbackVolume)
1357 {
1358 #if defined(USE_PORTMIXER)
1359 
1360  PxMixer *mixer = mPortMixer;
1361 
1362  if( mixer )
1363  {
1364  *recordDevice = Px_GetCurrentInputSource(mixer);
1365 
1366  if (mInputMixerWorks)
1367  *recordVolume = Px_GetInputVolume(mixer);
1368  else
1369  *recordVolume = 1.0f;
1370 
1372  *playbackVolume = mMixerOutputVol;
1373  else
1374  *playbackVolume = Px_GetPCMOutputVolume(mixer);
1375 
1376  return;
1377  }
1378 
1379 #endif
1380 
1381  *recordDevice = 0;
1382  *recordVolume = 1.0f;
1383  *playbackVolume = mMixerOutputVol;
1384 }
1385 
1387 {
1388  return mInputMixerWorks;
1389 }
1390 
1392 {
1393  return mEmulateMixerOutputVol;
1394 }
1395 
1397 {
1398 #if defined(USE_PORTMIXER)
1399 
1400  wxArrayString deviceNames;
1401 
1402  if( mPortMixer )
1403  {
1404  int numSources = Px_GetNumInputSources(mPortMixer);
1405  for( int source = 0; source < numSources; source++ )
1406  deviceNames.Add(wxString(wxSafeConvertMB2WX(Px_GetInputSourceName(mPortMixer, source))));
1407  }
1408  else
1409  {
1410  wxLogDebug(wxT("AudioIO::GetInputSourceNames(): PortMixer not initialised!"));
1411  }
1412 
1413  return deviceNames;
1414 
1415 #else
1416 
1417  wxArrayString blank;
1418 
1419  return blank;
1420 
1421 #endif
1422 }
1423 
1425 {
1426  // This should not happen, but it would screw things up if it did.
1427  // Vaughan, 2010-10-08: But it *did* happen, due to a bug, and nobody
1428  // caught it because this method just returned. Added wxASSERT().
1429  wxASSERT(!IsStreamActive());
1430  if (IsStreamActive())
1431  return;
1432 
1433  // get the selected record and playback devices
1434  const int playDeviceNum = getPlayDevIndex();
1435  const int recDeviceNum = getRecordDevIndex();
1436 
1437  // If no change needed, return
1438  if (mCachedPlaybackIndex == playDeviceNum &&
1439  mCachedCaptureIndex == recDeviceNum)
1440  return;
1441 
1442  // cache playback/capture rates
1445  mCachedSampleRates = GetSupportedSampleRates(playDeviceNum, recDeviceNum);
1446  mCachedPlaybackIndex = playDeviceNum;
1447  mCachedCaptureIndex = recDeviceNum;
1448  mCachedBestRateIn = 0.0;
1449 
1450 #if defined(USE_PORTMIXER)
1451 
1452  // if we have a PortMixer object, close it down
1453  if (mPortMixer) {
1454  #if __WXMAC__
1455  // on the Mac we must make sure that we restore the hardware playthrough
1456  // state of the sound device to what it was before, because there isn't
1457  // a UI for this (!)
1458  if (Px_SupportsPlaythrough(mPortMixer) && mPreviousHWPlaythrough >= 0.0)
1459  Px_SetPlaythrough(mPortMixer, mPreviousHWPlaythrough);
1460  mPreviousHWPlaythrough = -1.0;
1461  #endif
1462  Px_CloseMixer(mPortMixer);
1463  mPortMixer = NULL;
1464  }
1465 
1466  // that might have given us no rates whatsoever, so we have to guess an
1467  // answer to do the next bit
1468  int numrates = mCachedSampleRates.GetCount();
1469  int highestSampleRate;
1470  if (numrates > 0)
1471  {
1472  highestSampleRate = mCachedSampleRates[numrates - 1];
1473  }
1474  else
1475  { // we don't actually have any rates that work for Rec and Play. Guess one
1476  // to use for messing with the mixer, which doesn't actually do either
1477  highestSampleRate = 44100;
1478  // mCachedSampleRates is still empty, but it's not used again, so
1479  // can ignore
1480  }
1481  mInputMixerWorks = false;
1482  mEmulateMixerOutputVol = true;
1483  mMixerOutputVol = 1.0;
1484 
1485  int error;
1486  // This tries to open the device with the samplerate worked out above, which
1487  // will be the highest available for play and record on the device, or
1488  // 44.1kHz if the info cannot be fetched.
1489 
1490  PaStream *stream;
1491 
1492  PaStreamParameters playbackParameters;
1493 
1494  playbackParameters.device = playDeviceNum;
1495  playbackParameters.sampleFormat = paFloat32;
1496  playbackParameters.hostApiSpecificStreamInfo = NULL;
1497  playbackParameters.channelCount = 1;
1498  if (Pa_GetDeviceInfo(playDeviceNum))
1499  playbackParameters.suggestedLatency =
1500  Pa_GetDeviceInfo(playDeviceNum)->defaultLowOutputLatency;
1501  else
1502  playbackParameters.suggestedLatency = DEFAULT_LATENCY_CORRECTION/1000.0;
1503 
1504  PaStreamParameters captureParameters;
1505 
1506  captureParameters.device = recDeviceNum;
1507  captureParameters.sampleFormat = paFloat32;;
1508  captureParameters.hostApiSpecificStreamInfo = NULL;
1509  captureParameters.channelCount = 1;
1510  if (Pa_GetDeviceInfo(recDeviceNum))
1511  captureParameters.suggestedLatency =
1512  Pa_GetDeviceInfo(recDeviceNum)->defaultLowInputLatency;
1513  else
1514  captureParameters.suggestedLatency = DEFAULT_LATENCY_CORRECTION/1000.0;
1515 
1516  // try opening for record and playback
1517  error = Pa_OpenStream(&stream,
1518  &captureParameters, &playbackParameters,
1519  highestSampleRate, paFramesPerBufferUnspecified,
1520  paClipOff | paDitherOff,
1521  audacityAudioCallback, NULL);
1522 
1523  if (!error) {
1524  // Try portmixer for this stream
1525  mPortMixer = Px_OpenMixer(stream, 0);
1526  if (!mPortMixer) {
1527  Pa_CloseStream(stream);
1528  error = true;
1529  }
1530  }
1531 
1532  // if that failed, try just for record
1533  if( error ) {
1534  error = Pa_OpenStream(&stream,
1535  &captureParameters, NULL,
1536  highestSampleRate, paFramesPerBufferUnspecified,
1537  paClipOff | paDitherOff,
1538  audacityAudioCallback, NULL);
1539 
1540  if (!error) {
1541  mPortMixer = Px_OpenMixer(stream, 0);
1542  if (!mPortMixer) {
1543  Pa_CloseStream(stream);
1544  error = true;
1545  }
1546  }
1547  }
1548 
1549  // finally, try just for playback
1550  if ( error ) {
1551  error = Pa_OpenStream(&stream,
1552  NULL, &playbackParameters,
1553  highestSampleRate, paFramesPerBufferUnspecified,
1554  paClipOff | paDitherOff,
1555  audacityAudioCallback, NULL);
1556 
1557  if (!error) {
1558  mPortMixer = Px_OpenMixer(stream, 0);
1559  if (!mPortMixer) {
1560  Pa_CloseStream(stream);
1561  error = true;
1562  }
1563  }
1564  }
1565 
1566  // FIXME: TRAP_ERR errors in HandleDeviceChange not reported.
1567  // if it's still not working, give up
1568  if( error )
1569  return;
1570 
1571  // Set input source
1572 #if USE_PORTMIXER
1573  int sourceIndex;
1574  if (gPrefs->Read(wxT("/AudioIO/RecordingSourceIndex"), &sourceIndex)) {
1575  if (sourceIndex >= 0) {
1576  //the current index of our source may be different because the stream
1577  //is a combination of two devices, so update it.
1578  sourceIndex = getRecordSourceIndex(mPortMixer);
1579  if (sourceIndex >= 0)
1580  SetMixer(sourceIndex);
1581  }
1582  }
1583 #endif
1584 
1585  // Determine mixer capabilities - if it doesn't support control of output
1586  // signal level, we emulate it (by multiplying this value by all outgoing
1587  // samples)
1588 
1589  mMixerOutputVol = Px_GetPCMOutputVolume(mPortMixer);
1590  mEmulateMixerOutputVol = false;
1591  Px_SetPCMOutputVolume(mPortMixer, 0.0);
1592  if (Px_GetPCMOutputVolume(mPortMixer) > 0.1)
1593  mEmulateMixerOutputVol = true;
1594  Px_SetPCMOutputVolume(mPortMixer, 0.2f);
1595  if (Px_GetPCMOutputVolume(mPortMixer) < 0.1 ||
1596  Px_GetPCMOutputVolume(mPortMixer) > 0.3)
1597  mEmulateMixerOutputVol = true;
1598  Px_SetPCMOutputVolume(mPortMixer, mMixerOutputVol);
1599 
1600  float inputVol = Px_GetInputVolume(mPortMixer);
1601  mInputMixerWorks = true; // assume it works unless proved wrong
1602  Px_SetInputVolume(mPortMixer, 0.0);
1603  if (Px_GetInputVolume(mPortMixer) > 0.1)
1604  mInputMixerWorks = false; // can't set to zero
1605  Px_SetInputVolume(mPortMixer, 0.2f);
1606  if (Px_GetInputVolume(mPortMixer) < 0.1 ||
1607  Px_GetInputVolume(mPortMixer) > 0.3)
1608  mInputMixerWorks = false; // can't set level accurately
1609  Px_SetInputVolume(mPortMixer, inputVol);
1610 
1611  Pa_CloseStream(stream);
1612 
1613 
1614  #if 0
1615  wxPrintf("PortMixer: Playback: %s Recording: %s\n",
1616  mEmulateMixerOutputVol? "emulated": "native",
1617  mInputMixerWorks? "hardware": "no control");
1618  #endif
1619 
1620  mMixerOutputVol = 1.0;
1621 
1622 #endif // USE_PORTMIXER
1623 }
1624 
1625 static PaSampleFormat AudacityToPortAudioSampleFormat(sampleFormat format)
1626 {
1627  switch(format) {
1628  case int16Sample:
1629  return paInt16;
1630  case int24Sample:
1631  return paInt24;
1632  case floatSample:
1633  default:
1634  return paFloat32;
1635  }
1636 }
1637 
1638 bool AudioIO::StartPortAudioStream(double sampleRate,
1639  unsigned int numPlaybackChannels,
1640  unsigned int numCaptureChannels,
1641  sampleFormat captureFormat)
1642 {
1643 #ifdef EXPERIMENTAL_MIDI_OUT
1644  mNumFrames = 0;
1645  mNumPauseFrames = 0;
1646  // we want this initial value to be way high. It should be
1647  // sufficient to assume AudioTime is zero and therefore
1648  // mSystemMinusAudioTime is SystemTime(), but we'll add 1000s
1649  // for good measure. On the first callback, this should be
1650  // reduced to SystemTime() - mT0, and note that mT0 is always
1651  // positive.
1652  mSystemMinusAudioTimePlusLatency =
1653  mSystemMinusAudioTime = SystemTime(mUsingAlsa) + 1000;
1654  mAudioOutLatency = 0.0; // set when stream is opened
1655  mCallbackCount = 0;
1656  mAudioFramesPerBuffer = 0;
1657 #endif
1659 
1660  // PRL: Protection from crash reported by David Bailes, involving starting
1661  // and stopping with frequent changes of active window, hard to reproduce
1662  if (!mOwningProject)
1663  return false;
1664 
1665  mInputMeter = NULL;
1666  mOutputMeter = NULL;
1667 
1668  mLastPaError = paNoError;
1669  // pick a rate to do the audio I/O at, from those available. The project
1670  // rate is suggested, but we may get something else if it isn't supported
1671  mRate = GetBestRate(numCaptureChannels > 0, numPlaybackChannels > 0, sampleRate);
1672 
1673  // July 2016 (Carsten and Uwe)
1674  // BUG 193: Tell PortAudio sound card will handle 24 bit (under DirectSound) using
1675  // userData.
1676  int captureFormat_saved = captureFormat;
1677  // Special case: Our 24-bit sample format is different from PortAudio's
1678  // 3-byte packed format. So just make PortAudio return float samples,
1679  // since we need float values anyway to apply the gain.
1680  // ANSWER-ME: So we *never* actually handle 24-bit?! This causes mCapture to
1681  // be set to floatSample below.
1682  // JKC: YES that's right. Internally Audacity uses float, and float has space for
1683  // 24 bits as well as exponent. Actual 24 bit would require packing and
1684  // unpacking unaligned bytes and would be inefficient.
1685  // ANSWER ME: is floatSample 64 bit on 64 bit machines?
1686  if (captureFormat == int24Sample)
1687  captureFormat = floatSample;
1688 
1689  mNumPlaybackChannels = numPlaybackChannels;
1690  mNumCaptureChannels = numCaptureChannels;
1691 
1692  bool usePlayback = false, useCapture = false;
1693  PaStreamParameters playbackParameters{};
1694  PaStreamParameters captureParameters{};
1695 
1696  double latencyDuration = DEFAULT_LATENCY_DURATION;
1697  gPrefs->Read(wxT("/AudioIO/LatencyDuration"), &latencyDuration);
1698 
1699  if( numPlaybackChannels > 0)
1700  {
1701  usePlayback = true;
1702 
1703  // this sets the device index to whatever is "right" based on preferences,
1704  // then defaults
1705  playbackParameters.device = getPlayDevIndex();
1706 
1707  const PaDeviceInfo *playbackDeviceInfo;
1708  playbackDeviceInfo = Pa_GetDeviceInfo( playbackParameters.device );
1709 
1710  if( playbackDeviceInfo == NULL )
1711  return false;
1712 
1713  // regardless of source formats, we always mix to float
1714  playbackParameters.sampleFormat = paFloat32;
1715  playbackParameters.hostApiSpecificStreamInfo = NULL;
1716  playbackParameters.channelCount = mNumPlaybackChannels;
1717 
1719  playbackParameters.suggestedLatency =
1720  playbackDeviceInfo->defaultLowOutputLatency;
1721  else
1722  playbackParameters.suggestedLatency = latencyDuration/1000.0;
1723 
1725  }
1726 
1727  if( numCaptureChannels > 0)
1728  {
1729  useCapture = true;
1730  mCaptureFormat = captureFormat;
1731 
1732  const PaDeviceInfo *captureDeviceInfo;
1733  // retrieve the index of the device set in the prefs, or a sensible
1734  // default if it isn't set/valid
1735  captureParameters.device = getRecordDevIndex();
1736 
1737  captureDeviceInfo = Pa_GetDeviceInfo( captureParameters.device );
1738 
1739  if( captureDeviceInfo == NULL )
1740  return false;
1741 
1742  captureParameters.sampleFormat =
1744 
1745  captureParameters.hostApiSpecificStreamInfo = NULL;
1746  captureParameters.channelCount = mNumCaptureChannels;
1747 
1749  captureParameters.suggestedLatency =
1750  captureDeviceInfo->defaultHighInputLatency;
1751  else
1752  captureParameters.suggestedLatency = latencyDuration/1000.0;
1753 
1755  }
1756 
1757  SetMeters();
1758 
1759 #ifdef USE_PORTMIXER
1760 #ifdef __WXMSW__
1761  //mchinen nov 30 2010. For some reason Pa_OpenStream resets the input volume on windows.
1762  //so cache and restore after it.
1763  //The actual problem is likely in portaudio's pa_win_wmme.c OpenStream().
1764  float oldRecordVolume = Px_GetInputVolume(mPortMixer);
1765 #endif
1766 #endif
1767 
1768  // July 2016 (Carsten and Uwe)
1769  // BUG 193: Possibly tell portAudio to use 24 bit with DirectSound.
1770  int userData = 24;
1771  int* lpUserData = (captureFormat_saved == int24Sample) ? &userData : NULL;
1772 
1773  mLastPaError = Pa_OpenStream( &mPortStreamV19,
1774  useCapture ? &captureParameters : NULL,
1775  usePlayback ? &playbackParameters : NULL,
1776  mRate, paFramesPerBufferUnspecified,
1777  paNoFlag,
1778  audacityAudioCallback, lpUserData );
1779 
1780 
1781 #if USE_PORTMIXER
1782 #ifdef __WXMSW__
1783  Px_SetInputVolume(mPortMixer, oldRecordVolume);
1784 #endif
1785  if (mPortStreamV19 != NULL && mLastPaError == paNoError) {
1786 
1787  #ifdef __WXMAC__
1788  if (mPortMixer) {
1789  if (Px_SupportsPlaythrough(mPortMixer)) {
1790  bool playthrough = false;
1791 
1792  mPreviousHWPlaythrough = Px_GetPlaythrough(mPortMixer);
1793 
1794  // Bug 388. Feature not supported.
1795  //gPrefs->Read(wxT("/AudioIO/Playthrough"), &playthrough, false);
1796  if (playthrough)
1797  Px_SetPlaythrough(mPortMixer, 1.0);
1798  else
1799  Px_SetPlaythrough(mPortMixer, 0.0);
1800  }
1801  }
1802  #endif
1803  }
1804 #endif
1805 
1806  // We use audio latency to estimate how far ahead of DACS we are writing
1807  if (mPortStreamV19 != NULL && mLastPaError == paNoError) {
1808  const PaStreamInfo* info = Pa_GetStreamInfo(mPortStreamV19);
1809  // this is an initial guess, but for PA/Linux/ALSA it's wrong and will be
1810  // updated with a better value:
1811  mAudioOutLatency = info->outputLatency;
1812  mSystemMinusAudioTimePlusLatency += mAudioOutLatency;
1813  }
1814 
1815  return (mLastPaError == paNoError);
1816 }
1817 
1818 void AudioIO::StartMonitoring(double sampleRate)
1819 {
1820  if ( mPortStreamV19 || mStreamToken )
1821  return;
1822 
1823  bool success;
1824  long captureChannels;
1825  sampleFormat captureFormat = (sampleFormat)
1826  gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample);
1827  gPrefs->Read(wxT("/AudioIO/RecordChannels"), &captureChannels, 2L);
1828  gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &mSoftwarePlaythrough, false);
1829  int playbackChannels = 0;
1830 
1832  playbackChannels = 2;
1833 
1834  // FIXME: TRAP_ERR StartPortAudioStream (a PaError may be present)
1835  // but StartPortAudioStream function only returns true or false.
1836  mUsingAlsa = false;
1837  success = StartPortAudioStream(sampleRate, (unsigned int)playbackChannels,
1838  (unsigned int)captureChannels,
1839  captureFormat);
1840  // TODO: Check return value of success.
1841  (void)success;
1842 
1843  wxCommandEvent e(EVT_AUDIOIO_MONITOR);
1844  e.SetEventObject(mOwningProject);
1845  e.SetInt(true);
1846  wxTheApp->ProcessEvent(e);
1847 
1848  // FIXME: TRAP_ERR PaErrorCode 'noted' but not reported in StartMonitoring.
1849  // Now start the PortAudio stream!
1850  // TODO: ? Factor out and reuse error reporting code from end of
1851  // AudioIO::StartStream?
1852  mLastPaError = Pa_StartStream( mPortStreamV19 );
1853 
1854  // Update UI display only now, after all possibilities for error are past.
1855  if ((mLastPaError == paNoError) && mListener) {
1856  // advertise the chosen I/O sample rate to the UI
1857  mListener->OnAudioIORate((int)mRate);
1858  }
1859 }
1860 
1861 int AudioIO::StartStream(const WaveTrackConstArray &playbackTracks,
1862  const WaveTrackArray &captureTracks,
1863 #ifdef EXPERIMENTAL_MIDI_OUT
1864  const NoteTrackArray &midiPlaybackTracks,
1865 #endif
1866  double t0, double t1,
1867  const AudioIOStartStreamOptions &options)
1868 {
1869  mLostSamples = 0;
1870  mLostCaptureIntervals.clear();
1871  mDetectDropouts =
1872  gPrefs->Read( WarningDialogKey(wxT("DropoutDetected")), true );
1873  auto cleanup = finally ( [this] { ClearRecordingException(); } );
1874 
1875  if( IsBusy() )
1876  return 0;
1877 
1878  const auto &sampleRate = options.rate;
1879 
1880  // We just want to set mStreamToken to -1 - this way avoids
1881  // an extremely rare but possible race condition, if two functions
1882  // somehow called StartStream at the same time...
1883  mStreamToken--;
1884  if (mStreamToken != -1)
1885  return 0;
1886 
1887  // TODO: we don't really need to close and reopen stream if the
1888  // format matches; however it's kind of tricky to keep it open...
1889  //
1890  // if (sampleRate == mRate &&
1891  // playbackChannels == mNumPlaybackChannels &&
1892  // captureChannels == mNumCaptureChannels &&
1893  // captureFormat == mCaptureFormat) {
1894 
1895  if (mPortStreamV19) {
1896  StopStream();
1897  while(mPortStreamV19)
1898  wxMilliSleep( 50 );
1899  }
1900 
1901 #ifdef __WXGTK__
1902  // Detect whether ALSA is the chosen host, and do the various involved MIDI
1903  // timing compensations only then.
1904  mUsingAlsa = (gPrefs->Read(wxT("/AudioIO/Host"), wxT("")) == "ALSA");
1905 #endif
1906 
1907  gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &mSoftwarePlaythrough, false);
1908  gPrefs->Read(wxT("/AudioIO/SoundActivatedRecord"), &mPauseRec, false);
1909  int silenceLevelDB;
1910  gPrefs->Read(wxT("/AudioIO/SilenceLevel"), &silenceLevelDB, -50);
1911  int dBRange;
1912  dBRange = gPrefs->Read(ENV_DB_KEY, ENV_DB_RANGE);
1913  if(silenceLevelDB < -dBRange)
1914  {
1915  silenceLevelDB = -dBRange + 3; // meter range was made smaller than SilenceLevel
1916  gPrefs->Write(ENV_DB_KEY, dBRange); // so set SilenceLevel reasonable
1917  gPrefs->Flush();
1918  }
1919  mSilenceLevel = (silenceLevelDB + dBRange)/(double)dBRange; // meter goes -dBRange dB -> 0dB
1920 
1921  mTimeTrack = options.timeTrack;
1922  mListener = options.listener;
1923  mRate = sampleRate;
1924  mT0 = t0;
1925  mT1 = t1;
1926  mTime = t0;
1927  mSeek = 0;
1929  mCaptureTracks = captureTracks;
1930  mPlaybackTracks = playbackTracks;
1931 #ifdef EXPERIMENTAL_MIDI_OUT
1932  mMidiPlaybackTracks = midiPlaybackTracks;
1933 #endif
1934 
1935  bool commit = false;
1936  auto cleanupTracks = finally([&]{
1937  if (!commit) {
1938  // Don't keep unnecessary shared pointers to tracks
1939  mPlaybackTracks.clear();
1940  mCaptureTracks.clear();
1941 #ifdef EXPERIMENTAL_MIDI_OUT
1942  mMidiPlaybackTracks.clear();
1943 #endif
1944  }
1945  });
1946 
1950 
1951  mPlaybackBuffers.reset();
1952  mPlaybackMixers.reset();
1953  mCaptureBuffers.reset();
1954  mResample.reset();
1955 
1956  double playbackTime = 4.0;
1957 
1958  streamStartTime = 0;
1959  streamStartTime = SystemTime(mUsingAlsa);
1960 
1961 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
1962  bool scrubbing = (options.pScrubbingOptions != nullptr);
1963 
1964  // Scrubbing is not compatible with looping or recording or a time track!
1965  if (scrubbing)
1966  {
1967  const auto &scrubOptions = *options.pScrubbingOptions;
1968 
1969  if (mCaptureTracks.size() > 0 ||
1970  mPlayMode == PLAY_LOOPED ||
1971  mTimeTrack != NULL ||
1972  scrubOptions.maxSpeed < ScrubbingOptions::MinAllowedScrubSpeed()) {
1973  wxASSERT(false);
1974  scrubbing = false;
1975  }
1976  else {
1977  playbackTime = lrint(scrubOptions.delay * sampleRate) / sampleRate;
1979  }
1980  }
1981 #endif
1982 
1983  // mWarpedTime and mWarpedLength are irrelevant when scrubbing,
1984  // else they are used in updating mTime,
1985  // and when not scrubbing or playing looped, mTime is also used
1986  // in the test for termination of playback.
1987 
1988  // with ComputeWarpedLength, it is now possible the calculate the warped length with 100% accuracy
1989  // (ignoring accumulated rounding errors during playback) which fixes the 'missing sound at the end' bug
1990  mWarpedTime = 0.0;
1991 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
1992  if (scrubbing)
1993  mWarpedLength = 0.0;
1994  else
1995 #endif
1996  {
1997  if (mTimeTrack)
1998  // Following gives negative when mT0 > mT1
2000  else
2001  mWarpedLength = mT1 - mT0;
2002  // PRL allow backwards play
2003  mWarpedLength = fabs(mWarpedLength);
2004  }
2005 
2006  //
2007  // The RingBuffer sizes, and the max amount of the buffer to
2008  // fill at a time, both grow linearly with the number of
2009  // tracks. This allows us to scale up to many tracks without
2010  // killing performance.
2011  //
2012 
2013  // (warped) playback time to produce with each filling of the buffers
2014  // by the Audio thread (except at the end of playback):
2015  // usually, make fillings fewer and longer for less CPU usage.
2016  // But for useful scrubbing, we can't run too far ahead without checking
2017  // mouse input, so make fillings more and shorter.
2018  // What Audio thread produces for playback is then consumed by the PortAudio
2019  // thread, in many smaller pieces.
2020  wxASSERT( playbackTime >= 0 );
2021  mPlaybackSamplesToCopy = playbackTime * mRate;
2022 
2023  // Capacity of the playback buffer.
2024  mPlaybackRingBufferSecs = 10.0;
2025 
2026  mCaptureRingBufferSecs = 4.5 + 0.5 * std::min(size_t(16), mCaptureTracks.size());
2027  mMinCaptureSecsToCopy = 0.2 + 0.2 * std::min(size_t(16), mCaptureTracks.size());
2028 
2029  unsigned int playbackChannels = 0;
2030  unsigned int captureChannels = 0;
2031  sampleFormat captureFormat = floatSample;
2032 
2033  if (playbackTracks.size() > 0
2034 #ifdef EXPERIMENTAL_MIDI_OUT
2035  || midiPlaybackTracks.size() > 0
2036 #endif
2037  )
2038  playbackChannels = 2;
2039 
2041  playbackChannels = 2;
2042 
2043  if( captureTracks.size() > 0 )
2044  {
2045  // For capture, every input channel gets its own track
2046  captureChannels = mCaptureTracks.size();
2047  // I don't deal with the possibility of the capture tracks
2048  // having different sample formats, since it will never happen
2049  // with the current code. This code wouldn't *break* if this
2050  // assumption was false, but it would be sub-optimal. For example,
2051  // if the first track was 16-bit and the second track was 24-bit,
2052  // we would set the sound card to capture in 16 bits and the second
2053  // track wouldn't get the benefit of all 24 bits the card is capable
2054  // of.
2055  captureFormat = mCaptureTracks[0]->GetSampleFormat();
2056 
2057  // Tell project that we are about to start recording
2058  if (mListener)
2060  }
2061 
2062  bool successAudio;
2063 
2064  successAudio = StartPortAudioStream(sampleRate, playbackChannels,
2065  captureChannels, captureFormat);
2066 #ifdef EXPERIMENTAL_MIDI_OUT
2067 
2068  // TODO: it may be that midi out will not work unless audio in or out is
2069  // active -- this would be a bug and may require a change in the
2070  // logic here.
2071 
2072  bool successMidi = true;
2073 
2074  if(!mMidiPlaybackTracks.empty()){
2075  successMidi = StartPortMidiStream();
2076  }
2077 
2078  // On the other hand, if MIDI cannot be opened, we will not complain
2079 #endif
2080 
2081  if (!successAudio) {
2082  if (mListener && captureChannels > 0)
2084  mStreamToken = 0;
2085 
2086  // Don't cause a busy wait in the audio thread after stopping scrubbing
2088 
2089  return 0;
2090  }
2091 
2092  //
2093  // The (audio) stream has been opened successfully (assuming we tried
2094  // to open it). We now proceed to
2095  // allocate the memory structures the stream will need.
2096  //
2097 
2098  bool bDone;
2099  do
2100  {
2101  bDone = true; // assume success
2102  try
2103  {
2104  if( mNumPlaybackChannels > 0 ) {
2105  // Allocate output buffers. For every output track we allocate
2106  // a ring buffer of five seconds
2107  auto playbackBufferSize =
2108  (size_t)lrint(mRate * mPlaybackRingBufferSecs);
2109  auto playbackMixBufferSize =
2111 
2114 
2115  const Mixer::WarpOptions &warpOptions =
2116 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2117  scrubbing
2121  :
2122 #endif
2123  Mixer::WarpOptions(mTimeTrack);
2124 
2125  for (unsigned int i = 0; i < mPlaybackTracks.size(); i++)
2126  {
2127  mPlaybackBuffers[i] = std::make_unique<RingBuffer>(floatSample, playbackBufferSize);
2128 
2129  // MB: use normal time for the end time, not warped time!
2130  WaveTrackConstArray tracks;
2131  tracks.push_back(mPlaybackTracks[i]);
2132  mPlaybackMixers[i] = std::make_unique<Mixer>
2133  (tracks,
2134  // Don't throw for read errors, just play silence:
2135  false,
2136  warpOptions,
2137  mT0, mT1, 1,
2138  playbackMixBufferSize, false,
2139  mRate, floatSample, false);
2140  mPlaybackMixers[i]->ApplyTrackGains(false);
2141  }
2142  }
2143 
2144  if( mNumCaptureChannels > 0 )
2145  {
2146  // Allocate input buffers. For every input track we allocate
2147  // a ring buffer of five seconds
2148  auto captureBufferSize = (size_t)(mRate * mCaptureRingBufferSecs + 0.5);
2149 
2150  // In the extraordinarily rare case that we can't even afford 100 samples, just give up.
2151  if(captureBufferSize < 100)
2152  {
2154  AudacityMessageBox(_("Out of memory!"));
2155  return 0;
2156  }
2157 
2160  mFactor = sampleRate / mRate;
2161 
2162  for( unsigned int i = 0; i < mCaptureTracks.size(); i++ )
2163  {
2164  mCaptureBuffers[i] = std::make_unique<RingBuffer>
2165  ( mCaptureTracks[i]->GetSampleFormat(),
2166  captureBufferSize );
2167  mResample[i] = std::make_unique<Resample>(true, mFactor, mFactor); // constant rate resampling
2168  }
2169  }
2170  }
2171  catch(std::bad_alloc&)
2172  {
2173  // Oops! Ran out of memory. This is pretty rare, so we'll just
2174  // try deleting everything, halving our buffer size, and try again.
2175  StartStreamCleanup(true);
2176  mPlaybackRingBufferSecs *= 0.5;
2178  mCaptureRingBufferSecs *= 0.5;
2179  mMinCaptureSecsToCopy *= 0.5;
2180  bDone = false;
2181 
2182  // In the extraordinarily rare case that we can't even afford 100 samples, just give up.
2183  auto playbackBufferSize = (size_t)lrint(mRate * mPlaybackRingBufferSecs);
2184  auto playbackMixBufferSize = mPlaybackSamplesToCopy;
2185  if(playbackBufferSize < 100 || playbackMixBufferSize < 100)
2186  {
2188  AudacityMessageBox(_("Out of memory!"));
2189  return 0;
2190  }
2191  }
2192  } while(!bDone);
2193 
2194  if (mNumPlaybackChannels > 0)
2195  {
2197  // Setup for realtime playback at the rate of the realtime
2198  // stream, not the rate of the track.
2199  em.RealtimeInitialize(mRate);
2200 
2201  // The following adds a NEW effect processor for each logical track and the
2202  // group determination should mimic what is done in audacityAudioCallback()
2203  // when calling RealtimeProcess().
2204  int group = 0;
2205  for (size_t i = 0, cnt = mPlaybackTracks.size(); i < cnt; i++)
2206  {
2207  const WaveTrack *vt = gAudioIO->mPlaybackTracks[i].get();
2208 
2209  unsigned chanCnt = 1;
2210  if (vt->GetLinked())
2211  {
2212  i++;
2213  chanCnt++;
2214  }
2215 
2216  // Setup for realtime playback at the rate of the realtime
2217  // stream, not the rate of the track.
2218  em.RealtimeAddProcessor(group++, chanCnt, mRate);
2219  }
2220  }
2221 
2222 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
2223  AILASetStartTime();
2224 #endif
2225 
2226  if (options.pStartTime)
2227  {
2228  // Calculate the NEW time position
2229  mTime = std::max(mT0, std::min(mT1, *options.pStartTime));
2230  // Reset mixer positions for all playback tracks
2231  unsigned numMixers = mPlaybackTracks.size();
2232  for (unsigned ii = 0; ii < numMixers; ++ii)
2233  mPlaybackMixers[ii]->Reposition(mTime);
2234  if(mTimeTrack)
2236  else
2237  mWarpedTime = mTime - mT0;
2238  }
2239 
2240 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2241  if (scrubbing)
2242  {
2243  const auto &scrubOptions = *options.pScrubbingOptions;
2244  mScrubQueue =
2245  std::make_unique<ScrubQueue>(mT0, mT1, scrubOptions.startClockTimeMillis,
2246  sampleRate, 2 * scrubOptions.minStutter,
2247  scrubOptions);
2248  mScrubDuration = 0;
2249  mSilentScrub = false;
2250  }
2251  else
2252  mScrubQueue.reset();
2253 #endif
2254 
2255  // We signal the audio thread to call FillBuffers, to prime the RingBuffers
2256  // so that they will have data in them when the stream starts. Having the
2257  // audio thread call FillBuffers here makes the code more predictable, since
2258  // FillBuffers will ALWAYS get called from the Audio thread.
2260 
2261  while( mAudioThreadShouldCallFillBuffersOnce == true ) {
2262  if (mScrubQueue)
2263  mScrubQueue->Nudge();
2264  wxMilliSleep( 50 );
2265  }
2266 
2267  if(mNumPlaybackChannels > 0 || mNumCaptureChannels > 0) {
2268 
2269 #ifdef REALTIME_ALSA_THREAD
2270  // PRL: Do this in hope of less thread scheduling jitter in calls to
2271  // audacityAudioCallback.
2272  // Not needed to make audio playback work smoothly.
2273  // But needed in case we also play MIDI, so that the variable "offset"
2274  // in AudioIO::MidiTime() is a better approximation of the duration
2275  // between the call of audacityAudioCallback and the actual output of
2276  // the first audio sample.
2277  // (Which we should be able to determine from fields of
2278  // PaStreamCallbackTimeInfo, but that seems not to work as documented with
2279  // ALSA.)
2280  if (mUsingAlsa)
2281  // Perhaps we should do this only if also playing MIDI ?
2282  PaAlsa_EnableRealtimeScheduling( mPortStreamV19, 1 );
2283 #endif
2284 
2285  //
2286  // Generate a unique value each time, to be returned to
2287  // clients accessing the AudioIO API, so they can query if they
2288  // are the ones who have reserved AudioIO or not.
2289  //
2290  // It is important to set this before setting the portaudio stream in
2291  // motion -- otherwise it may play an unspecified number of leading
2292  // zeroes.
2294 
2295  // This affects the AudioThread (not the portaudio callback).
2296  // Probably not needed so urgently before portaudio thread start for usual
2297  // playback, since our ring buffers have been primed already with 4 sec
2298  // of audio, but then we might be scrubbing, so do it.
2300 
2301  // Now start the PortAudio stream!
2302  PaError err;
2303  err = Pa_StartStream( mPortStreamV19 );
2304 
2305  if( err != paNoError )
2306  {
2307  mStreamToken = 0;
2309  if (mListener && mNumCaptureChannels > 0)
2312  AudacityMessageBox(LAT1CTOWX(Pa_GetErrorText(err)));
2313  return 0;
2314  }
2315  }
2316 
2317  // Update UI display only now, after all possibilities for error are past.
2318  if (mListener) {
2319  // advertise the chosen I/O sample rate to the UI
2320  mListener->OnAudioIORate((int)mRate);
2321  }
2322 
2323  if (mNumPlaybackChannels > 0)
2324  {
2325  wxCommandEvent e(EVT_AUDIOIO_PLAYBACK);
2326  e.SetEventObject(mOwningProject);
2327  e.SetInt(true);
2328  wxTheApp->ProcessEvent(e);
2329  }
2330 
2331  if (mNumCaptureChannels > 0)
2332  {
2333  wxCommandEvent e(EVT_AUDIOIO_CAPTURE);
2334  e.SetEventObject(mOwningProject);
2335  e.SetInt(true);
2336  wxTheApp->ProcessEvent(e);
2337  }
2338 
2339  // Enable warning popups for unfound aliased blockfiles.
2341 
2342  commit = true;
2343  return mStreamToken;
2344 }
2345 
2346 void AudioIO::StartStreamCleanup(bool bOnlyBuffers)
2347 {
2348  if (mNumPlaybackChannels > 0)
2349  {
2351  }
2352 
2353  mPlaybackBuffers.reset();
2354  mPlaybackMixers.reset();
2355  mCaptureBuffers.reset();
2356  mResample.reset();
2357 
2358  if(!bOnlyBuffers)
2359  {
2360  Pa_AbortStream( mPortStreamV19 );
2361  Pa_CloseStream( mPortStreamV19 );
2362  mPortStreamV19 = NULL;
2363  mStreamToken = 0;
2364  }
2365 
2366 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2367  mScrubQueue.reset();
2368 #endif
2369 
2370 
2371  // Don't cause a busy wait in the audio thread after stopping scrubbing
2373 }
2374 
2375 #ifdef EXPERIMENTAL_MIDI_OUT
2376 
2377 PmTimestamp MidiTime(void *WXUNUSED(info))
2378 {
2379  return gAudioIO->MidiTime();
2380 }
2381 
2382 // Set up state to iterate NoteTrack events in sequence.
2383 // Sends MIDI control changes up to the starting point mT0
2384 // if send is true. Output is delayed by offset to facilitate
2385 // looping (each iteration is delayed more).
2386 void AudioIO::PrepareMidiIterator(bool send, double offset)
2387 {
2388  int i;
2389  int nTracks = mMidiPlaybackTracks.size();
2390  // instead of initializing with an Alg_seq, we use begin_seq()
2391  // below to add ALL Alg_seq's.
2392  mIterator = std::make_unique<Alg_iterator>(nullptr, false);
2393  // Iterator not yet intialized, must add each track...
2394  for (i = 0; i < nTracks; i++) {
2395  NoteTrack *t = mMidiPlaybackTracks[i].get();
2396  Alg_seq_ptr seq = &t->GetSeq();
2397  // mark sequence tracks as "in use" since we're handing this
2398  // off to another thread and want to make sure nothing happens
2399  // to the data until playback finishes. This is just a sanity check.
2400  seq->set_in_use(true);
2401  mIterator->begin_seq(seq, t, t->GetOffset() + offset);
2402  }
2403  GetNextEvent(); // prime the pump for FillMidiBuffers
2404 
2405  // Start MIDI from current cursor position
2406  mSendMidiState = true;
2407  while (mNextEvent &&
2408  mNextEventTime < mT0 + offset) {
2409  if (send) OutputEvent();
2410  GetNextEvent();
2411  }
2412  mSendMidiState = false;
2413 }
2414 
2415 bool AudioIO::StartPortMidiStream()
2416 {
2417  int i;
2418  int nTracks = mMidiPlaybackTracks.size();
2419  // Only start MIDI stream if there is an open track
2420  if (nTracks == 0)
2421  return false;
2422 
2423  //wxPrintf("StartPortMidiStream: mT0 %g mTime %g\n",
2424  // gAudioIO->mT0, gAudioIO->mTime);
2425 
2426  /* get midi playback device */
2427  PmDeviceID playbackDevice = Pm_GetDefaultOutputDeviceID();
2428  wxString playbackDeviceName = gPrefs->Read(wxT("/MidiIO/PlaybackDevice"),
2429  wxT(""));
2430  mSynthLatency = gPrefs->Read(wxT("/MidiIO/SynthLatency"),
2432  if (wxStrcmp(playbackDeviceName, wxT("")) != 0) {
2433  for (i = 0; i < Pm_CountDevices(); i++) {
2434  const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
2435  if (!info) continue;
2436  if (!info->output) continue;
2437  wxString interf = wxSafeConvertMB2WX(info->interf);
2438  wxString name = wxSafeConvertMB2WX(info->name);
2439  interf.Append(wxT(": ")).Append(name);
2440  if (wxStrcmp(interf, playbackDeviceName) == 0) {
2441  playbackDevice = i;
2442  }
2443  }
2444  } // (else playback device has Pm_GetDefaultOuputDeviceID())
2445 
2446  /* open output device */
2447  mLastPmError = Pm_OpenOutput(&mMidiStream,
2448  playbackDevice,
2449  NULL,
2450  0,
2451  &::MidiTime,
2452  NULL,
2454  if (mLastPmError == pmNoError) {
2455  mMidiStreamActive = true;
2456  mMidiPaused = false;
2457  mMidiLoopPasses = 0;
2458  mMidiOutputComplete = false;
2459  mMaxMidiTimestamp = 0;
2460  PrepareMidiIterator();
2461 
2462  // It is ok to call this now, but do not send timestamped midi
2463  // until after the first audio callback, which provides necessary
2464  // data for MidiTime().
2465  Pm_Synchronize(mMidiStream); // start using timestamps
2466  // start midi output flowing (pending first audio callback)
2467  mMidiThreadFillBuffersLoopRunning = true;
2468  }
2469  return (mLastPmError == pmNoError);
2470 }
2471 #endif
2472 
2474 {
2475  return mOwningProject == NULL || mOwningProject == project;
2476 }
2477 
2479 {
2480  if (!mOwningProject || mOwningProject == project)
2481  {
2482  mInputMeter = meter;
2483  if (mInputMeter)
2484  {
2485  mInputMeter->Reset(mRate, true);
2486  }
2487  }
2488 }
2489 
2491 {
2492  if (!mOwningProject || mOwningProject == project)
2493  {
2494  mOutputMeter = meter;
2495  if (mOutputMeter)
2496  {
2497  mOutputMeter->Reset(mRate, true);
2498  }
2499  }
2500 }
2501 
2503  return mInputMeter;
2504 }
2505 
2507 {
2508  if (mInputMeter)
2509  mInputMeter->Reset(mRate, true);
2510  if (mOutputMeter)
2511  mOutputMeter->Reset(mRate, true);
2512 
2513  AudacityProject* pProj = GetActiveProject();
2514  MixerBoard* pMixerBoard = pProj->GetMixerBoard();
2515  if (pMixerBoard)
2516  pMixerBoard->ResetMeters(true);
2517 
2518  mUpdateMeters = true;
2519 }
2520 
2522 {
2523  auto cleanup = finally ( [this] { ClearRecordingException(); } );
2524 
2525  if( mPortStreamV19 == NULL
2526 #ifdef EXPERIMENTAL_MIDI_OUT
2527  && mMidiStream == NULL
2528 #endif
2529  )
2530  return;
2531 
2532  if( Pa_IsStreamStopped( mPortStreamV19 )
2533 #ifdef EXPERIMENTAL_MIDI_OUT
2534  && !mMidiStreamActive
2535 #endif
2536  )
2537  return;
2538 
2539  wxMutexLocker locker(mSuspendAudioThread);
2540 
2541  // No longer need effects processing
2542  if (mNumPlaybackChannels > 0)
2543  {
2545  }
2546 
2547  //
2548  // We got here in one of two ways:
2549  //
2550  // 1. The user clicked the stop button and we therefore want to stop
2551  // as quickly as possible. So we use AbortStream(). If this is
2552  // the case the portaudio stream is still in the Running state
2553  // (see PortAudio state machine docs).
2554  //
2555  // 2. The callback told PortAudio to stop the stream since it had
2556  // reached the end of the selection. The UI thread discovered
2557  // this by noticing that AudioIO::IsActive() returned false.
2558  // IsActive() (which calls Pa_GetStreamActive()) will not return
2559  // false until all buffers have finished playing, so we can call
2560  // AbortStream without losing any samples. If this is the case
2561  // we are in the "callback finished state" (see PortAudio state
2562  // machine docs).
2563  //
2564  // The moral of the story: We can call AbortStream safely, without
2565  // losing samples.
2566  //
2567  // DMM: This doesn't seem to be true; it seems to be necessary to
2568  // call StopStream if the callback brought us here, and AbortStream
2569  // if the user brought us here.
2570  //
2571 
2573  if (mScrubQueue)
2574  mScrubQueue->Nudge();
2575 
2576  // Audacity can deadlock if it tries to update meters while
2577  // we're stopping PortAudio (because the meter updating code
2578  // tries to grab a UI mutex while PortAudio tries to join a
2579  // pthread). So we tell the callback to stop updating meters,
2580  // and wait until the callback has left this part of the code
2581  // if it was already there.
2582  mUpdateMeters = false;
2583  while(mUpdatingMeters) {
2584  ::wxSafeYield();
2585  wxMilliSleep( 50 );
2586  }
2587 
2588  // Turn off HW playthrough if PortMixer is being used
2589 
2590  #if defined(USE_PORTMIXER)
2591  if( mPortMixer ) {
2592  #if __WXMAC__
2593  if (Px_SupportsPlaythrough(mPortMixer) && mPreviousHWPlaythrough >= 0.0)
2594  Px_SetPlaythrough(mPortMixer, mPreviousHWPlaythrough);
2595  mPreviousHWPlaythrough = -1.0;
2596  #endif
2597  }
2598  #endif
2599 
2600  if (mPortStreamV19) {
2601  Pa_AbortStream( mPortStreamV19 );
2602  Pa_CloseStream( mPortStreamV19 );
2603  mPortStreamV19 = NULL;
2604  }
2605 
2606  if (mNumPlaybackChannels > 0)
2607  {
2608  wxCommandEvent e(EVT_AUDIOIO_PLAYBACK);
2609  e.SetEventObject(mOwningProject);
2610  e.SetInt(false);
2611  wxTheApp->ProcessEvent(e);
2612  }
2613 
2614  if (mNumCaptureChannels > 0)
2615  {
2616  wxCommandEvent e(mStreamToken == 0 ? EVT_AUDIOIO_MONITOR : EVT_AUDIOIO_CAPTURE);
2617  e.SetEventObject(mOwningProject);
2618  e.SetInt(false);
2619  wxTheApp->ProcessEvent(e);
2620  }
2621 
2622 #ifdef EXPERIMENTAL_MIDI_OUT
2623  /* Stop Midi playback */
2624  if ( mMidiStream ) {
2625 
2626  mMidiStreamActive = false;
2627 
2628 #ifdef USE_MIDI_THREAD
2629  mMidiThreadFillBuffersLoopRunning = false; // stop output to stream
2630  // but output is in another thread. Wait for output to stop...
2631  while (mMidiThreadFillBuffersLoopActive) {
2632  wxMilliSleep(1);
2633  }
2634 #endif
2635 
2636  mMidiOutputComplete = true;
2637 
2638  // now we can assume "ownership" of the mMidiStream
2639  // if output in progress, send all off, etc.
2640  AllNotesOff();
2641  // AllNotesOff() should be sufficient to stop everything, but
2642  // in Linux, if you Pm_Close() immediately, it looks like
2643  // messages are dropped. ALSA then seems to send All Sound Off
2644  // and Reset All Controllers messages, but not all synthesizers
2645  // respond to these messages. This is probably a bug in PortMidi
2646  // if the All Off messages do not get out, but for security,
2647  // delay a bit so that messages can be delivered before closing
2648  // the stream. Add 2ms of "padding" to avoid any rounding errors.
2649  while (mMaxMidiTimestamp + 2 > MidiTime()) {
2650  wxMilliSleep(1); // deliver the all-off messages
2651  }
2652  Pm_Close(mMidiStream);
2653  mMidiStream = NULL;
2654  mIterator->end();
2655 
2656  // set in_use flags to false
2657  int nTracks = mMidiPlaybackTracks.size();
2658  for (int i = 0; i < nTracks; i++) {
2659  NoteTrack *t = mMidiPlaybackTracks[i].get();
2660  Alg_seq_ptr seq = &t->GetSeq();
2661  seq->set_in_use(false);
2662  }
2663 
2664  mIterator.reset(); // just in case someone tries to reference it
2665  }
2666 #endif
2667 
2668  // If there's no token, we were just monitoring, so we can
2669  // skip this next part...
2670  if (mStreamToken > 0) {
2671  // In either of the above cases, we want to make sure that any
2672  // capture data that made it into the PortAudio callback makes it
2673  // to the target WaveTrack. To do this, we ask the audio thread to
2674  // call FillBuffers one last time (it normally would not do so since
2675  // Pa_GetStreamActive() would now return false
2677 
2678  while( mAudioThreadShouldCallFillBuffersOnce == true )
2679  {
2680  // LLL: Experienced recursive yield here...once.
2681  wxGetApp().Yield(true); // Pass true for onlyIfNeeded to avoid recursive call error.
2682  if (mScrubQueue)
2683  mScrubQueue->Nudge();
2684  wxMilliSleep( 50 );
2685  }
2686 
2687  //
2688  // Everything is taken care of. Now, just free all the resources
2689  // we allocated in StartStream()
2690  //
2691 
2692  if (mPlaybackTracks.size() > 0)
2693  {
2694  mPlaybackBuffers.reset();
2695  mPlaybackMixers.reset();
2696  }
2697 
2698  //
2699  // Offset all recorded tracks to account for latency
2700  //
2701  if (mCaptureTracks.size() > 0)
2702  {
2703  mCaptureBuffers.reset();
2704  mResample.reset();
2705 
2706  //
2707  // We only apply latency correction when we actually played back
2708  // tracks during the recording. If we did not play back tracks,
2709  // there's nothing we could be out of sync with. This also covers the
2710  // case that we do not apply latency correction when recording the
2711  // first track in a project.
2712  //
2713  double latencyCorrection = DEFAULT_LATENCY_CORRECTION;
2714  gPrefs->Read(wxT("/AudioIO/LatencyCorrection"), &latencyCorrection);
2715 
2716  double recordingOffset =
2717  mLastRecordingOffset + latencyCorrection / 1000.0;
2718 
2719  for (unsigned int i = 0; i < mCaptureTracks.size(); i++) {
2720  // The calls to Flush, and (less likely) Clear and InsertSilence,
2721  // may cause exceptions because of exhaustion of disk space.
2722  // Stop those exceptions here, or else they propagate through too
2723  // many parts of Audacity that are not effects or editing
2724  // operations. GuardedCall ensures that the user sees a warning.
2725 
2726  // Also be sure to Flush each track, at the top of the guarded call,
2727  // relying on the guarantee that the track will be left in a flushed
2728  // state, though the append buffer may be lost.
2729 
2730  // If the other track operations fail their strong guarantees, then
2731  // the shift for latency correction may be skipped.
2732  GuardedCall( [&] {
2733  WaveTrack* track = mCaptureTracks[i].get();
2734 
2735  // use NOFAIL-GUARANTEE that track is flushed,
2736  // PARTIAL-GUARANTEE that some initial length of the recording
2737  // is saved.
2738  // See comments in FillBuffers().
2739  track->Flush();
2740 
2741  if (mPlaybackTracks.size() > 0)
2742  { // only do latency correction if some tracks are being played back
2743  WaveTrackArray playbackTracks;
2745  // we need to get this as mPlaybackTracks does not contain tracks being recorded into
2746  playbackTracks = p->GetTracks()->GetWaveTrackArray(false);
2747  bool appendRecord = false;
2748  for (unsigned int j = 0; j < playbackTracks.size(); j++)
2749  { // find if we are recording into an existing track (append-record)
2750  WaveTrack* trackP = playbackTracks[j].get();
2751  if( track == trackP )
2752  {
2753  if( track->GetStartTime() != mT0 ) // in a NEW track if these are equal
2754  {
2755  appendRecord = true;
2756  break;
2757  }
2758  }
2759  }
2760  if( appendRecord )
2761  { // append-recording
2762  if (recordingOffset < 0)
2763  // use STRONG-GUARANTEE
2764  track->Clear(mT0, mT0 - recordingOffset); // cut the latency out
2765  else
2766  // use STRONG-GUARANTEE
2767  track->InsertSilence(mT0, recordingOffset); // put silence in
2768  }
2769  else
2770  { // recording into a NEW track
2771  // gives NOFAIL-GUARANTEE though we only need STRONG
2772  track->SetOffset(track->GetStartTime() + recordingOffset);
2773  if(track->GetEndTime() < 0.)
2774  {
2775  // Bug 96: Only warn for the first track.
2776  if( i==0 )
2777  {
2778  AudacityMessageDialog m(NULL, _(
2779 "Latency Correction setting has caused the recorded audio to be hidden before zero.\nAudacity has brought it back to start at zero.\nYou may have to use the Time Shift Tool (<---> or F5) to drag the track to the right place."),
2780  _("Latency problem"), wxOK);
2781  m.ShowModal();
2782  }
2783  // gives NOFAIL-GUARANTEE though we only need STRONG
2784  track->SetOffset(0.);
2785  }
2786  }
2787  }
2788  } );
2789  }
2790 
2791  for (auto &interval : mLostCaptureIntervals) {
2792  auto &start = interval.first;
2793  if (mPlaybackTracks.size() > 0)
2794  // only do latency correction if some tracks are being played back
2795  start += recordingOffset;
2796  auto duration = interval.second;
2797  for (auto &track : mCaptureTracks) {
2798  GuardedCall([&] {
2799  track->SyncLockAdjust(start, start + duration);
2800  });
2801  }
2802  }
2803  }
2804  }
2805 
2806  if (mInputMeter)
2807  mInputMeter->Reset(mRate, false);
2808 
2809  if (mOutputMeter)
2810  mOutputMeter->Reset(mRate, false);
2811 
2812  MixerBoard* pMixerBoard = mOwningProject->GetMixerBoard();
2813  if (pMixerBoard)
2814  pMixerBoard->ResetMeters(false);
2815 
2816  mInputMeter = NULL;
2817  mOutputMeter = NULL;
2818  mOwningProject = NULL;
2819 
2820  if (mListener && mNumCaptureChannels > 0)
2822 
2823  //
2824  // Only set token to 0 after we're totally finished with everything
2825  //
2826  mStreamToken = 0;
2827 
2828  mNumCaptureChannels = 0;
2830 
2831  mPlaybackTracks.clear();
2832  mCaptureTracks.clear();
2833  mMidiPlaybackTracks.clear();
2834 
2835 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2836  mScrubQueue.reset();
2837 #endif
2838 
2839  if (mListener) {
2840  // Tell UI to hide sample rate
2842  }
2843 
2844  // Don't cause a busy wait in the audio thread after stopping scrubbing
2846 }
2847 
2848 void AudioIO::SetPaused(bool state)
2849 {
2850  if (state != mPaused)
2851  {
2852  if (state)
2853  {
2855  }
2856  else
2857  {
2859  }
2860  }
2861 
2862  mPaused = state;
2863 }
2864 
2866 {
2867  return mPaused;
2868 }
2869 
2870 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2872  (double endTimeOrSpeed, const ScrubbingOptions &options)
2873 {
2874  if (mScrubQueue)
2875  return mScrubQueue->Producer(endTimeOrSpeed, options);
2876  else
2877  return false;
2878 }
2879 
2881 {
2882  if (mScrubQueue)
2883  return mScrubQueue->LastTimeInQueue();
2884  else
2885  return -1.0;
2886 }
2887 
2888 #endif
2889 
2891 {
2892  if (mStreamToken != 0)
2893  return true;
2894 
2895  return false;
2896 }
2897 
2899 {
2900  bool isActive = false;
2901  // JKC: Not reporting any Pa error, but that looks OK.
2902  if( mPortStreamV19 )
2903  isActive = (Pa_IsStreamActive( mPortStreamV19 ) > 0);
2904 
2905 #ifdef EXPERIMENTAL_MIDI_OUT
2906  if( mMidiStreamActive && !mMidiOutputComplete )
2907  isActive = true;
2908 #endif
2909  return isActive;
2910 }
2911 
2913 {
2914  return (this->IsStreamActive() && this->IsAudioTokenActive(token));
2915 }
2916 
2918 {
2919  return ( token > 0 && token == mStreamToken );
2920 }
2921 
2923 {
2924  return ( mPortStreamV19 && mStreamToken==0 );
2925 }
2926 
2927 double AudioIO::LimitStreamTime(double absoluteTime) const
2928 {
2929  // Allows for forward or backward play
2930  if (ReversedTime())
2931  return std::max(mT1, std::min(mT0, absoluteTime));
2932  else
2933  return std::max(mT0, std::min(mT1, absoluteTime));
2934 }
2935 
2936 double AudioIO::NormalizeStreamTime(double absoluteTime) const
2937 {
2938  // dmazzoni: This function is needed for two reasons:
2939  // One is for looped-play mode - this function makes sure that the
2940  // position indicator keeps wrapping around. The other reason is
2941  // more subtle - it's because PortAudio can query the hardware for
2942  // the current stream time, and this query is not always accurate.
2943  // Sometimes it's a little behind or ahead, and so this function
2944  // makes sure that at least we clip it to the selection.
2945  //
2946  // msmeyer: There is also the possibility that we are using "cut preview"
2947  // mode. In this case, we should jump over a defined "gap" in the
2948  // audio.
2949 
2950 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2951  // Limit the time between t0 and t1 if not scrubbing.
2952  // Should the limiting be necessary in any play mode if there are no bugs?
2953  if (mPlayMode != PLAY_SCRUB)
2954 #endif
2955  absoluteTime = LimitStreamTime(absoluteTime);
2956 
2957  if (mCutPreviewGapLen > 0)
2958  {
2959  // msmeyer: We're in cut preview mode, so if we are on the right
2960  // side of the gap, we jump over it.
2961  if (absoluteTime > mCutPreviewGapStart)
2962  absoluteTime += mCutPreviewGapLen;
2963  }
2964 
2965  return absoluteTime;
2966 }
2967 
2969 {
2970  if( !IsStreamActive() )
2971  return BAD_STREAM_TIME;
2972 
2973  return NormalizeStreamTime(mTime);
2974 }
2975 
2976 
2977 wxArrayLong AudioIO::GetSupportedPlaybackRates(int devIndex, double rate)
2978 {
2979  if (devIndex == -1)
2980  { // weren't given a device index, get the prefs / default one
2981  devIndex = getPlayDevIndex();
2982  }
2983 
2984  // Check if we can use the cached rates
2985  if (mCachedPlaybackIndex != -1 && devIndex == mCachedPlaybackIndex
2986  && (rate == 0.0 || mCachedPlaybackRates.Index(rate) != wxNOT_FOUND))
2987  {
2988  return mCachedPlaybackRates;
2989  }
2990 
2991  wxArrayLong supported;
2992  int irate = (int)rate;
2993  const PaDeviceInfo* devInfo = NULL;
2994  int i;
2995 
2996  devInfo = Pa_GetDeviceInfo(devIndex);
2997 
2998  if (!devInfo)
2999  {
3000  wxLogDebug(wxT("GetSupportedPlaybackRates() Could not get device info!"));
3001  return supported;
3002  }
3003 
3004  // LLL: Remove when a proper method of determining actual supported
3005  // DirectSound rate is devised.
3006  const PaHostApiInfo* hostInfo = Pa_GetHostApiInfo(devInfo->hostApi);
3007  bool isDirectSound = (hostInfo && hostInfo->type == paDirectSound);
3008 
3009  PaStreamParameters pars;
3010 
3011  pars.device = devIndex;
3012  pars.channelCount = 1;
3013  pars.sampleFormat = paFloat32;
3014  pars.suggestedLatency = devInfo->defaultHighOutputLatency;
3015  pars.hostApiSpecificStreamInfo = NULL;
3016 
3017  // JKC: PortAudio Errors handled OK here. No need to report them
3018  for (i = 0; i < NumRatesToTry; i++)
3019  {
3020  // LLL: Remove when a proper method of determining actual supported
3021  // DirectSound rate is devised.
3022  if (!(isDirectSound && RatesToTry[i] > 200000))
3023  if (Pa_IsFormatSupported(NULL, &pars, RatesToTry[i]) == 0)
3024  supported.Add(RatesToTry[i]);
3025  }
3026 
3027  if (irate != 0 && supported.Index(irate) == wxNOT_FOUND)
3028  {
3029  // LLL: Remove when a proper method of determining actual supported
3030  // DirectSound rate is devised.
3031  if (!(isDirectSound && RatesToTry[i] > 200000))
3032  if (Pa_IsFormatSupported(NULL, &pars, irate) == 0)
3033  supported.Add(irate);
3034  }
3035 
3036  return supported;
3037 }
3038 
3039 wxArrayLong AudioIO::GetSupportedCaptureRates(int devIndex, double rate)
3040 {
3041  if (devIndex == -1)
3042  { // not given a device, look up in prefs / default
3043  devIndex = getRecordDevIndex();
3044  }
3045 
3046  // Check if we can use the cached rates
3047  if (mCachedCaptureIndex != -1 && devIndex == mCachedCaptureIndex
3048  && (rate == 0.0 || mCachedCaptureRates.Index(rate) != wxNOT_FOUND))
3049  {
3050  return mCachedCaptureRates;
3051  }
3052 
3053  wxArrayLong supported;
3054  int irate = (int)rate;
3055  const PaDeviceInfo* devInfo = NULL;
3056  int i;
3057 
3058  devInfo = Pa_GetDeviceInfo(devIndex);
3059 
3060  if (!devInfo)
3061  {
3062  wxLogDebug(wxT("GetSupportedCaptureRates() Could not get device info!"));
3063  return supported;
3064  }
3065 
3066  double latencyDuration = DEFAULT_LATENCY_DURATION;
3067  long recordChannels = 1;
3068  gPrefs->Read(wxT("/AudioIO/LatencyDuration"), &latencyDuration);
3069  gPrefs->Read(wxT("/AudioIO/RecordChannels"), &recordChannels);
3070 
3071  // LLL: Remove when a proper method of determining actual supported
3072  // DirectSound rate is devised.
3073  const PaHostApiInfo* hostInfo = Pa_GetHostApiInfo(devInfo->hostApi);
3074  bool isDirectSound = (hostInfo && hostInfo->type == paDirectSound);
3075 
3076  PaStreamParameters pars;
3077 
3078  pars.device = devIndex;
3079  pars.channelCount = recordChannels;
3080  pars.sampleFormat = paFloat32;
3081  pars.suggestedLatency = latencyDuration / 1000.0;
3082  pars.hostApiSpecificStreamInfo = NULL;
3083 
3084  for (i = 0; i < NumRatesToTry; i++)
3085  {
3086  // LLL: Remove when a proper method of determining actual supported
3087  // DirectSound rate is devised.
3088  if (!(isDirectSound && RatesToTry[i] > 200000))
3089  if (Pa_IsFormatSupported(&pars, NULL, RatesToTry[i]) == 0)
3090  supported.Add(RatesToTry[i]);
3091  }
3092 
3093  if (irate != 0 && supported.Index(irate) == wxNOT_FOUND)
3094  {
3095  // LLL: Remove when a proper method of determining actual supported
3096  // DirectSound rate is devised.
3097  if (!(isDirectSound && RatesToTry[i] > 200000))
3098  if (Pa_IsFormatSupported(&pars, NULL, irate) == 0)
3099  supported.Add(irate);
3100  }
3101 
3102  return supported;
3103 }
3104 
3105 wxArrayLong AudioIO::GetSupportedSampleRates(int playDevice, int recDevice, double rate)
3106 {
3107  // Not given device indices, look up prefs
3108  if (playDevice == -1) {
3109  playDevice = getPlayDevIndex();
3110  }
3111  if (recDevice == -1) {
3112  recDevice = getRecordDevIndex();
3113  }
3114 
3115  // Check if we can use the cached rates
3116  if (mCachedPlaybackIndex != -1 && mCachedCaptureIndex != -1 &&
3117  playDevice == mCachedPlaybackIndex &&
3118  recDevice == mCachedCaptureIndex &&
3119  (rate == 0.0 || mCachedSampleRates.Index(rate) != wxNOT_FOUND))
3120  {
3121  return mCachedSampleRates;
3122  }
3123 
3124  wxArrayLong playback = GetSupportedPlaybackRates(playDevice, rate);
3125  wxArrayLong capture = GetSupportedCaptureRates(recDevice, rate);
3126  int i;
3127 
3128  // Return only sample rates which are in both arrays
3129  wxArrayLong result;
3130 
3131  for (i = 0; i < (int)playback.GetCount(); i++)
3132  if (capture.Index(playback[i]) != wxNOT_FOUND)
3133  result.Add(playback[i]);
3134 
3135  // If this yields no results, use the default sample rates nevertheless
3136 /* if (result.IsEmpty())
3137  {
3138  for (i = 0; i < NumStandardRates; i++)
3139  result.Add(StandardRates[i]);
3140  }*/
3141 
3142  return result;
3143 }
3144 
3150 {
3151  wxArrayLong rates = GetSupportedSampleRates();
3152 
3153  if (rates.Index(44100) != wxNOT_FOUND)
3154  return 44100;
3155 
3156  if (rates.Index(48000) != wxNOT_FOUND)
3157  return 48000;
3158 
3159  // if there are no supported rates, the next bit crashes. So check first,
3160  // and give them a "sensible" value if there are no valid values. They
3161  // will still get an error later, but with any luck may have changed
3162  // something by then. It's no worse than having an invalid default rate
3163  // stored in the preferences, which we don't check for
3164  if (rates.IsEmpty()) return 44100;
3165 
3166  return rates[rates.GetCount() - 1];
3167 }
3168 
3169 double AudioIO::GetBestRate(bool capturing, bool playing, double sampleRate)
3170 {
3171  // Check if we can use the cached value
3172  if (mCachedBestRateIn != 0.0 && mCachedBestRateIn == sampleRate) {
3173  return mCachedBestRateOut;
3174  }
3175 
3176  // In order to cache the value, all early returns should instead set retval
3177  // and jump to finished
3178  double retval;
3179 
3180  wxArrayLong rates;
3181  if (capturing) wxLogDebug(wxT("AudioIO::GetBestRate() for capture"));
3182  if (playing) wxLogDebug(wxT("AudioIO::GetBestRate() for playback"));
3183  wxLogDebug(wxT("GetBestRate() suggested rate %.0lf Hz"), sampleRate);
3184 
3185  if (capturing && !playing) {
3186  rates = GetSupportedCaptureRates(-1, sampleRate);
3187  }
3188  else if (playing && !capturing) {
3189  rates = GetSupportedPlaybackRates(-1, sampleRate);
3190  }
3191  else { // we assume capturing and playing - the alternative would be a
3192  // bit odd
3193  rates = GetSupportedSampleRates(-1, -1, sampleRate);
3194  }
3195  /* rem rates is the array of hardware-supported sample rates (in the current
3196  * configuration), sampleRate is the Project Rate (desired sample rate) */
3197  long rate = (long)sampleRate;
3198 
3199  if (rates.Index(rate) != wxNOT_FOUND) {
3200  wxLogDebug(wxT("GetBestRate() Returning %.0ld Hz"), rate);
3201  retval = rate;
3202  goto finished;
3203  /* the easy case - the suggested rate (project rate) is in the list, and
3204  * we can just accept that and send back to the caller. This should be
3205  * the case for most users most of the time (all of the time on
3206  * Win MME as the OS does resampling) */
3207  }
3208 
3209  /* if we get here, there is a problem - the project rate isn't supported
3210  * on our hardware, so we can't us it. Need to come up with an alternative
3211  * rate to use. The process goes like this:
3212  * * If there are no rates to pick from, we're stuck and return 0 (error)
3213  * * If there are some rates, we pick the next one higher than the requested
3214  * rate to use.
3215  * * If there aren't any higher, we use the highest available rate */
3216 
3217  if (rates.IsEmpty()) {
3218  /* we're stuck - there are no supported rates with this hardware. Error */
3219  wxLogDebug(wxT("GetBestRate() Error - no supported sample rates"));
3220  retval = 0.0;
3221  goto finished;
3222  }
3223  int i;
3224  for (i = 0; i < (int)rates.GetCount(); i++) // for each supported rate
3225  {
3226  if (rates[i] > rate) {
3227  // supported rate is greater than requested rate
3228  wxLogDebug(wxT("GetBestRate() Returning next higher rate - %.0ld Hz"), rates[i]);
3229  retval = rates[i];
3230  goto finished;
3231  }
3232  }
3233 
3234  wxLogDebug(wxT("GetBestRate() Returning highest rate - %.0ld Hz"), rates[rates.GetCount() - 1]);
3235  retval = rates[rates.GetCount() - 1]; // the highest available rate
3236  goto finished;
3237 
3238 finished:
3239  mCachedBestRateIn = sampleRate;
3240  mCachedBestRateOut = retval;
3241  return retval;
3242 }
3243 
3244 
3246 //
3247 // Audio Thread Context
3248 //
3250 
3251 AudioThread::ExitCode AudioThread::Entry()
3252 {
3253  while( !TestDestroy() )
3254  {
3255  // Set LoopActive outside the tests to avoid race condition
3258  {
3259  gAudioIO->FillBuffers();
3261  }
3263  {
3264  gAudioIO->FillBuffers();
3265  }
3267 
3269  // Rely on the Wait() in ScrubQueue::Transformer()
3270  // This allows the scrubbing update interval to be made very short without
3271  // playback becoming intermittent.
3272  }
3273  else {
3274  // Perhaps this too could use a condition variable, for available space in the
3275  // ring buffer, instead of a polling loop? But no harm in doing it this way.
3276  Sleep(10);
3277  }
3278  }
3279 
3280  return 0;
3281 }
3282 
3283 
3284 #ifdef EXPERIMENTAL_MIDI_OUT
3285 MidiThread::ExitCode MidiThread::Entry()
3286 {
3287  while( !TestDestroy() )
3288  {
3289  // Set LoopActive outside the tests to avoid race condition
3290  gAudioIO->mMidiThreadFillBuffersLoopActive = true;
3291  if( gAudioIO->mMidiThreadFillBuffersLoopRunning &&
3292  // mNumFrames signals at least one callback, needed for MidiTime()
3293  gAudioIO->mNumFrames > 0)
3294  {
3295  gAudioIO->FillMidiBuffers();
3296  }
3297  gAudioIO->mMidiThreadFillBuffersLoopActive = false;
3298  Sleep(MIDI_SLEEP);
3299  }
3300  return 0;
3301 }
3302 #endif
3303 
3305 {
3306  auto commonlyAvail = mPlaybackBuffers[0]->AvailForPut();
3307  for (unsigned i = 1; i < mPlaybackTracks.size(); ++i)
3308  commonlyAvail = std::min(commonlyAvail,
3309  mPlaybackBuffers[i]->AvailForPut());
3310  return commonlyAvail;
3311 }
3312 
3314 {
3315  auto commonlyAvail = mCaptureBuffers[0]->AvailForGet();
3316  for (unsigned i = 1; i < mCaptureTracks.size(); ++i)
3317  commonlyAvail = std::min(commonlyAvail,
3318  mCaptureBuffers[i]->AvailForGet());
3319  return commonlyAvail;
3320 }
3321 
3322 #if USE_PORTMIXER
3323 int AudioIO::getRecordSourceIndex(PxMixer *portMixer)
3324 {
3325  int i;
3326  wxString sourceName = gPrefs->Read(wxT("/AudioIO/RecordingSource"), wxT(""));
3327  int numSources = Px_GetNumInputSources(portMixer);
3328  for (i = 0; i < numSources; i++) {
3329  if (sourceName == wxString(wxSafeConvertMB2WX(Px_GetInputSourceName(portMixer, i))))
3330  return i;
3331  }
3332  return -1;
3333 }
3334 #endif
3335 
3336 int AudioIO::getPlayDevIndex(const wxString &devNameArg)
3337 {
3338  wxString devName(devNameArg);
3339  // if we don't get given a device, look up the preferences
3340  if (devName.IsEmpty())
3341  {
3342  devName = gPrefs->Read(wxT("/AudioIO/PlaybackDevice"), wxT(""));
3343  }
3344 
3345  wxString hostName = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
3346  PaHostApiIndex hostCnt = Pa_GetHostApiCount();
3347  PaHostApiIndex hostNum;
3348  for (hostNum = 0; hostNum < hostCnt; hostNum++)
3349  {
3350  const PaHostApiInfo *hinfo = Pa_GetHostApiInfo(hostNum);
3351  if (hinfo && wxString(wxSafeConvertMB2WX(hinfo->name)) == hostName)
3352  {
3353  for (PaDeviceIndex hostDevice = 0; hostDevice < hinfo->deviceCount; hostDevice++)
3354  {
3355  PaDeviceIndex deviceNum = Pa_HostApiDeviceIndexToDeviceIndex(hostNum, hostDevice);
3356 
3357  const PaDeviceInfo *dinfo = Pa_GetDeviceInfo(deviceNum);
3358  if (dinfo && DeviceName(dinfo) == devName && dinfo->maxOutputChannels > 0 )
3359  {
3360  // this device name matches the stored one, and works.
3361  // So we say this is the answer and return it
3362  return deviceNum;
3363  }
3364  }
3365 
3366  // The device wasn't found so use the default for this host.
3367  // LL: At this point, preferences and active no longer match.
3368  return hinfo->defaultOutputDevice;
3369  }
3370  }
3371 
3372  // The host wasn't found, so use the default output device.
3373  // FIXME: TRAP_ERR PaErrorCode not handled well (this code is similar to input code
3374  // and the input side has more comments.)
3375 
3376  PaDeviceIndex deviceNum = Pa_GetDefaultOutputDevice();
3377 
3378  // Sometimes PortAudio returns -1 if it cannot find a suitable default
3379  // device, so we just use the first one available
3380  //
3381  // LL: At this point, preferences and active no longer match
3382  //
3383  // And I can't imagine how far we'll get specifying an "invalid" index later
3384  // on...are we certain "0" even exists?
3385  if (deviceNum < 0) {
3386  wxASSERT(false);
3387  deviceNum = 0;
3388  }
3389 
3390  return deviceNum;
3391 }
3392 
3393 int AudioIO::getRecordDevIndex(const wxString &devNameArg)
3394 {
3395  wxString devName(devNameArg);
3396  // if we don't get given a device, look up the preferences
3397  if (devName.IsEmpty())
3398  {
3399  devName = gPrefs->Read(wxT("/AudioIO/RecordingDevice"), wxT(""));
3400  }
3401 
3402  wxString hostName = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
3403  PaHostApiIndex hostCnt = Pa_GetHostApiCount();
3404  PaHostApiIndex hostNum;
3405  for (hostNum = 0; hostNum < hostCnt; hostNum++)
3406  {
3407  const PaHostApiInfo *hinfo = Pa_GetHostApiInfo(hostNum);
3408  if (hinfo && wxString(wxSafeConvertMB2WX(hinfo->name)) == hostName)
3409  {
3410  for (PaDeviceIndex hostDevice = 0; hostDevice < hinfo->deviceCount; hostDevice++)
3411  {
3412  PaDeviceIndex deviceNum = Pa_HostApiDeviceIndexToDeviceIndex(hostNum, hostDevice);
3413 
3414  const PaDeviceInfo *dinfo = Pa_GetDeviceInfo(deviceNum);
3415  if (dinfo && DeviceName(dinfo) == devName && dinfo->maxInputChannels > 0 )
3416  {
3417  // this device name matches the stored one, and works.
3418  // So we say this is the answer and return it
3419  return deviceNum;
3420  }
3421  }
3422 
3423  // The device wasn't found so use the default for this host.
3424  // LL: At this point, preferences and active no longer match.
3425  return hinfo->defaultInputDevice;
3426  }
3427  }
3428 
3429  // The host wasn't found, so use the default input device.
3430  // FIXME: TRAP_ERR PaErrorCode not handled well in getRecordDevIndex()
3431  PaDeviceIndex deviceNum = Pa_GetDefaultInputDevice();
3432 
3433  // Sometimes PortAudio returns -1 if it cannot find a suitable default
3434  // device, so we just use the first one available
3435  // PortAudio has an error reporting function. We should log/report the error?
3436  //
3437  // LL: At this point, preferences and active no longer match
3438  //
3439  // And I can't imagine how far we'll get specifying an "invalid" index later
3440  // on...are we certain "0" even exists?
3441  if (deviceNum < 0) {
3442  // JKC: This ASSERT will happen if you run with no config file
3443  // This happens once. Config file will exist on the next run.
3444  // TODO: Look into this a bit more. Could be relevant to blank Device Toolbar.
3445  wxASSERT(false);
3446  deviceNum = 0;
3447  }
3448 
3449  return deviceNum;
3450 }
3451 
3453 {
3454  wxStringOutputStream o;
3455  wxTextOutputStream s(o, wxEOL_UNIX);
3456  wxString e(wxT("\n"));
3457 
3458  if (IsStreamActive()) {
3459  return wxT("Stream is active ... unable to gather information.");
3460  }
3461 
3462 
3463  // FIXME: TRAP_ERR PaErrorCode not handled. 3 instances in GetDeviceInfo().
3464  int recDeviceNum = Pa_GetDefaultInputDevice();
3465  int playDeviceNum = Pa_GetDefaultOutputDevice();
3466  int cnt = Pa_GetDeviceCount();
3467 
3468  wxLogDebug(wxT("Portaudio reports %d audio devices"),cnt);
3469 
3470  s << wxT("==============================") << e;
3471  s << wxT("Default recording device number: ") << recDeviceNum << e;
3472  s << wxT("Default playback device number: ") << playDeviceNum << e;
3473 
3474  wxString recDevice = gPrefs->Read(wxT("/AudioIO/RecordingDevice"), wxT(""));
3475  wxString playDevice = gPrefs->Read(wxT("/AudioIO/PlaybackDevice"), wxT(""));
3476  int j;
3477 
3478  // This gets info on all available audio devices (input and output)
3479  if (cnt <= 0) {
3480  s << wxT("No devices found\n");
3481  return o.GetString();
3482  }
3483 
3484  const PaDeviceInfo* info;
3485 
3486  for (j = 0; j < cnt; j++) {
3487  s << wxT("==============================") << e;
3488 
3489  info = Pa_GetDeviceInfo(j);
3490  if (!info) {
3491  s << wxT("Device info unavailable for: ") << j << wxT("\n");
3492  continue;
3493  }
3494 
3495  wxString name = DeviceName(info);
3496  s << wxT("Device ID: ") << j << e;
3497  s << wxT("Device name: ") << name << e;
3498  s << wxT("Host name: ") << HostName(info) << e;
3499  s << wxT("Recording channels: ") << info->maxInputChannels << e;
3500  s << wxT("Playback channels: ") << info->maxOutputChannels << e;
3501  s << wxT("Low Recording Latency: ") << info->defaultLowInputLatency << e;
3502  s << wxT("Low Playback Latency: ") << info->defaultLowOutputLatency << e;
3503  s << wxT("High Recording Latency: ") << info->defaultHighInputLatency << e;
3504  s << wxT("High Playback Latency: ") << info->defaultHighOutputLatency << e;
3505 
3506  wxArrayLong rates = GetSupportedPlaybackRates(j, 0.0);
3507 
3508  s << wxT("Supported Rates:") << e;
3509  for (int k = 0; k < (int) rates.GetCount(); k++) {
3510  s << wxT(" ") << (int)rates[k] << e;
3511  }
3512 
3513  if (name == playDevice && info->maxOutputChannels > 0)
3514  playDeviceNum = j;
3515 
3516  if (name == recDevice && info->maxInputChannels > 0)
3517  recDeviceNum = j;
3518 
3519  // Sometimes PortAudio returns -1 if it cannot find a suitable default
3520  // device, so we just use the first one available
3521  if (recDeviceNum < 0 && info->maxInputChannels > 0){
3522  recDeviceNum = j;
3523  }
3524  if (playDeviceNum < 0 && info->maxOutputChannels > 0){
3525  playDeviceNum = j;
3526  }
3527  }
3528 
3529  bool haveRecDevice = (recDeviceNum >= 0);
3530  bool havePlayDevice = (playDeviceNum >= 0);
3531 
3532  s << wxT("==============================") << e;
3533  if(haveRecDevice){
3534  s << wxT("Selected recording device: ") << recDeviceNum << wxT(" - ") << recDevice << e;
3535  }else{
3536  s << wxT("No recording device found for '") << recDevice << wxT("'.") << e;
3537  }
3538  if(havePlayDevice){
3539  s << wxT("Selected playback device: ") << playDeviceNum << wxT(" - ") << playDevice << e;
3540  }else{
3541  s << wxT("No playback device found for '") << playDevice << wxT("'.") << e;
3542  }
3543 
3544  wxArrayLong supportedSampleRates;
3545 
3546  if(havePlayDevice && haveRecDevice){
3547  supportedSampleRates = GetSupportedSampleRates(playDeviceNum, recDeviceNum);
3548 
3549  s << wxT("Supported Rates:") << e;
3550  for (int k = 0; k < (int) supportedSampleRates.GetCount(); k++) {
3551  s << wxT(" ") << (int)supportedSampleRates[k] << e;
3552  }
3553  }else{
3554  s << wxT("Cannot check mutual sample rates without both devices.") << e;
3555  return o.GetString();
3556  }
3557 
3558 #if defined(USE_PORTMIXER)
3559  if (supportedSampleRates.GetCount() > 0)
3560  {
3561  int highestSampleRate = supportedSampleRates[supportedSampleRates.GetCount() - 1];
3562  bool EmulateMixerInputVol = true;
3563  bool EmulateMixerOutputVol = true;
3564  float MixerInputVol = 1.0;
3565  float MixerOutputVol = 1.0;
3566 
3567  int error;
3568 
3569  PaStream *stream;
3570 
3571  PaStreamParameters playbackParameters;
3572 
3573  playbackParameters.device = playDeviceNum;
3574  playbackParameters.sampleFormat = paFloat32;
3575  playbackParameters.hostApiSpecificStreamInfo = NULL;
3576  playbackParameters.channelCount = 1;
3577  if (Pa_GetDeviceInfo(playDeviceNum)){
3578  playbackParameters.suggestedLatency =
3579  Pa_GetDeviceInfo(playDeviceNum)->defaultLowOutputLatency;
3580  }
3581  else{
3582  playbackParameters.suggestedLatency = DEFAULT_LATENCY_CORRECTION/1000.0;
3583  }
3584 
3585  PaStreamParameters captureParameters;
3586 
3587  captureParameters.device = recDeviceNum;
3588  captureParameters.sampleFormat = paFloat32;;
3589  captureParameters.hostApiSpecificStreamInfo = NULL;
3590  captureParameters.channelCount = 1;
3591  if (Pa_GetDeviceInfo(recDeviceNum)){
3592  captureParameters.suggestedLatency =
3593  Pa_GetDeviceInfo(recDeviceNum)->defaultLowInputLatency;
3594  }else{
3595  captureParameters.suggestedLatency = DEFAULT_LATENCY_CORRECTION/1000.0;
3596  }
3597 
3598  error = Pa_OpenStream(&stream,
3599  &captureParameters, &playbackParameters,
3600  highestSampleRate, paFramesPerBufferUnspecified,
3601  paClipOff | paDitherOff,
3602  audacityAudioCallback, NULL);
3603 
3604  if (error) {
3605  error = Pa_OpenStream(&stream,
3606  &captureParameters, NULL,
3607  highestSampleRate, paFramesPerBufferUnspecified,
3608  paClipOff | paDitherOff,
3609  audacityAudioCallback, NULL);
3610  }
3611 
3612  if (error) {
3613  s << wxT("Received ") << error << wxT(" while opening devices") << e;
3614  return o.GetString();
3615  }
3616 
3617  PxMixer *PortMixer = Px_OpenMixer(stream, 0);
3618 
3619  if (!PortMixer) {
3620  s << wxT("Unable to open Portmixer") << e;
3621  Pa_CloseStream(stream);
3622  return o.GetString();
3623  }
3624 
3625  s << wxT("==============================") << e;
3626  s << wxT("Available mixers:") << e;
3627 
3628  // FIXME: ? PortMixer errors on query not reported in GetDeviceInfo
3629  cnt = Px_GetNumMixers(stream);
3630  for (int i = 0; i < cnt; i++) {
3631  wxString name = wxSafeConvertMB2WX(Px_GetMixerName(stream, i));
3632  s << i << wxT(" - ") << name << e;
3633  }
3634 
3635  s << wxT("==============================") << e;
3636  s << wxT("Available recording sources:") << e;
3637  cnt = Px_GetNumInputSources(PortMixer);
3638  for (int i = 0; i < cnt; i++) {
3639  wxString name = wxSafeConvertMB2WX(Px_GetInputSourceName(PortMixer, i));
3640  s << i << wxT(" - ") << name << e;
3641  }
3642 
3643  s << wxT("==============================") << e;
3644  s << wxT("Available playback volumes:") << e;
3645  cnt = Px_GetNumOutputVolumes(PortMixer);
3646  for (int i = 0; i < cnt; i++) {
3647  wxString name = wxSafeConvertMB2WX(Px_GetOutputVolumeName(PortMixer, i));
3648  s << i << wxT(" - ") << name << e;
3649  }
3650 
3651  // Determine mixer capabilities - it it doesn't support either
3652  // input or output, we emulate them (by multiplying this value
3653  // by all incoming/outgoing samples)
3654 
3655  MixerOutputVol = Px_GetPCMOutputVolume(PortMixer);
3656  EmulateMixerOutputVol = false;
3657  Px_SetPCMOutputVolume(PortMixer, 0.0);
3658  if (Px_GetPCMOutputVolume(PortMixer) > 0.1)
3659  EmulateMixerOutputVol = true;
3660  Px_SetPCMOutputVolume(PortMixer, 0.2f);
3661  if (Px_GetPCMOutputVolume(PortMixer) < 0.1 ||
3662  Px_GetPCMOutputVolume(PortMixer) > 0.3)
3663  EmulateMixerOutputVol = true;
3664  Px_SetPCMOutputVolume(PortMixer, MixerOutputVol);
3665 
3666  MixerInputVol = Px_GetInputVolume(PortMixer);
3667  EmulateMixerInputVol = false;
3668  Px_SetInputVolume(PortMixer, 0.0);
3669  if (Px_GetInputVolume(PortMixer) > 0.1)
3670  EmulateMixerInputVol = true;
3671  Px_SetInputVolume(PortMixer, 0.2f);
3672  if (Px_GetInputVolume(PortMixer) < 0.1 ||
3673  Px_GetInputVolume(PortMixer) > 0.3)
3674  EmulateMixerInputVol = true;
3675  Px_SetInputVolume(PortMixer, MixerInputVol);
3676 
3677  Pa_CloseStream(stream);
3678 
3679  s << wxT("==============================") << e;
3680  s << wxT("Recording volume is ") << (EmulateMixerInputVol? wxT("emulated"): wxT("native")) << e;
3681  s << wxT("Playback volume is ") << (EmulateMixerOutputVol? wxT("emulated"): wxT("native")) << e;
3682 
3683  Px_CloseMixer(PortMixer);
3684 
3685  } //end of massive if statement if a valid sample rate has been found
3686 #endif
3687  return o.GetString();
3688 }
3689 
3690 #ifdef EXPERIMENTAL_MIDI_OUT
3691 // FIXME: When EXPERIMENTAL_MIDI_IN is added (eventually) this should also be enabled -- Poke
3692 wxString AudioIO::GetMidiDeviceInfo()
3693 {
3694  wxStringOutputStream o;
3695  wxTextOutputStream s(o, wxEOL_UNIX);
3696  wxString e(wxT("\n"));
3697 
3698  if (IsStreamActive()) {
3699  return wxT("Stream is active ... unable to gather information.");
3700  }
3701 
3702 
3703  // XXX: May need to trap errors as with the normal device info
3704  int recDeviceNum = Pm_GetDefaultInputDeviceID();
3705  int playDeviceNum = Pm_GetDefaultOutputDeviceID();
3706  int cnt = Pm_CountDevices();
3707 
3708  wxLogDebug(wxT("PortMidi reports %d MIDI devices"), cnt);
3709 
3710  s << wxT("==============================") << e;
3711  s << wxT("Default recording device number: ") << recDeviceNum << e;
3712  s << wxT("Default playback device number: ") << playDeviceNum << e;
3713 
3714  wxString recDevice = gPrefs->Read(wxT("/MidiIO/RecordingDevice"), wxT(""));
3715  wxString playDevice = gPrefs->Read(wxT("/MidiIO/PlaybackDevice"), wxT(""));
3716 
3717  // This gets info on all available audio devices (input and output)
3718  if (cnt <= 0) {
3719  s << wxT("No devices found\n");
3720  return o.GetString();
3721  }
3722 
3723  for (int i = 0; i < cnt; i++) {
3724  s << wxT("==============================") << e;
3725 
3726  const PmDeviceInfo* info = Pm_GetDeviceInfo(i);
3727  if (!info) {
3728  s << wxT("Device info unavailable for: ") << i << e;
3729  continue;
3730  }
3731 
3732  wxString name = wxSafeConvertMB2WX(info->name);
3733  wxString hostName = wxSafeConvertMB2WX(info->interf);
3734 
3735  s << wxT("Device ID: ") << i << e;
3736  s << wxT("Device name: ") << name << e;
3737  s << wxT("Host name: ") << hostName << e;
3738  s << wxT("Supports output: ") << info->output << e;
3739  s << wxT("Supports input: ") << info->input << e;
3740  s << wxT("Opened: ") << info->opened << e;
3741 
3742  if (name == playDevice && info->output)
3743  playDeviceNum = i;
3744 
3745  if (name == recDevice && info->input)
3746  recDeviceNum = i;
3747 
3748  // XXX: This is only done because the same was applied with PortAudio
3749  // If PortMidi returns -1 for the default device, use the first one
3750  if (recDeviceNum < 0 && info->input){
3751  recDeviceNum = i;
3752  }
3753  if (playDeviceNum < 0 && info->output){
3754  playDeviceNum = i;
3755  }
3756  }
3757 
3758  bool haveRecDevice = (recDeviceNum >= 0);
3759  bool havePlayDevice = (playDeviceNum >= 0);
3760 
3761  s << wxT("==============================") << e;
3762  if (haveRecDevice) {
3763  s << wxT("Selected MIDI recording device: ") << recDeviceNum << wxT(" - ") << recDevice << e;
3764  } else {
3765  s << wxT("No MIDI recording device found for '") << recDevice << wxT("'.") << e;
3766  }
3767  if (havePlayDevice) {
3768  s << wxT("Selected MIDI playback device: ") << playDeviceNum << wxT(" - ") << playDevice << e;
3769  } else {
3770  s << wxT("No MIDI playback device found for '") << playDevice << wxT("'.") << e;
3771  }
3772 
3773  // Mention our conditional compilation flags for Alpha only
3774 #ifdef IS_ALPHA
3775 
3776  s << wxT("==============================") << e;
3777 #ifdef EXPERIMENTAL_MIDI_OUT
3778  s << wxT("EXPERIMENTAL_MIDI_OUT is enabled") << e;
3779 #else
3780  s << wxT("EXPERIMENTAL_MIDI_OUT is NOT enabled") << e;
3781 #endif
3782 #ifdef EXPERIMENTAL_MIDI_IN
3783  s << wxT("EXPERIMENTAL_MIDI_IN is enabled") << e;
3784 #else
3785  s << wxT("EXPERIMENTAL_MIDI_IN is NOT enabled") << e;
3786 #endif
3787 
3788 #endif
3789 
3790  return o.GetString();
3791 }
3792 #endif
3793 
3794 // This method is the data gateway between the audio thread (which
3795 // communicates with the disk) and the PortAudio callback thread
3796 // (which communicates with the audio device).
3798 {
3799  unsigned int i;
3800 
3801  auto delayedHandler = [this] ( AudacityException * pException ) {
3802  // In the main thread, stop recording
3803  // This is one place where the application handles disk
3804  // exhaustion exceptions from wave track operations, without rolling
3805  // back to the last pushed undo state. Instead, partial recording
3806  // results are pushed as a NEW undo state. For this reason, as
3807  // commented elsewhere, we want an exception safety guarantee for
3808  // the output wave tracks, after the failed append operation, that
3809  // the tracks remain as they were after the previous successful
3810  // (block-level) appends.
3811 
3812  // Note that the Flush in StopStream() may throw another exception,
3813  // but StopStream() contains that exception, and the logic in
3814  // AudacityException::DelayedHandlerAction prevents redundant message
3815  // boxes.
3816  StopStream();
3817  DefaultDelayedHandlerAction{}( pException );
3818  };
3819 
3820  if (mPlaybackTracks.size() > 0)
3821  {
3822  // Though extremely unlikely, it is possible that some buffers
3823  // will have more samples available than others. This could happen
3824  // if we hit this code during the PortAudio callback. To keep
3825  // things simple, we only write as much data as is vacant in
3826  // ALL buffers, and advance the global time by that much.
3827  // MB: subtract a few samples because the code below has rounding errors
3828  auto nAvailable = (int)GetCommonlyAvailPlayback() - 10;
3829 
3830  //
3831  // Don't fill the buffers at all unless we can do the
3832  // full mMaxPlaybackSecsToCopy. This improves performance
3833  // by not always trying to process tiny chunks, eating the
3834  // CPU unnecessarily.
3835  //
3836  // The exception is if we're at the end of the selected
3837  // region - then we should just fill the buffer.
3838  //
3839  if (nAvailable >= (int)mPlaybackSamplesToCopy ||
3840  (mPlayMode == PLAY_STRAIGHT &&
3841  nAvailable > 0 &&
3842  mWarpedTime+(nAvailable/mRate) >= mWarpedLength))
3843  {
3844  // Limit maximum buffer size (increases performance)
3845  auto available =
3846  std::min<size_t>( nAvailable, mPlaybackSamplesToCopy );
3847 
3848  // msmeyer: When playing a very short selection in looped
3849  // mode, the selection must be copied to the buffer multiple
3850  // times, to ensure, that the buffer has a reasonable size
3851  // This is the purpose of this loop.
3852  // PRL: or, when scrubbing, we may get work repeatedly from the
3853  // scrub queue.
3854  bool done = false;
3855  Maybe<wxMutexLocker> cleanup;
3856  do {
3857  // How many samples to produce for each channel.
3858  auto frames = available;
3859  bool progress = true;
3860 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
3861  if (mPlayMode == PLAY_SCRUB)
3862  // scrubbing does not use warped time and length
3863  frames = limitSampleBufferSize(frames, mScrubDuration);
3864  else
3865 #endif
3866  {
3867  double deltat = frames / mRate;
3868  if (mWarpedTime + deltat > mWarpedLength)
3869  {
3870  frames = (mWarpedLength - mWarpedTime) * mRate;
3871  // Don't fall into an infinite loop, if loop-playing a selection
3872  // that is so short, it has no samples: detect that case
3873  progress =
3874  !(mPlayMode == PLAY_LOOPED &&
3875  mWarpedTime == 0.0 && frames == 0);
3876  mWarpedTime = mWarpedLength;
3877  }
3878  else
3879  mWarpedTime += deltat;
3880  }
3881 
3882  if (!progress)
3883  frames = available;
3884 
3885  for (i = 0; i < mPlaybackTracks.size(); i++)
3886  {
3887  // The mixer here isn't actually mixing: it's just doing
3888  // resampling, format conversion, and possibly time track
3889  // warping
3890  decltype(mPlaybackMixers[i]->Process(frames))
3891  processed = 0;
3892  samplePtr warpedSamples;
3893  //don't do anything if we have no length. In particular, Process() will fail an wxAssert
3894  //that causes a crash since this is not the GUI thread and wxASSERT is a GUI call.
3895 
3896  // don't generate either if scrubbing at zero speed.
3897 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
3898  const bool silent = (mPlayMode == PLAY_SCRUB) && mSilentScrub;
3899 #else
3900  const bool silent = false;
3901 #endif
3902 
3903  if (progress && !silent && frames > 0)
3904  {
3905  processed = mPlaybackMixers[i]->Process(frames);
3906  wxASSERT(processed <= frames);
3907  warpedSamples = mPlaybackMixers[i]->GetBuffer();
3908  const auto put = mPlaybackBuffers[i]->Put
3909  (warpedSamples, floatSample, processed);
3910  // wxASSERT(put == processed);
3911  // but we can't assert in this thread
3912  wxUnusedVar(put);
3913  }
3914 
3915  //if looping and processed is less than the full chunk/block/buffer that gets pulled from
3916  //other longer tracks, then we still need to advance the ring buffers or
3917  //we'll trip up on ourselves when we start them back up again.
3918  //if not looping we never start them up again, so its okay to not do anything
3919  // If scrubbing, we may be producing some silence. Otherwise this should not happen,
3920  // but makes sure anyway that we produce equal
3921  // numbers of samples for all channels for this pass of the do-loop.
3922  if(processed < frames && mPlayMode != PLAY_STRAIGHT)
3923  {
3924  mSilentBuf.Resize(frames, floatSample);
3925  ClearSamples(mSilentBuf.ptr(), floatSample, 0, frames);
3926  const auto put = mPlaybackBuffers[i]->Put
3927  (mSilentBuf.ptr(), floatSample, frames - processed);
3928  // wxASSERT(put == frames - processed);
3929  // but we can't assert in this thread
3930  wxUnusedVar(put);
3931  }
3932  }
3933 
3934  available -= frames;
3935  wxASSERT(available >= 0);
3936 
3937  switch (mPlayMode)
3938  {
3939 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
3940  case PLAY_SCRUB:
3941  {
3942  mScrubDuration -= frames;
3943  wxASSERT(mScrubDuration >= 0);
3944  done = (available == 0);
3945  if (!done && mScrubDuration <= 0)
3946  {
3947  sampleCount startSample, endSample;
3948  mScrubQueue->Transformer(startSample, endSample, mScrubDuration, cleanup);
3949  if (mScrubDuration < 0)
3950  {
3951  // Can't play anything
3952  // Stop even if we don't fill up available
3953  mScrubDuration = 0;
3954  done = true;
3955  }
3956  else
3957  {
3958  mSilentScrub = (endSample == startSample);
3959  if (!mSilentScrub)
3960  {
3961  double startTime, endTime, speed;
3962  startTime = startSample.as_double() / mRate;
3963  endTime = endSample.as_double() / mRate;
3964  auto diff = (endSample - startSample).as_long_long();
3965  speed = double(std::abs(diff)) / mScrubDuration.as_double();
3966  for (i = 0; i < mPlaybackTracks.size(); i++)
3967  mPlaybackMixers[i]->SetTimesAndSpeed(startTime, endTime, speed);
3968  }
3969  }
3970  }
3971  }
3972  break;
3973 #endif
3974  case PLAY_LOOPED:
3975  {
3976  done = !progress || (available == 0);
3977  // msmeyer: If playing looped, check if we are at the end of the buffer
3978  // and if yes, restart from the beginning.
3979  if (mWarpedTime >= mWarpedLength)
3980  {
3981  for (i = 0; i < mPlaybackTracks.size(); i++)
3982  mPlaybackMixers[i]->Restart();
3983  mWarpedTime = 0.0;
3984  }
3985  }
3986  break;
3987  default:
3988  done = true;
3989  break;
3990  }
3991  } while (!done);
3992  }
3993  } // end of playback buffering
3994 
3995  if (!mRecordingException &&
3996  mCaptureTracks.size() > 0)
3997  GuardedCall( [&] {
3998  // start record buffering
3999  auto commonlyAvail = GetCommonlyAvailCapture();
4000 
4001  //
4002  // Determine how much this will add to captured tracks
4003  //
4004  double deltat = commonlyAvail / mRate;
4005 
4007  deltat >= mMinCaptureSecsToCopy)
4008  {
4009  // Append captured samples to the end of the WaveTracks.
4010  // The WaveTracks have their own buffering for efficiency.
4011  AutoSaveFile blockFileLog;
4012  auto numChannels = mCaptureTracks.size();
4013 
4014  for( i = 0; (int)i < numChannels; i++ )
4015  {
4016  auto avail = commonlyAvail;
4017  sampleFormat trackFormat = mCaptureTracks[i]->GetSampleFormat();
4018 
4019  AutoSaveFile appendLog;
4020 
4021  if( mFactor == 1.0 )
4022  {
4023  SampleBuffer temp(avail, trackFormat);
4024  const auto got =
4025  mCaptureBuffers[i]->Get(temp.ptr(), trackFormat, avail);
4026  // wxASSERT(got == avail);
4027  // but we can't assert in this thread
4028  wxUnusedVar(got);
4029  // see comment in second handler about guarantee
4030  mCaptureTracks[i]-> Append(temp.ptr(), trackFormat, avail, 1,
4031  &appendLog);
4032  }
4033  else
4034  {
4035  size_t size = lrint(avail * mFactor);
4036  SampleBuffer temp1(avail, floatSample);
4037  SampleBuffer temp2(size, floatSample);
4038  const auto got =
4039  mCaptureBuffers[i]->Get(temp1.ptr(), floatSample, avail);
4040  // wxASSERT(got == avail);
4041  // but we can't assert in this thread
4042  wxUnusedVar(got);
4043  /* we are re-sampling on the fly. The last resampling call
4044  * must flush any samples left in the rate conversion buffer
4045  * so that they get recorded
4046  */
4047  const auto results =
4048  mResample[i]->Process(mFactor, (float *)temp1.ptr(), avail,
4049  !IsStreamActive(), (float *)temp2.ptr(), size);
4050  size = results.second;
4051  // see comment in second handler about guarantee
4052  mCaptureTracks[i]-> Append(temp2.ptr(), floatSample, size, 1,
4053  &appendLog);
4054  }
4055 
4056  if (!appendLog.IsEmpty())
4057  {
4058  blockFileLog.StartTag(wxT("recordingrecovery"));
4059  blockFileLog.WriteAttr(wxT("id"), mCaptureTracks[i]->GetAutoSaveIdent());
4060  blockFileLog.WriteAttr(wxT("channel"), (int)i);
4061  blockFileLog.WriteAttr(wxT("numchannels"), numChannels);
4062  blockFileLog.WriteSubTree(appendLog);
4063  blockFileLog.EndTag(wxT("recordingrecovery"));
4064  }
4065  }
4066 
4067  if (mListener && !blockFileLog.IsEmpty())
4068  mListener->OnAudioIONewBlockFiles(blockFileLog);
4069  }
4070  // end of record buffering
4071  },
4072  // handler
4073  [this] ( AudacityException *pException ) {
4074  if ( pException ) {
4075  // So that we don't attempt to fill the recording buffer again
4076  // before the main thread stops recording
4078  return ;
4079  }
4080  else
4081  // Don't want to intercept other exceptions (?)
4082  throw;
4083  },
4084  delayedHandler
4085  );
4086 }
4087 
4089 {
4090  if (IsBusy())
4091  return;
4092 
4093  mListener = listener;
4094 }
4095 
4096 #ifdef EXPERIMENTAL_MIDI_OUT
4097 
4098 static Alg_update gAllNotesOff; // special event for loop ending
4099 // the fields of this event are never used, only the address is important
4100 
4101 double AudioIO::UncorrectedMidiEventTime()
4102 {
4103  double time;
4104  if (mTimeTrack)
4105  time =
4106  mTimeTrack->ComputeWarpedLength(mT0, mNextEventTime - MidiLoopOffset())
4107  + mT0 + (mMidiLoopPasses * mWarpedLength);
4108  else
4109  time = mNextEventTime;
4110 
4111  return time + PauseTime();
4112 }
4113 
4114 void AudioIO::OutputEvent()
4115 {
4116  int channel = (mNextEvent->chan) & 0xF; // must be in [0..15]
4117  int command = -1;
4118  int data1 = -1;
4119  int data2 = -1;
4120 
4121  double eventTime = UncorrectedMidiEventTime();
4122 
4123  // 0.0005 is for rounding
4124  double time = eventTime + 0.0005 -
4125  (mSynthLatency * 0.001);
4126 
4127  time += 1; // MidiTime() has a 1s offset
4128  // state changes have to go out without delay because the
4129  // midi stream time gets reset when playback starts, and
4130  // we don't want to leave any control changes scheduled for later
4131  if (time < 0 || mSendMidiState) time = 0;
4132  PmTimestamp timestamp = (PmTimestamp) (time * 1000); /* s to ms */
4133 
4134  // The special event gAllNotesOff means "end of playback, send
4135  // all notes off on all channels"
4136  if (mNextEvent == &gAllNotesOff) {
4137  bool looping = (mPlayMode == gAudioIO->PLAY_LOOPED);
4138  AllNotesOff(looping);
4139  if (looping) {
4140  // jump back to beginning of loop
4141  ++mMidiLoopPasses;
4142  PrepareMidiIterator(false, MidiLoopOffset());
4143  } else {
4144  mNextEvent = NULL;
4145  }
4146  return;
4147  }
4148 
4149  // if mNextEvent's channel is visible, play it, visibility can
4150  // be updated while playing. Be careful: if we have a note-off,
4151  // then we must not pay attention to the channel selection
4152  // or mute/solo buttons because we must turn the note off
4153  // even if the user changed something after the note began
4154  // Note that because multiple tracks can output to the same
4155  // MIDI channels, it is not a good idea to send "All Notes Off"
4156  // when the user presses the mute button. We have no easy way
4157  // to know what notes are sounding on any given muted track, so
4158  // we'll just wait for the note-off events to happen.
4159  // Also note that note-offs are only sent when we call
4160  // mIterator->request_note_off(), so notes that are not played
4161  // will note generate random note-offs. There is the interesting
4162  // case that if the playback is paused, all-notes-off WILL be sent
4163  // and if playback resumes, the pending note-off events WILL also
4164  // be sent (but if that is a problem, there would also be a problem
4165  // in the non-pause case.
4166  if (((mNextEventTrack->IsVisibleChan(channel)) &&
4167  // only play if note is not muted:
4168  !((mHasSolo || mNextEventTrack->GetMute()) &&
4169  !mNextEventTrack->GetSolo())) ||
4170  (mNextEvent->is_note() && !mNextIsNoteOn)) {
4171  // Note event
4172  if (mNextEvent->is_note() && !mSendMidiState) {
4173  // Pitch and velocity
4174  data1 = mNextEvent->get_pitch();
4175  if (mNextIsNoteOn) {
4176  data2 = mNextEvent->get_loud(); // get velocity
4177  int offset = mNextEventTrack->GetVelocity();
4178  data2 += offset; // offset comes from per-track slider
4179  // clip velocity to insure a legal note-on value
4180  data2 = (data2 < 1 ? 1 : (data2 > 127 ? 127 : data2));
4181  // since we are going to play this note, we need to get a note_off
4182  mIterator->request_note_off();
4183 
4184 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
4185  mPendingNotesOff.push_back(std::make_pair(channel, data1));
4186 #endif
4187  }
4188  else {
4189  data2 = 0; // 0 velocity means "note off"
4190 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
4191  auto end = mPendingNotesOff.end();
4192  auto iter = std::find(
4193  mPendingNotesOff.begin(), end, std::make_pair(channel, data1) );
4194  if (iter != end)
4195  mPendingNotesOff.erase(iter);
4196 #endif
4197  }
4198  command = 0x90; // MIDI NOTE ON (or OFF when velocity == 0)
4199  // Update event
4200  } else if (mNextEvent->is_update()) {
4201  // this code is based on allegrosmfwr.cpp -- it could be improved
4202  // by comparing attribute pointers instead of string compares
4203  Alg_update_ptr update = (Alg_update_ptr) mNextEvent;
4204  const char *name = update->get_attribute();
4205 
4206  if (!strcmp(name, "programi")) {
4207  // Instrument change
4208  data1 = update->parameter.i;
4209  data2 = 0;
4210  command = 0xC0; // MIDI PROGRAM CHANGE
4211  } else if (!strncmp(name, "control", 7)) {
4212  // Controller change
4213 
4214  // The number of the controller being changed is embedded
4215  // in the parameter name.
4216  data1 = atoi(name + 7);
4217  // Allegro normalizes controller values
4218  data2 = ROUND(update->parameter.r * 127);
4219  command = 0xB0;
4220  } else if (!strcmp(name, "bendr")) {
4221  // Bend change
4222 
4223  // Reverse Allegro's post-processing of bend values
4224  int temp = ROUND(0x2000 * (update->parameter.r + 1));
4225  if (temp > 0x3fff) temp = 0x3fff; // 14 bits maximum
4226  if (temp < 0) temp = 0;
4227  data1 = temp & 0x7f; // low 7 bits
4228  data2 = temp >> 7; // high 7 bits
4229  command = 0xE0; // MIDI PITCH BEND
4230  } else if (!strcmp(name, "pressurer")) {
4231  // Pressure change
4232  data1 = (int) (update->parameter.r * 127);
4233  if (update->get_identifier() < 0) {
4234  // Channel pressure
4235  data2 = 0;
4236  command = 0xD0; // MIDI CHANNEL PRESSURE
4237  } else {
4238  // Key pressure
4239  data2 = data1;
4240  data1 = update->get_identifier();
4241  command = 0xA0; // MIDI POLY PRESSURE
4242  }
4243  }
4244  }
4245  if (command != -1) {
4246  // keep track of greatest timestamp used
4247  if (timestamp > mMaxMidiTimestamp) {
4248  mMaxMidiTimestamp = timestamp;
4249  }
4250  Pm_WriteShort(mMidiStream, timestamp,
4251  Pm_Message((int) (command + channel),
4252  (long) data1, (long) data2));
4253  /* wxPrintf("Pm_WriteShort %lx (%p) @ %d, advance %d\n",
4254  Pm_Message((int) (command + channel),
4255  (long) data1, (long) data2),
4256  mNextEvent, timestamp, timestamp - Pt_Time()); */
4257  }
4258  }
4259 }
4260 
4261 void AudioIO::GetNextEvent()
4262 {
4263  mNextEventTrack = NULL; // clear it just to be safe
4264  // now get the next event and the track from which it came
4265  double nextOffset;
4266  if (!mIterator) {
4267  mNextEvent = NULL;
4268  return;
4269  }
4270  auto midiLoopOffset = MidiLoopOffset();
4271  mNextEvent = mIterator->next(&mNextIsNoteOn,
4272  (void **) &mNextEventTrack,
4273  &nextOffset, mT1 + midiLoopOffset);
4274 
4275  mNextEventTime = mT1 + midiLoopOffset + 1;
4276  if (mNextEvent) {
4277  mNextEventTime = (mNextIsNoteOn ? mNextEvent->time :
4278  mNextEvent->get_end_time()) + nextOffset;;
4279  }
4280  if (mNextEventTime > (mT1 + midiLoopOffset)){ // terminate playback at mT1
4281  mNextEvent = &gAllNotesOff;
4282  mNextEventTime = mT1 + midiLoopOffset - ALG_EPS;
4283  mNextIsNoteOn = true; // do not look at duration
4284  mIterator->end();
4285  mIterator.reset(); // debugging aid
4286  }
4287 }
4288 
4289 
4290 bool AudioIO::SetHasSolo(bool hasSolo)
4291 {
4292  mHasSolo = hasSolo;
4293  return mHasSolo;
4294 }
4295 
4296 
4297 void AudioIO::FillMidiBuffers()
4298 {
4299  // Keep track of time paused. If not paused, fill buffers.
4300  if (gAudioIO->IsPaused()) {
4301  if (!gAudioIO->mMidiPaused) {
4302  gAudioIO->mMidiPaused = true;
4303  gAudioIO->AllNotesOff(); // to avoid hanging notes during pause
4304  }
4305  return;
4306  }
4307 
4308  if (gAudioIO->mMidiPaused) {
4309  gAudioIO->mMidiPaused = false;
4310  }
4311 
4312  bool hasSolo = false;
4313  auto numPlaybackTracks = gAudioIO->mPlaybackTracks.size();
4314  for(unsigned t = 0; t < numPlaybackTracks; t++ )
4315  if( gAudioIO->mPlaybackTracks[t]->GetSolo() ) {
4316  hasSolo = true;
4317  break;
4318  }
4319  auto numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
4320  for(unsigned t = 0; t < numMidiPlaybackTracks; t++ )
4321  if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() ) {
4322  hasSolo = true;
4323  break;
4324  }
4325  SetHasSolo(hasSolo);
4326  // If we compute until mNextEventTime > current audio track time,
4327  // we would have a built-in compute-ahead of mAudioOutLatency, and
4328  // it's probably good to compute MIDI when we compute audio (so when
4329  // we stop, both stop about the same time).
4330  double time = AudioTime(); // compute to here
4331  // But if mAudioOutLatency is very low, we might need some extra
4332  // compute-ahead to deal with mSynthLatency or even this thread.
4333  double actual_latency = (MIDI_SLEEP + THREAD_LATENCY +
4334  MIDI_MINIMAL_LATENCY_MS + mSynthLatency) * 0.001;
4335  if (actual_latency > mAudioOutLatency) {
4336  time += actual_latency - mAudioOutLatency;
4337  }
4338  while (mNextEvent &&
4339  UncorrectedMidiEventTime() < time) {
4340  OutputEvent();
4341  GetNextEvent();
4342  }
4343 
4344  // test for end
4345  double realTime = gAudioIO->MidiTime() * 0.001 -
4346  gAudioIO->PauseTime();
4347  realTime -= 1; // MidiTime() runs ahead 1s
4348 
4349  // XXX Is this still true now? It seems to break looping --Poke
4350  //
4351  // The TrackPanel::OnTimer() method updates the time position
4352  // indicator every 200ms, so it tends to not advance the
4353  // indicator to the end of the selection (mT1) but instead stop
4354  // up to 200ms before the end. At this point, output is shut
4355  // down and the indicator is removed, but for a brief time, the
4356  // indicator is clearly stopped before reaching mT1. To avoid
4357  // this, we do not set mMidiOutputComplete until we are actually
4358  // 0.22s beyond mT1 (even though we stop playing at mT1). This
4359  // gives OnTimer() time to wake up and draw the final time
4360  // position at mT1 before shutting down the stream.
4361  const double loopDelay = 0.220;
4362 
4363  double timeAtSpeed;
4364  if (gAudioIO->mTimeTrack)
4365  timeAtSpeed = gAudioIO->mTimeTrack->SolveWarpedLength(gAudioIO->mT0, realTime);
4366  else
4367  timeAtSpeed = realTime;
4368 
4369  gAudioIO->mMidiOutputComplete =
4370  (gAudioIO->mPlayMode == gAudioIO->PLAY_STRAIGHT && // PRL: what if scrubbing?
4371  timeAtSpeed >= gAudioIO->mT1 + loopDelay);
4372  // !gAudioIO->mNextEvent);
4373 }
4374 
4375 double AudioIO::PauseTime()
4376 {
4377  return mNumPauseFrames / mRate;
4378 }
4379 
4380 
4381 // MidiTime() is an estimate in milliseconds of the current audio
4382 // output (DAC) time + 1s. In other words, what audacity track time
4383 // corresponds to the audio (including pause insertions) at the output?
4384 //
4385 PmTimestamp AudioIO::MidiTime()
4386 {
4387  // note: the extra 0.0005 is for rounding. Round down by casting to
4388  // unsigned long, then convert to PmTimeStamp (currently signed)
4389 
4390  // PRL: the time correction is really Midi latency achieved by different
4391  // means than specifying it to Pm_OpenStream. The use of the accumulated
4392  // sample count generated by the audio callback (in AudioTime()) might also
4393  // have the virtue of keeping the Midi output synched with audio.
4394 
4395  PmTimestamp ts;
4396  // subtract latency here because mSystemMinusAudioTime gets us
4397  // to the current *write* time, but we're writing ahead by audio output
4398  // latency (mAudioOutLatency).
4399  double now = SystemTime(mUsingAlsa);
4400  ts = (PmTimestamp) ((unsigned long)
4401  (1000 * (now + 1.0005 -
4402  mSystemMinusAudioTimePlusLatency)));
4403  // wxPrintf("AudioIO::MidiTime() %d time %g sys-aud %g\n",
4404  // ts, now, mSystemMinusAudioTime);
4405  return ts + MIDI_MINIMAL_LATENCY_MS;
4406 }
4407 
4408 
4409 void AudioIO::AllNotesOff(bool looping)
4410 {
4411 #ifdef __WXGTK__
4412  bool doDelay = !looping;
4413 #else
4414  bool doDelay = false;
4415  looping;// compiler food.
4416 #endif
4417 
4418  // to keep track of when MIDI should all be delivered,
4419  // update mMaxMidiTimestamp to now:
4420  PmTimestamp now = MidiTime();
4421  if (mMaxMidiTimestamp < now) {
4422  mMaxMidiTimestamp = now;
4423  }
4424 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
4425  // PRL:
4426  // Send individual note-off messages for each note-on not yet paired.
4427 
4428  // RBD:
4429  // Even this did not work as planned. My guess is ALSA does not use
4430  // a "stable sort" for timed messages, so that when a note-off is
4431  // added later at the same time as a future note-on, the order is
4432  // not respected, and the note-off can go first, leaving a stuck note.
4433  // The workaround here is to use mMaxMidiTimestamp to ensure that
4434  // note-offs come at least 1ms later than any previous message
4435 
4436  // PRL:
4437  // I think we should do that only when stopping or pausing, not when looping
4438  // Note that on Linux, MIDI always uses ALSA, no matter whether portaudio
4439  // uses some other host api.
4440 
4441  mMaxMidiTimestamp += 1;
4442  for (const auto &pair : mPendingNotesOff) {
4443  Pm_WriteShort(mMidiStream,
4444  (doDelay ? mMaxMidiTimestamp : 0),
4445  Pm_Message(
4446  0x90 + pair.first, pair.second, 0));
4447  mMaxMidiTimestamp++; // allow 1ms per note-off
4448  }
4449  mPendingNotesOff.clear();
4450 
4451  // Proceed to do the usual messages too.
4452 #endif
4453 
4454  for (int chan = 0; chan < 16; chan++) {
4455  Pm_WriteShort(mMidiStream,
4456  (doDelay ? mMaxMidiTimestamp : 0),
4457  Pm_Message(0xB0 + chan, 0x7B, 0));
4458  mMaxMidiTimestamp++; // allow 1ms per all-notes-off
4459  }
4460 }
4461 
4462 #endif
4463 
4464 // Automated Input Level Adjustment - Automatically tries to find an acceptable input volume
4465 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
4466 void AudioIO::AILAInitialize() {
4467  gPrefs->Read(wxT("/AudioIO/AutomatedInputLevelAdjustment"), &mAILAActive, false);
4468  gPrefs->Read(wxT("/AudioIO/TargetPeak"), &mAILAGoalPoint, AILA_DEF_TARGET_PEAK);
4469  gPrefs->Read(wxT("/AudioIO/DeltaPeakVolume"), &mAILAGoalDelta, AILA_DEF_DELTA_PEAK);
4470  gPrefs->Read(wxT("/AudioIO/AnalysisTime"), &mAILAAnalysisTime, AILA_DEF_ANALYSIS_TIME);
4471  gPrefs->Read(wxT("/AudioIO/NumberAnalysis"), &mAILATotalAnalysis, AILA_DEF_NUMBER_ANALYSIS);
4472  mAILAGoalDelta /= 100.0;
4473  mAILAGoalPoint /= 100.0;
4474  mAILAAnalysisTime /= 1000.0;
4475  mAILAMax = 0.0;
4476  mAILALastStartTime = max(0.0, mT0);
4477  mAILAClipped = false;
4478  mAILAAnalysisCounter = 0;
4479  mAILAChangeFactor = 1.0;
4480  mAILALastChangeType = 0;
4481  mAILATopLevel = 1.0;
4482  mAILAAnalysisEndTime = -1.0;
4483 }
4484 
4485 void AudioIO::AILADisable() {
4486  mAILAActive = false;
4487 }
4488 
4489 bool AudioIO::AILAIsActive() {
4490  return mAILAActive;
4491 }
4492 
4493 void AudioIO::AILASetStartTime() {
4494  mAILAAbsolutStartTime = Pa_GetStreamTime(mPortStreamV19);
4495  wxPrintf("START TIME %f\n\n", mAILAAbsolutStartTime);
4496 }
4497 
4498 double AudioIO::AILAGetLastDecisionTime() {
4499  return mAILAAnalysisEndTime;
4500 }
4501 
4502 void AudioIO::AILAProcess(double maxPeak) {
4504  if (proj && mAILAActive) {
4505  if (mInputMeter->IsClipping()) {
4506  mAILAClipped = true;
4507  wxPrintf("clipped");
4508  }
4509 
4510  mAILAMax = max(mAILAMax, maxPeak);
4511 
4512  if ((mAILATotalAnalysis == 0 || mAILAAnalysisCounter < mAILATotalAnalysis) && mTime - mAILALastStartTime >= mAILAAnalysisTime) {
4513  putchar('\n');
4514  mAILAMax = mInputMeter->ToLinearIfDB(mAILAMax);
4515  double iv = (double) Px_GetInputVolume(mPortMixer);
4516  unsigned short changetype = 0; //0 - no change, 1 - increase change, 2 - decrease change
4517  wxPrintf("mAILAAnalysisCounter:%d\n", mAILAAnalysisCounter);
4518  wxPrintf("\tmAILAClipped:%d\n", mAILAClipped);
4519  wxPrintf("\tmAILAMax (linear):%f\n", mAILAMax);
4520  wxPrintf("\tmAILAGoalPoint:%f\n", mAILAGoalPoint);
4521  wxPrintf("\tmAILAGoalDelta:%f\n", mAILAGoalDelta);
4522  wxPrintf("\tiv:%f\n", iv);
4523  wxPrintf("\tmAILAChangeFactor:%f\n", mAILAChangeFactor);
4524  if (mAILAClipped || mAILAMax > mAILAGoalPoint + mAILAGoalDelta) {
4525  wxPrintf("too high:\n");
4526  mAILATopLevel = min(mAILATopLevel, iv);
4527  wxPrintf("\tmAILATopLevel:%f\n", mAILATopLevel);
4528  //if clipped or too high
4529  if (iv <= LOWER_BOUND) {
4530  //we can't improve it more now
4531  if (mAILATotalAnalysis != 0) {
4532  mAILAActive = false;
4533  proj->TP_DisplayStatusMessage(_("Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too high."));
4534  }
4535  wxPrintf("\talready min vol:%f\n", iv);
4536  }
4537  else {
4538  float vol = (float) max(LOWER_BOUND, iv+(mAILAGoalPoint-mAILAMax)*mAILAChangeFactor);
4539  Px_SetInputVolume(mPortMixer, vol);
4540  wxString msg;
4541  msg.Printf(_("Automated Recording Level Adjustment decreased the volume to %f."), vol);
4542  proj->TP_DisplayStatusMessage(msg);
4543  changetype = 1;
4544  wxPrintf("\tnew vol:%f\n", vol);
4545  float check = Px_GetInputVolume(mPortMixer);
4546  wxPrintf("\tverified %f\n", check);
4547  }
4548  }
4549  else if ( mAILAMax < mAILAGoalPoint - mAILAGoalDelta ) {
4550  //if too low
4551  wxPrintf("too low:\n");
4552  if (iv >= UPPER_BOUND || iv + 0.005 > mAILATopLevel) { //condition for too low volumes and/or variable volumes that cause mAILATopLevel to decrease too much
4553  //we can't improve it more
4554  if (mAILATotalAnalysis != 0) {
4555  mAILAActive = false;
4556  proj->TP_DisplayStatusMessage(_("Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too low."));
4557  }
4558  wxPrintf("\talready max vol:%f\n", iv);
4559  }
4560  else {
4561  float vol = (float) min(UPPER_BOUND, iv+(mAILAGoalPoint-mAILAMax)*mAILAChangeFactor);
4562  if (vol > mAILATopLevel) {
4563  vol = (iv + mAILATopLevel)/2.0;
4564  wxPrintf("\tTruncated vol:%f\n", vol);
4565  }
4566  Px_SetInputVolume(mPortMixer, vol);
4567  wxString msg;
4568  msg.Printf(_("Automated Recording Level Adjustment increased the volume to %.2f."), vol);
4569  proj->TP_DisplayStatusMessage(msg);
4570  changetype = 2;
4571  wxPrintf("\tnew vol:%f\n", vol);
4572  float check = Px_GetInputVolume(mPortMixer);
4573  wxPrintf("\tverified %f\n", check);
4574  }
4575  }
4576 
4577  mAILAAnalysisCounter++;
4578  //const PaStreamInfo* info = Pa_GetStreamInfo(mPortStreamV19);
4579  //double latency = 0.0;
4580  //if (info)
4581  // latency = info->inputLatency;
4582  //mAILAAnalysisEndTime = mTime+latency;
4583  mAILAAnalysisEndTime = Pa_GetStreamTime(mPortStreamV19) - mAILAAbsolutStartTime;
4584  mAILAMax = 0;
4585  wxPrintf("\tA decision was made @ %f\n", mAILAAnalysisEndTime);
4586  mAILAClipped = false;
4587  mAILALastStartTime = mTime;
4588 
4589  if (changetype == 0)
4590  mAILAChangeFactor *= 0.8; //time factor
4591  else if (mAILALastChangeType == changetype)
4592  mAILAChangeFactor *= 1.1; //concordance factor
4593  else
4594  mAILAChangeFactor *= 0.7; //discordance factor
4595  mAILALastChangeType = changetype;
4596  putchar('\n');
4597  }
4598 
4599  if (mAILAActive && mAILATotalAnalysis != 0 && mAILAAnalysisCounter >= mAILATotalAnalysis) {
4600  mAILAActive = false;
4601  if (mAILAMax > mAILAGoalPoint + mAILAGoalDelta)
4602  proj->TP_DisplayStatusMessage(_("Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too high."));
4603  else if (mAILAMax < mAILAGoalPoint - mAILAGoalDelta)
4604  proj->TP_DisplayStatusMessage(_("Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too low."));
4605  else {
4606  wxString msg;
4607  msg.Printf(_("Automated Recording Level Adjustment stopped. %.2f seems an acceptable volume."), Px_GetInputVolume(mPortMixer));
4608  proj->TP_DisplayStatusMessage(msg);
4609  }
4610  }
4611  }
4612 }
4613 #endif
4614 
4616 //
4617 // PortAudio callback thread context
4618 //
4620 
4621 #define MAX(a,b) ((a) > (b) ? (a) : (b))
4622 
4623 static void DoSoftwarePlaythrough(const void *inputBuffer,
4624  sampleFormat inputFormat,
4625  unsigned inputChannels,
4626  float *outputBuffer,
4627  int len)
4628 {
4629  for (unsigned int i=0; i < inputChannels; i++) {
4630  samplePtr inputPtr = ((samplePtr)inputBuffer) + (i * SAMPLE_SIZE(inputFormat));
4631  samplePtr outputPtr = ((samplePtr)outputBuffer) + (i * SAMPLE_SIZE(floatSample));
4632 
4633  CopySamples(inputPtr, inputFormat,
4634  (samplePtr)outputPtr, floatSample,
4635  len, true, inputChannels, 2);
4636  }
4637 
4638  // One mono input channel goes to both output channels...
4639  if (inputChannels == 1)
4640  for (int i=0; i < len; i++)
4641  outputBuffer[2*i + 1] = outputBuffer[2*i];
4642 }
4643 
4644 int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
4645  unsigned long framesPerBuffer,
4646 // If there were more of these conditionally used arguments, it
4647 // could make sense to make a NEW macro that looks like this:
4648 // USEDIF( EXPERIMENTAL_MIDI_OUT, timeInfo )
4649 #ifdef EXPERIMENTAL_MIDI_OUT
4650  const PaStreamCallbackTimeInfo *timeInfo,
4651 #else
4652  const PaStreamCallbackTimeInfo * WXUNUSED(timeInfo),
4653 #endif
4654  const PaStreamCallbackFlags statusFlags, void * WXUNUSED(userData) )
4655 {
4656  auto numPlaybackChannels = gAudioIO->mNumPlaybackChannels;
4657  auto numPlaybackTracks = gAudioIO->mPlaybackTracks.size();
4658  auto numCaptureChannels = gAudioIO->mNumCaptureChannels;
4659  int callbackReturn = paContinue;
4660  void *tempBuffer = alloca(framesPerBuffer*sizeof(float)*
4661  MAX(numCaptureChannels,numPlaybackChannels));
4662  float *tempFloats = (float*)tempBuffer;
4663 
4664  // output meter may need samples untouched by volume emulation
4665  float *outputMeterFloats;
4666  outputMeterFloats =
4667  (outputBuffer && gAudioIO->mEmulateMixerOutputVol &&
4668  gAudioIO->mMixerOutputVol != 1.0) ?
4669  (float *)alloca(framesPerBuffer*numPlaybackChannels * sizeof(float)) :
4670  (float *)outputBuffer;
4671 
4672  if (gAudioIO->mCallbackCount++ == 0) {
4673  // This is effectively mSystemMinusAudioTime when the buffer is empty:
4674  gAudioIO->mStartTime = SystemTime(gAudioIO->mUsingAlsa) - gAudioIO->mT0;
4675  // later, mStartTime - mSystemMinusAudioTime will tell us latency
4676  }
4677 
4678 #ifdef EXPERIMENTAL_MIDI_OUT
4679  /* GSW: Save timeInfo in case MidiPlayback needs it */
4680  gAudioIO->mAudioCallbackClockTime = PaUtil_GetTime();
4681 
4682  /* for Linux, estimate a smooth audio time as a slowly-changing
4683  offset from system time */
4684  // rnow is system time as a double to simplify math
4685  double rnow = SystemTime(gAudioIO->mUsingAlsa);
4686  // anow is next-sample-to-be-computed audio time as a double
4687  double anow = gAudioIO->AudioTime();
4688 
4689  if (gAudioIO->mUsingAlsa) {
4690  // timeInfo's fields are not all reliable.
4691 
4692  // enow is audio time estimated from our clock synchronization protocol,
4693  // which produces mSystemMinusAudioTime. But we want the estimate
4694  // to drift low, so we steadily increase mSystemMinusAudioTime to
4695  // simulate a fast system clock or a slow audio clock. If anow > enow,
4696  // we'll update mSystemMinusAudioTime to keep in sync. (You might think
4697  // we could just use anow as the "truth", but it has a lot of jitter,
4698  // so we are using enow to smooth out this jitter, in fact to < 1ms.)
4699  // Add worst-case clock drift using previous framesPerBuffer:
4700  const auto increase =
4701  gAudioIO->mAudioFramesPerBuffer * 0.0002 / gAudioIO->mRate;
4702  gAudioIO->mSystemMinusAudioTime += increase;
4703  gAudioIO->mSystemMinusAudioTimePlusLatency += increase;
4704  double enow = rnow - gAudioIO->mSystemMinusAudioTime;
4705 
4706 
4707  // now, use anow instead if it is ahead of enow
4708  if (anow > enow) {
4709  gAudioIO->mSystemMinusAudioTime = rnow - anow;
4710  // Update our mAudioOutLatency estimate during the first 20 callbacks.
4711  // During this period, the buffer should fill. Once we have a good
4712  // estimate of mSystemMinusAudioTime (expected in fewer than 20 callbacks)
4713  // we want to stop the updating in case there is clock drift, which would
4714  // cause the mAudioOutLatency estimation to drift as well. The clock drift
4715  // in the first 20 callbacks should be negligible, however.
4716  if (gAudioIO->mCallbackCount < 20) {
4717  gAudioIO->mAudioOutLatency = gAudioIO->mStartTime -
4718  gAudioIO->mSystemMinusAudioTime;
4719  }
4720  gAudioIO->mSystemMinusAudioTimePlusLatency =
4721  gAudioIO->mSystemMinusAudioTime + gAudioIO->mAudioOutLatency;
4722  }
4723  }
4724  else {
4725  // If not using Alsa, rely on timeInfo to have meaningful values that are
4726  // more precise than the output latency value reported at stream start.
4727  gAudioIO->mSystemMinusAudioTime = rnow - anow;
4728  gAudioIO->mSystemMinusAudioTimePlusLatency =
4729  gAudioIO->mSystemMinusAudioTime +
4730  (timeInfo->outputBufferDacTime - timeInfo->currentTime);
4731  }
4732 
4733  gAudioIO->mAudioFramesPerBuffer = framesPerBuffer;
4734  if (gAudioIO->IsPaused()
4735  // PRL: Why was this added? Was it only because of the mysterious
4736  // initial leading zeroes, now solved by setting mStreamToken early?
4737  || gAudioIO->mStreamToken <= 0
4738  )
4739  gAudioIO->mNumPauseFrames += framesPerBuffer;
4740 
4741  // PRL: Note that when there is a separate MIDI thread, it is effectively
4742  // blocked until the first visit to this line during a playback, and will
4743  // not read gAudioIO->mSystemMinusAudioTimePlusLatency sooner:
4744  gAudioIO->mNumFrames += framesPerBuffer;
4745 
4746 #ifndef USE_MIDI_THREAD
4747  if (gAudioIO->mMidiStream)
4748  gAudioIO->FillMidiBuffers();
4749 #endif
4750 
4751 #endif
4752 
4753  unsigned int i;
4754 
4755  /* Send data to recording VU meter if applicable */
4756 
4757  if (gAudioIO->mInputMeter &&
4759  inputBuffer) {
4760  // get here if meters are actually live , and being updated
4761  /* It's critical that we don't update the meters while StopStream is
4762  * trying to stop PortAudio, otherwise it can lead to a freeze. We use
4763  * two variables to synchronize:
4764  * mUpdatingMeters tells StopStream when the callback is about to enter
4765  * the code where it might update the meters, and
4766  * mUpdateMeters is how the rest of the code tells the callback when it
4767  * is allowed to actually do the updating.
4768  * Note that mUpdatingMeters must be set first to avoid a race condition.
4769  */
4770  gAudioIO->mUpdatingMeters = true;
4771  if (gAudioIO->mUpdateMeters) {
4772  if (gAudioIO->mCaptureFormat == floatSample)
4773  gAudioIO->mInputMeter->UpdateDisplay(numCaptureChannels,
4774  framesPerBuffer,
4775  (float *)inputBuffer);
4776  else {
4777  CopySamples((samplePtr)inputBuffer, gAudioIO->mCaptureFormat,
4778  (samplePtr)tempFloats, floatSample,
4779  framesPerBuffer * numCaptureChannels);
4780  gAudioIO->mInputMeter->UpdateDisplay(numCaptureChannels,
4781  framesPerBuffer,
4782  tempFloats);
4783  }
4784  }
4785  gAudioIO->mUpdatingMeters = false;
4786  } // end recording VU meter update
4787 
4788  // Stop recording if 'silence' is detected
4789  //
4790  // LL: We'd gotten a little "dangerous" with the control toolbar calls
4791  // here because we are not running in the main GUI thread. Eventually
4792  // the toolbar attempts to update the active project's status bar.
4793  // But, since we're not in the main thread, we can get all manner of
4794  // really weird failures. Or none at all which is even worse, since
4795  // we don't know a problem exists.
4796  //
4797  // By using CallAfter(), we can schedule the call to the toolbar
4798  // to run in the main GUI thread after the next event loop iteration.
4799  if(gAudioIO->mPauseRec && inputBuffer && gAudioIO->mInputMeter) {
4801  if(!gAudioIO->IsPaused()) {
4803  ControlToolBar *bar = p->GetControlToolBar();
4804  bar->CallAfter(&ControlToolBar::Pause);
4805  }
4806  }
4807  else {
4808  if(gAudioIO->IsPaused()) {
4810  ControlToolBar *bar = p->GetControlToolBar();
4811  bar->CallAfter(&ControlToolBar::Pause);
4812  }
4813  }
4814  }
4815  if( gAudioIO->mPaused )
4816  {
4817  if (outputBuffer && numPlaybackChannels > 0)
4818  {
4819  ClearSamples((samplePtr)outputBuffer, floatSample,
4820  0, framesPerBuffer * numPlaybackChannels);
4821 
4822  if (inputBuffer && gAudioIO->mSoftwarePlaythrough) {
4824  numCaptureChannels,
4825  (float *)outputBuffer, (int)framesPerBuffer);
4826  }
4827  }
4828 
4829  return paContinue;
4830  }
4831 
4832  if (gAudioIO->mStreamToken > 0)
4833  {
4834  //
4835  // Mix and copy to PortAudio's output buffer
4836  //
4837 
4838  if( outputBuffer && (numPlaybackChannels > 0) )
4839  {
4840  bool cut = false;
4841  bool linkFlag = false;
4842 
4843  float *outputFloats = (float *)outputBuffer;
4844  for( i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
4845  outputFloats[i] = 0.0;
4846 
4847  if (inputBuffer && gAudioIO->mSoftwarePlaythrough) {
4849  numCaptureChannels,
4850  (float *)outputBuffer, (int)framesPerBuffer);
4851  }
4852 
4853  // Copy the results to outputMeterFloats if necessary
4854  if (outputMeterFloats != outputFloats) {
4855  for (i = 0; i < framesPerBuffer*numPlaybackChannels; ++i) {
4856  outputMeterFloats[i] = outputFloats[i];
4857  }
4858  }
4859 
4860 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
4861  // While scrubbing, ignore seek requests
4863  gAudioIO->mSeek = 0.0;
4864  else
4865 #endif
4866  if (gAudioIO->mSeek)
4867  {
4868  int token = gAudioIO->mStreamToken;
4869  wxMutexLocker locker(gAudioIO->mSuspendAudioThread);
4870  if (token != gAudioIO->mStreamToken)
4871  // This stream got destroyed while we waited for it
4872  return paAbort;
4873 
4874  // Pause audio thread and wait for it to finish
4877  {
4878  wxMilliSleep( 50 );
4879  }
4880 
4881  // Calculate the NEW time position
4884  gAudioIO->mSeek = 0.0;
4885 
4886  // Reset mixer positions and flush buffers for all tracks
4887  if(gAudioIO->mTimeTrack)
4888  // Following gives negative when mT0 > mTime
4891  (gAudioIO->mT0, gAudioIO->mTime);
4892  else
4894  gAudioIO->mWarpedTime = std::abs(gAudioIO->mWarpedTime);
4895 
4896  // Reset mixer positions and flush buffers for all tracks
4897  for (i = 0; i < numPlaybackTracks; i++)
4898  {
4899  gAudioIO->mPlaybackMixers[i]->Reposition(gAudioIO->mTime);
4900  const auto toDiscard =
4901  gAudioIO->mPlaybackBuffers[i]->AvailForGet();
4902  const auto discarded =
4903  gAudioIO->mPlaybackBuffers[i]->Discard( toDiscard );
4904  // wxASSERT( discarded == toDiscard );
4905  // but we can't assert in this thread
4906  wxUnusedVar(discarded);
4907  }
4908 
4909  // Reload the ring buffers
4912  {
4913  wxMilliSleep( 50 );
4914  }
4915 
4916  // Reenable the audio thread
4918 
4919  return paContinue;
4920  }
4921 
4922  unsigned numSolo = 0;
4923  for(unsigned t = 0; t < numPlaybackTracks; t++ )
4924  if( gAudioIO->mPlaybackTracks[t]->GetSolo() )
4925  numSolo++;
4926 #ifdef EXPERIMENTAL_MIDI_OUT
4927  auto numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
4928  for( unsigned t = 0; t < numMidiPlaybackTracks; t++ )
4929  if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() )
4930  numSolo++;
4931 #endif
4932 
4933  const WaveTrack **chans = (const WaveTrack **) alloca(numPlaybackChannels * sizeof(WaveTrack *));
4934  float **tempBufs = (float **) alloca(numPlaybackChannels * sizeof(float *));
4935  for (unsigned int c = 0; c < numPlaybackChannels; c++)
4936  {
4937  tempBufs[c] = (float *) alloca(framesPerBuffer * sizeof(float));
4938  }
4939 
4941  em.RealtimeProcessStart();
4942 
4943  bool selected = false;
4944  int group = 0;
4945  int chanCnt = 0;
4946  decltype(framesPerBuffer) maxLen = 0;
4947  for (unsigned t = 0; t < numPlaybackTracks; t++)
4948  {
4949  const WaveTrack *vt = gAudioIO->mPlaybackTracks[t].get();
4950 
4951  chans[chanCnt] = vt;
4952 
4953  if (linkFlag)
4954  linkFlag = false;
4955  else {
4956  cut = false;
4957 
4958  // Cut if somebody else is soloing
4959  if (numSolo>0 && !vt->GetSolo())
4960  cut = true;
4961 
4962  // Cut if we're muted (unless we're soloing)
4963  if (vt->GetMute() && !vt->GetSolo())
4964  cut = true;
4965 
4966  linkFlag = vt->GetLinked();
4967  selected = vt->GetSelected();
4968 
4969  // If we have a mono track, clear the right channel
4970  if (!linkFlag)
4971  {
4972  memset(tempBufs[1], 0, framesPerBuffer * sizeof(float));
4973  }
4974  }
4975 
4976 #define ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
4977 #ifdef ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
4978  decltype(framesPerBuffer) len = 0;
4979  // this is original code prior to r10680 -RBD
4980  if (cut)
4981  {
4982  len = gAudioIO->mPlaybackBuffers[t]->Discard(framesPerBuffer);
4983  // keep going here.
4984  // we may still need to issue a paComplete.
4985  }
4986  else
4987  {
4988  len = gAudioIO->mPlaybackBuffers[t]->Get((samplePtr)tempBufs[chanCnt],
4989  floatSample,
4990  framesPerBuffer);
4991  if (len < framesPerBuffer)
4992  // Pad with zeroes to the end, in case of a short channel
4993  memset((void*)&tempBufs[chanCnt][len], 0,
4994  (framesPerBuffer - len) * sizeof(float));
4995 
4996  chanCnt++;
4997  }
4998 
4999  // PRL: Bug1104:
5000  // There can be a difference of len in different loop passes if one channel
5001  // of a stereo track ends before the other! Take a max!
5002  maxLen = std::max(maxLen, len);
5003 
5004 
5005  if (linkFlag)
5006  {
5007  continue;
5008  }
5009 #else
5010  // This code was reorganized so that if all audio tracks
5011  // are muted, we still return paComplete when the end of
5012  // a selection is reached.
5013  // Vaughan, 2011-10-20: Further comments from Roger, by off-list email:
5014  // ...something to do with what it means to mute all audio tracks. E.g. if you
5015  // mute all and play, does the playback terminate immediately or play
5016  // silence? If it terminates immediately, does that terminate any MIDI
5017  // playback that might also be going on? ...Maybe muted audio tracks + MIDI,
5018  // the playback would NEVER terminate. ...I think the #else part is probably preferable...
5019  size_t len;
5020  if (cut)
5021  {
5022  len =
5023  gAudioIO->mPlaybackBuffers[t]->Discard(framesPerBuffer);
5024  } else
5025  {
5026  len =
5027  gAudioIO->mPlaybackBuffers[t]->Get((samplePtr)tempFloats,
5028  floatSample,
5029  framesPerBuffer);
5030  }
5031 #endif
5032 
5033  // Last channel seen now
5034  len = maxLen;
5035 
5036  if( !cut && selected )
5037  {
5038  len = em.RealtimeProcess(group, chanCnt, tempBufs, len);
5039  }
5040  group++;
5041 
5042  // If our buffer is empty and the time indicator is past
5043  // the end, then we've actually finished playing the entire
5044  // selection.
5045  // msmeyer: We never finish if we are playing looped
5046  // PRL: or scrubbing.
5047  if (len == 0 &&
5049  if ((gAudioIO->ReversedTime()
5050  ? gAudioIO->mTime <= gAudioIO->mT1
5051  : gAudioIO->mTime >= gAudioIO->mT1))
5052  // PRL: singalling MIDI output complete is necessary if
5053  // not USE_MIDI_THREAD, otherwise it's harmlessly redundant
5054  gAudioIO->mMidiOutputComplete = true,
5055  callbackReturn = paComplete;
5056  }
5057 
5058  if (cut) // no samples to process, they've been discarded
5059  continue;
5060 
5061  for (int c = 0; c < chanCnt; c++)
5062  {
5063  vt = chans[c];
5064 
5065  if (vt->GetChannel() == Track::LeftChannel ||
5066  vt->GetChannel() == Track::MonoChannel)
5067  {
5068  float gain = vt->GetChannelGain(0);
5069 
5070  // Output volume emulation: possibly copy meter samples, then
5071  // apply volume, then copy to the output buffer
5072  if (outputMeterFloats != outputFloats)
5073  for (decltype(len) i = 0; i < len; ++i)
5074  outputMeterFloats[numPlaybackChannels*i] +=
5075  gain*tempFloats[i];
5076 
5078  gain *= gAudioIO->mMixerOutputVol;
5079 
5080  for(decltype(len) i = 0; i < len; i++)
5081  outputFloats[numPlaybackChannels*i] += gain*tempBufs[c][i];
5082  }
5083 
5084  if (vt->GetChannel() == Track::RightChannel ||
5085  vt->GetChannel() == Track::MonoChannel)
5086  {
5087  float gain = vt->GetChannelGain(1);
5088 
5089  // Output volume emulation (as above)
5090  if (outputMeterFloats != outputFloats)
5091  for (decltype(len) i = 0; i < len; ++i)
5092  outputMeterFloats[numPlaybackChannels*i+1] +=
5093  gain*tempFloats[i];
5094 
5096  gain *= gAudioIO->mMixerOutputVol;
5097 
5098  for(decltype(len) i = 0; i < len; i++)
5099  outputFloats[numPlaybackChannels*i+1] += gain*tempBufs[c][i];
5100  }
5101  }
5102 
5103  chanCnt = 0;
5104  }
5105  // Poke: If there are no playback tracks, then the earlier check
5106  // about the time indicator being passed the end won't happen;
5107  // do it here instead (but not if looping or scrubbing)
5108  if (numPlaybackTracks == 0
5110  {
5111  if ((gAudioIO->ReversedTime()
5112  ? gAudioIO->mTime <= gAudioIO->mT1
5113  : gAudioIO->mTime >= gAudioIO->mT1)) {
5114 
5115  // PRL: singalling MIDI output complete is necessary if
5116  // not USE_MIDI_THREAD, otherwise it's harmlessly redundant
5117  gAudioIO->mMidiOutputComplete = true,
5118  callbackReturn = paComplete;
5119  }
5120  }
5121 
5122 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
5123  // Update the current time position, for scrubbing
5124  // "Consume" only as much as the ring buffers produced, which may
5125  // be less than framesPerBuffer (during "stutter")
5127  gAudioIO->mTime = gAudioIO->mScrubQueue->Consumer(maxLen);
5128 #endif
5129 
5130  em.RealtimeProcessEnd();
5131 
5132  gAudioIO->mLastPlaybackTimeMillis = ::wxGetLocalTimeMillis();
5133 
5134  //
5135  // Clip output to [-1.0,+1.0] range (msmeyer)
5136  //
5137  for( i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
5138  {
5139  float f = outputFloats[i];
5140  if (f > 1.0)
5141  outputFloats[i] = 1.0;
5142  else if (f < -1.0)
5143  outputFloats[i] = -1.0;
5144  }
5145 
5146  // Same for meter output
5147  if (outputMeterFloats != outputFloats)
5148  {
5149  for (i = 0; i < framesPerBuffer*numPlaybackChannels; ++i)
5150  {
5151  float f = outputMeterFloats[i];
5152  if (f > 1.0)
5153  outputMeterFloats[i] = 1.0;
5154  else if (f < -1.0)
5155  outputMeterFloats[i] = -1.0;
5156  }
5157  }
5158  }
5159 
5160  //
5161  // Copy from PortAudio to our input buffers.
5162  //
5163 
5164  if( inputBuffer && (numCaptureChannels > 0) )
5165  {
5166  // The error likely from a too-busy CPU falling behind real-time data
5167  // is paInputOverflow
5168  bool inputError =
5169  (statusFlags & (paInputOverflow))
5170  && !(statusFlags & paPrimingOutput);
5171 
5172  // But it seems it's easy to get false positives, at least on Mac
5173  // So we have not decided to enable this extra detection yet in
5174  // production
5175 
5176  size_t len = framesPerBuffer;
5177  for(unsigned t = 0; t < numCaptureChannels; t++)
5178  len = std::min( len,
5179  gAudioIO->mCaptureBuffers[t]->AvailForPut());
5180 
5181  if (gAudioIO->mSimulateRecordingErrors && 100LL * rand() < RAND_MAX)
5182  // Make spurious errors for purposes of testing the error
5183  // reporting
5184  len = 0;
5185 
5186  // A different symptom is that len < framesPerBuffer because
5187  // the other thread, executing FillBuffers, isn't consuming fast
5188  // enough from mCaptureBuffers; maybe it's CPU-bound, or maybe the
5189  // storage device it writes is too slow
5190  if (gAudioIO->mDetectDropouts &&
5191  ((gAudioIO->mDetectUpstreamDropouts && inputError) ||
5192  len < framesPerBuffer) ) {
5193  // Assume that any good partial buffer should be written leftmost
5194  // and zeroes will be padded after; label the zeroes.
5195  auto start = gAudioIO->mTime + len / gAudioIO->mRate;
5196  auto duration = (framesPerBuffer - len) / gAudioIO->mRate;
5197  auto interval = std::make_pair( start, duration );
5198  gAudioIO->mLostCaptureIntervals.push_back( interval );
5199  }
5200 
5201  if (len < framesPerBuffer)
5202  {
5203  gAudioIO->mLostSamples += (framesPerBuffer - len);
5204  wxPrintf(wxT("lost %d samples\n"), (int)(framesPerBuffer - len));
5205  }
5206 
5207  if (len > 0) {
5208  for(unsigned t = 0; t < numCaptureChannels; t++) {
5209 
5210  // dmazzoni:
5211  // Un-interleave. Ugly special-case code required because the
5212  // capture channels could be in three different sample formats;
5213  // it'd be nice to be able to call CopySamples, but it can't
5214  // handle multiplying by the gain and then clipping. Bummer.
5215 
5216  switch(gAudioIO->mCaptureFormat) {
5217  case floatSample: {
5218  float *inputFloats = (float *)inputBuffer;
5219  for( i = 0; i < len; i++)
5220  tempFloats[i] =
5221  inputFloats[numCaptureChannels*i+t];
5222  } break;
5223  case int24Sample:
5224  // We should never get here. Audacity's int24Sample format
5225  // is different from PortAudio's sample format and so we
5226  // make PortAudio return float samples when recording in
5227  // 24-bit samples.
5228  wxASSERT(false);
5229  break;
5230  case int16Sample: {
5231  short *inputShorts = (short *)inputBuffer;
5232  short *tempShorts = (short *)tempBuffer;
5233  for( i = 0; i < len; i++) {
5234  float tmp = inputShorts[numCaptureChannels*i+t];
5235  if (tmp > 32767)
5236  tmp = 32767;
5237  if (tmp < -32768)
5238  tmp = -32768;
5239  tempShorts[i] = (short)(tmp);
5240  }
5241  } break;
5242  } // switch
5243 
5244  const auto put =
5245  gAudioIO->mCaptureBuffers[t]->Put(
5246  (samplePtr)tempBuffer, gAudioIO->mCaptureFormat, len);
5247  // wxASSERT(put == len);
5248  // but we can't assert in this thread
5249  wxUnusedVar(put);
5250  }
5251  }
5252  }
5253 
5254  // Update the current time position if not scrubbing
5255  // (Already did it above, for scrubbing)
5256 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
5258 #endif
5259  {
5260  double delta = framesPerBuffer / gAudioIO->mRate;
5261  if (gAudioIO->ReversedTime())
5262  delta *= -1.0;
5263  if (gAudioIO->mTimeTrack)
5264  // MB: this is why SolveWarpedLength is needed :)
5265  gAudioIO->mTime =
5267  else
5268  gAudioIO->mTime += delta;
5269  }
5270 
5271  // Wrap to start if looping
5273  {
5274  while (gAudioIO->ReversedTime()
5275  ? gAudioIO->mTime <= gAudioIO->mT1
5276  : gAudioIO->mTime >= gAudioIO->mT1)
5277  {
5278  // LL: This is not exactly right, but I'm at my wits end trying to
5279  // figure it out. Feel free to fix it. :-)
5280  // MB: it's much easier than you think, mTime isn't warped at all!
5282  }
5283  }
5284 
5285  // Record the reported latency from PortAudio.
5286  // TODO: Don't recalculate this with every callback?
5287 
5288  // 01/21/2009: Disabled until a better solution presents itself.
5289  #if 0
5290  // As of 06/17/2006, portaudio v19 returns inputBufferAdcTime set to
5291  // zero. It is being worked on, but for now we just can't do much
5292  // but follow the leader.
5293  //
5294  // 08/27/2006: too inconsistent for now...just leave it a zero.
5295  //
5296  // 04/16/2008: Looks like si->inputLatency comes back with something useful though.
5297  // This rearranged logic uses si->inputLatency, but if PortAudio fixes inputBufferAdcTime,
5298  // this code won't have to be modified to use it.
5299  // Also avoids setting mLastRecordingOffset except when simultaneously playing and recording.
5300  //
5301  if (numCaptureChannels > 0 && numPlaybackChannels > 0) // simultaneously playing and recording
5302  {
5303  if (timeInfo->inputBufferAdcTime > 0)
5304  gAudioIO->mLastRecordingOffset = timeInfo->inputBufferAdcTime - timeInfo->outputBufferDacTime;
5305  else if (gAudioIO->mLastRecordingOffset == 0.0)
5306  {
5307  const PaStreamInfo* si = Pa_GetStreamInfo( gAudioIO->mPortStreamV19 );
5308  gAudioIO->mLastRecordingOffset = -si->inputLatency;
5309  }
5310  }
5311  #endif
5312  } // if mStreamToken > 0
5313  else {
5314  // No tracks to play, but we should clear the output, and
5315  // possibly do software playthrough...
5316 
5317  if( outputBuffer && (numPlaybackChannels > 0) ) {
5318  float *outputFloats = (float *)outputBuffer;
5319  for( i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
5320  outputFloats[i] = 0.0;
5321 
5322  if (inputBuffer && gAudioIO->mSoftwarePlaythrough) {
5324  numCaptureChannels,
5325  (float *)outputBuffer, (int)framesPerBuffer);
5326  }
5327 
5328  // Copy the results to outputMeterFloats if necessary
5329  if (outputMeterFloats != outputFloats) {
5330  for (i = 0; i < framesPerBuffer*numPlaybackChannels; ++i) {
5331  outputMeterFloats[i] = outputFloats[i];
5332  }
5333  }
5334  }
5335 
5336  }
5337  /* Send data to playback VU meter if applicable */
5338  if (gAudioIO->mOutputMeter &&
5340  outputMeterFloats) {
5341  // Get here if playback meter is live
5342  /* It's critical that we don't update the meters while StopStream is
5343  * trying to stop PortAudio, otherwise it can lead to a freeze. We use
5344  * two variables to synchronize:
5345  * mUpdatingMeters tells StopStream when the callback is about to enter
5346  * the code where it might update the meters, and
5347  * mUpdateMeters is how the rest of the code tells the callback when it
5348  * is allowed to actually do the updating.
5349  * Note that mUpdatingMeters must be set first to avoid a race condition.
5350  */
5351  gAudioIO->mUpdatingMeters = true;
5352  if (gAudioIO->mUpdateMeters) {
5353  gAudioIO->mOutputMeter->UpdateDisplay(numPlaybackChannels,
5354  framesPerBuffer,
5355  outputMeterFloats);
5356 
5357  //v Vaughan, 2011-02-25: Moved this update back to TrackPanel::OnTimer()
5358  // as it helps with playback issues reported by Bill and noted on Bug 258.
5359  // The problem there occurs if Software Playthrough is on.
5360  // Could conditionally do the update here if Software Playthrough is off,
5361  // and in TrackPanel::OnTimer() if Software Playthrough is on, but not now.
5362  // PRL 12 Jul 2015: and what was in TrackPanel::OnTimer is now handled by means of event
5363  // type EVT_TRACK_PANEL_TIMER
5364  //AudacityProject* pProj = GetActiveProject();
5365  //MixerBoard* pMixerBoard = pProj->GetMixerBoard();
5366  //if (pMixerBoard)
5367  // pMixerBoard->UpdateMeters(gAudioIO->GetStreamTime(),
5368  // (pProj->mLastPlayMode == loopedPlay));
5369  }
5370  gAudioIO->mUpdatingMeters = false;
5371  } // end playback VU meter update
5372 
5373  return callbackReturn;
5374 }
virtual void OnAudioIOStartRecording()=0
size_t GetCommonlyAvailCapture()
Get the number of audio samples ready in all of the recording buffers.
Definition: AudioIO.cpp:3313
double LimitStreamTime(double absoluteTime) const
Clamps the given time to be between mT0 and mT1.
Definition: AudioIO.cpp:2927
void StartTag(const wxString &name) override
bool GetSolo() const
Definition: Track.h:321
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:143
A ToolBar that has the main Transport buttons.
wxArrayString GetInputSourceNames()
Get the list of inputs to the current mixer device.
Definition: AudioIO.cpp:1396
void StopStream()
Stop recording, playback or input monitoring.
Definition: AudioIO.cpp:2521
GrowableSampleBuffer & Resize(size_t count, sampleFormat format)
Definition: SampleFormat.h:101
static wxArrayLong mCachedPlaybackRates
Definition: AudioIO.h:745
double ComputeWarpedLength(double t0, double t1) const
Compute the duration (in seconds at playback) of the specified region of the track.
Definition: TimeTrack.cpp:160
bool OutputMixerEmulated()
Find out if the output level control is being emulated via software attenuation.
Definition: AudioIO.cpp:1391
size_t RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples)
void Transformer(sampleCount &startSample, sampleCount &endSample, sampleCount &duration, Maybe< wxMutexLocker > &cleanup)
Definition: AudioIO.cpp:663
sampleCount maxSample
Definition: Scrubbing.h:43
double mMinCaptureSecsToCopy
Definition: AudioIO.h:670
Meter * GetPlaybackMeter()
Definition: Project.cpp:4874
std::unique_ptr< AudioIO > ugAudioIO
Definition: AudioIO.cpp:480
double GetTime(double rate) const
Definition: AudioIO.cpp:917
Duration(ScrubQueue &queue_)
Definition: AudioIO.cpp:943
root of a hierarchy of classes that are thrown and caught by Audacity.
TimeTrack * timeTrack
Definition: AudioIO.h:123
void WriteAttr(const wxString &name, const wxString &value) override
#define ENV_DB_KEY
Definition: GUISettings.h:15
double GetStreamTime()
During playback, the (unwarped) track time most recently played.
Definition: AudioIO.cpp:2968
bool IsEmpty() const
static double mCachedBestRateIn
Definition: AudioIO.h:749
static int mNextStreamToken
Definition: AudioIO.h:645
bool GetSelected() const
Definition: Track.h:217
bool IsStreamActive()
Returns true if the audio i/o is running at all, but not during cleanup.
Definition: AudioIO.cpp:2898
void SetMissingAliasedFileWarningShouldShow(bool b)
Changes the behavior of missing aliased blockfiles warnings.
Meter * mInputMeter
Definition: AudioIO.h:697
enum AudioIO::@3 mPlayMode
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:499
bool mDetectDropouts
Definition: AudioIO.h:801
sampleCount mScrubDuration
Definition: AudioIO.h:789
void RealtimeAddProcessor(int group, unsigned chans, float rate)
wxString WarningDialogKey(const wxString &internalDialogName)
Definition: Warning.cpp:114
void CopySamples(samplePtr src, sampleFormat srcFormat, samplePtr dst, sampleFormat dstFormat, unsigned int len, bool highQuality, unsigned int srcStride, unsigned int dstStride)
bool IsAvailable(AudacityProject *projecT)
Function to automatically set an acceptable volume.
Definition: AudioIO.cpp:2473
bool mDetectUpstreamDropouts
Definition: AudioIO.h:813
VU Meter, for displaying recording/playback level.
Definition: Meter.h:88
volatile bool mUpdatingMeters
Definition: AudioIO.h:700
float mMixerOutputVol
Definition: AudioIO.h:716
#define USE_MIDI_THREAD
Definition: AudioIO.h:105
void SetMeters()
Set the current VU meters - this should be done once after each call to StartStream currently...
Definition: AudioIO.cpp:2506
double LastTimeInQueue() const
Definition: AudioIO.cpp:581
wxLongLong mLastScrubTimeMillis
Definition: AudioIO.cpp:966
double Consumer(unsigned long frames)
Definition: AudioIO.cpp:747
double mTime
Current time position during playback, in seconds. Between mT0 and mT1.
Definition: AudioIO.h:654
sampleCount mGoal
Definition: AudioIO.cpp:928
bool mInputMixerWorks
Can we control the hardware input level?
Definition: AudioIO.h:715
bool mSoftwarePlaythrough
Definition: AudioIO.h:674
unsigned mTrailingIdx
Definition: AudioIO.cpp:962
bool GetLinked() const
Definition: Track.h:218
sampleCount mDuration
Definition: AudioIO.cpp:932
double GetLastTimeInScrubQueue() const
return the ending time of the last enqueued scrub interval.
Definition: AudioIO.cpp:2880
bool IsAudioTokenActive(int token)
Returns true if the stream is active, or even if audio I/O is busy cleaning up its data or writing to...
Definition: AudioIO.cpp:2917
~AudioIO()
Definition: AudioIO.cpp:1281
double NormalizeStreamTime(double absoluteTime) const
Normalizes the given time, clamping it and handling gaps from cut preview.
Definition: AudioIO.cpp:2936
const TimeTrack * mTimeTrack
Definition: AudioIO.h:739
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
Definition: MemoryX.h:585
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:672
void StartStreamCleanup(bool bOnlyBuffers=false)
Clean up after StartStream if it fails.
Definition: AudioIO.cpp:2346
void FillBuffers()
Definition: AudioIO.cpp:3797
float GetChannelGain(int channel) const
Definition: WaveTrack.cpp:439
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:640
virtual void OnAudioIOStopRecording()=0
bool IsBusy()
Returns true if audio i/o is busy starting, stopping, playing, or recording.
Definition: AudioIO.cpp:2890
wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:1151
ScrubbingOptions * pScrubbingOptions
Definition: AudioIO.h:135
static int GetOptimalSupportedSampleRate()
Get a supported sample rate which can be used a an optimal default.
Definition: AudioIO.cpp:3149
Entry mEntries[Size]
Definition: AudioIO.cpp:961
const double mRate
Definition: AudioIO.cpp:965
static int getPlayDevIndex(const wxString &devName=wxEmptyString)
get the index of the device selected in the preferences.
Definition: AudioIO.cpp:3336
void StartMonitoring(double sampleRate)
Start up Portaudio for capture and recording as needed for input monitoring and software playthrough ...
Definition: AudioIO.cpp:1818
float mSilenceLevel
Definition: AudioIO.h:677
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:637
void WriteSubTree(const AutoSaveFile &value)
MixerBoard * GetMixerBoard()
Definition: Project.h:503
bool InputMixerWorks()
Find out if the input hardware level control is available.
Definition: AudioIO.cpp:1386
sampleFormat mCaptureFormat
Definition: AudioIO.h:680
GrowableSampleBuffer mSilentBuf
Definition: AudioIO.h:728
static wxArrayLong mCachedSampleRates
Definition: AudioIO.h:748
wxString HostName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:1158
ArrayOf< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:643
void DeinitAudioIO()
Definition: AudioIO.cpp:1146
bool Init(Entry *previous, sampleCount s0, sampleCount s1, sampleCount &duration, const ScrubbingOptions &options)
Definition: AudioIO.cpp:794
std::unique_ptr< ScrubQueue > mScrubQueue
Definition: AudioIO.h:785
#define safenew
Definition: Audacity.h:223
#define BAD_STREAM_TIME
Definition: AudioIO.h:78
double mWarpedTime
Definition: AudioIO.h:659
void InsertSilence(double t, double len) override
Definition: WaveTrack.cpp:1364
static int mCachedPlaybackIndex
Definition: AudioIO.h:744
wxMutex mSuspendAudioThread
Definition: AudioIO.h:782
#define DEFAULT_LATENCY_CORRECTION
Definition: AudioIO.h:84
wxAtomicInt mRecordingException
Definition: AudioIO.h:794
#define ENV_DB_RANGE
Definition: GUISettings.h:16
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:161
bool mPaused
True if audio playback is paused.
Definition: AudioIO.h:672
void GetMixer(int *inputSource, float *inputVolume, float *playbackVolume)
Definition: AudioIO.cpp:1355
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
static double MaxAllowedScrubSpeed()
Definition: Scrubbing.h:63
void EndTag(const wxString &name) override
static double streamStartTime
Definition: AudioIO.cpp:980
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:638
int format
Definition: ExportPCM.cpp:56
bool ReversedTime() const
True if the end time is before the start time.
Definition: AudioIO.h:513
volatile int mStreamToken
Definition: AudioIO.h:644
unsigned mMiddleIdx
Definition: AudioIO.cpp:963
static double SystemTime(bool usingAlsa)
Definition: AudioIO.cpp:982
WaveTrackArray mCaptureTracks
Definition: AudioIO.h:639
#define DEFAULT_SYNTH_LATENCY
Definition: AudioIO.h:81
bool mEmulateMixerOutputVol
Definition: AudioIO.h:707
bool Producer(double end, const ScrubbingOptions &options)
Definition: AudioIO.cpp:598
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:64
PaStream * mPortStreamV19
Definition: AudioIO.h:673
struct holding stream options, including a pointer to the TimeTrack and AudioIOListener and whether t...
Definition: AudioIO.h:110
sampleCount mS0
Definition: AudioIO.cpp:926
void ClearRecordingException()
Definition: AudioIO.h:797
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:65
ScrubQueue(double t0, double t1, wxLongLong startClockMillis, double rate, long maxDebt, const ScrubbingOptions &options)
Definition: AudioIO.cpp:546
Meter * GetCaptureMeter()
Definition: AudioIO.cpp:2502
double mCaptureRingBufferSecs
Definition: AudioIO.h:668
bool IsPaused()
Find out if playback / recording is currently paused.
Definition: AudioIO.cpp:2865
const wxLongLong clockTime
Definition: AudioIO.cpp:953
const long mMaxDebt
Definition: AudioIO.cpp:971
Entry()
Definition: AudioIO.cpp:786
#define lrint(dbl)
Definition: float_cast.h:136
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
double GetBestRate(bool capturing, bool playing, double sampleRate)
Return a valid sample rate that is supported by the current I/O device(s).
Definition: AudioIO.cpp:3169
WaveTrackArray GetWaveTrackArray(bool selectionOnly, bool includeMuted=true)
Definition: Track.cpp:1260
bool EnqueueScrub(double endTimeOrSpeed, const ScrubbingOptions &options)
enqueue a NEW scrub play interval, using the last end as the NEW start, to be played over the same du...
Definition: AudioIO.cpp:2872
void RealtimeInitialize(double rate)
void HandleDeviceChange()
update state after changing what audio devices are selected
Definition: AudioIO.cpp:1424
static wxArrayLong GetSupportedPlaybackRates(int DevIndex=-1, double rate=0.0)
Get a list of sample rates the output (playback) device supports.
Definition: AudioIO.cpp:2977
if(pTrack &&pTrack->GetDisplay()!=WaveTrack::Spectrum)
AudacityProject * mOwningProject
Definition: AudioIO.h:696
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:49
static PaSampleFormat AudacityToPortAudioSampleFormat(sampleFormat format)
Definition: AudioIO.cpp:1625
int min(int a, int b)
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:686
AudioIOListener * mListener
Definition: AudioIO.h:730
volatile bool mAudioThreadShouldCallFillBuffersOnce
Definition: AudioIO.h:682
samplePtr ptr() const
Definition: SampleFormat.h:81
wxCondition mAvailable
Definition: AudioIO.cpp:974
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:679
#define LAT1CTOWX(X)
Definition: Internat.h:168
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
double mSeek
Definition: AudioIO.h:666
std::vector< std::shared_ptr< NoteTrack > > NoteTrackArray
Definition: Track.h:53
DEFINE_EVENT_TYPE(EVT_AUDIOIO_PLAYBACK)
unsigned int mNumCaptureChannels
Definition: AudioIO.h:678
static EffectManager & Get()
size_t GetCommonlyAvailPlayback()
Get the number of audio samples free in all of the playback buffers.
Definition: AudioIO.cpp:3304
wxLongLong mLastTransformerTimeMillis
Definition: AudioIO.cpp:968
void TP_DisplayStatusMessage(const wxString &msg) override
Definition: Project.cpp:5140
std::unique_ptr< AudioThread > mThread
Definition: AudioIO.h:631
unsigned long long mLostSamples
Definition: AudioIO.h:681
static void DoSoftwarePlaythrough(const void *inputBuffer, sampleFormat inputFormat, unsigned inputChannels, float *outputBuffer, int len)
Definition: AudioIO.cpp:4623
int StartStream(const WaveTrackConstArray &playbackTracks, const WaveTrackArray &captureTracks, double t0, double t1, const AudioIOStartStreamOptions &options)
Start recording or playing back audio.
Definition: AudioIO.cpp:1861
static wxArrayLong GetSupportedSampleRates(int playDevice=-1, int recDevice=-1, double rate=0.0)
Get a list of sample rates the current input/output device combination supports.
Definition: AudioIO.cpp:3105
unsigned mLeadingIdx
Definition: AudioIO.cpp:964
sampleCount mS1
Definition: AudioIO.cpp:927
void UpdateDisplay(unsigned numChannels, int numFrames, float *sampleData)
Update the meters with a block of audio data.
Definition: Meter.cpp:923
bool IsClipping() const
Definition: Meter.cpp:1135
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
virtual void OnAudioIONewBlockFiles(const AutoSaveFile &blockFileLog)=0
double mRate
Audio playback rate in samples per second.
Definition: AudioIO.h:648
double maxSpeed
Definition: Scrubbing.h:52
Monitors record play start/stop and new blockfiles. Has callbacks for these events.
bool mUpdateMeters
Definition: AudioIO.h:699
void SetMixer(int inputSource)
Definition: AudioIO.cpp:1323
AudioIO * gAudioIO
Definition: AudioIO.cpp:481
ControlToolBar * GetControlToolBar()
Definition: Project.cpp:4787
float GetMaxPeak() const
Definition: Meter.cpp:1100
volatile double mLastRecordingOffset
Definition: AudioIO.h:693
void SetListener(AudioIOListener *listener)
Definition: AudioIO.cpp:4088
const wxChar * name
Definition: Distortion.cpp:94
sampleCount mCredit
Definition: AudioIO.cpp:969
bool IsMonitoring()
Returns true if we're monitoring input (but not recording or playing actual audio) ...
Definition: AudioIO.cpp:2922
double minSpeed
Definition: Scrubbing.h:51
static int mCachedCaptureIndex
Definition: AudioIO.h:746
Meter * GetCaptureMeter()
Definition: Project.cpp:4888
static const int NumStandardRates
How many standard sample rates there are.
Definition: AudioIO.h:381
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:302
void ClearSamples(samplePtr dst, sampleFormat format, size_t start, size_t len)
bool mUsingAlsa
Definition: AudioIO.h:741
double mWarpedLength
Definition: AudioIO.h:664
double mCutPreviewGapLen
Definition: AudioIO.h:726
sampleCount minSample
Definition: Scrubbing.h:44
void SetOffset(double o) override
Definition: WaveTrack.cpp:197
double mT0
Playback starts at offset of mT0, which is measured in seconds.
Definition: AudioIO.h:650
double mCutPreviewGapStart
Definition: AudioIO.h:725
double GetEndTime() const
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1852
Meter * mOutputMeter
Definition: AudioIO.h:698
virtual void OnAudioIORate(int rate)=0
wxString GetDeviceInfo()
Get diagnostic information on all the available audio I/O devices.
Definition: AudioIO.cpp:3452
static double mCachedBestRateOut
Definition: AudioIO.h:750
double SolveWarpedLength(double t0, double length) const
Compute how much unwarped time must have elapsed if length seconds of warped time has elapsed...
Definition: TimeTrack.cpp:165
bool enqueueBySpeed
Definition: Scrubbing.h:46
void SetCaptureMeter(AudacityProject *project, Meter *meter)
Definition: AudioIO.cpp:2478
bool GetMute() const
Definition: Track.h:320
static const int StandardRates[]
Array of common audio sample rates.
Definition: AudioIO.h:379
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:800
AudioIOListener * listener
Definition: AudioIO.h:124
void InitAudioIO()
Definition: AudioIO.cpp:1113
sampleCount mDebt
Definition: AudioIO.cpp:970
void SetPlaybackMeter(AudacityProject *project, Meter *meter)
Definition: AudioIO.cpp:2490
static const int NumRatesToTry
How many sample rates to try.
Definition: AudioIO.h:510
volatile bool mAudioThreadFillBuffersLoopActive
Definition: AudioIO.h:684
AudacityApp & wxGetApp()
#define DEFAULT_LATENCY_DURATION
Definition: AudioIO.h:83
TrackList * GetTracks()
Definition: Project.h:177
sampleCount mPlayed
Definition: AudioIO.cpp:939
static const int RatesToTry[]
Array of audio sample rates to try to use.
Definition: AudioIO.h:508
void RealtimeFinalize()
double mFactor
Definition: AudioIO.h:646
PaError mLastPaError
Definition: AudioIO.h:694
const sampleCount duration
Definition: AudioIO.cpp:954
void ResetMeters(const bool bResetClipping)
size_t mPlaybackSamplesToCopy
Definition: AudioIO.h:669
void SetPaused(bool state)
Pause and un-pause playback and recording.
Definition: AudioIO.cpp:2848
void RealtimeSuspend()
#define MAX(a, b)
Definition: AudioIO.cpp:4621
bool StartPortAudioStream(double sampleRate, unsigned int numPlaybackChannels, unsigned int numCaptureChannels, sampleFormat captureFormat)
Opens the portaudio stream(s) used to do playback or recording (or both) through. ...
Definition: AudioIO.cpp:1638
Definition: AudioIO.cpp:784
static bool ValidateDeviceNames(const wxString &play, const wxString &rec)
Ensure selected device names are valid.
Definition: AudioIO.cpp:1165
void RealtimeProcessEnd()
static wxArrayLong GetSupportedCaptureRates(int devIndex=-1, double rate=0.0)
Get a list of sample rates the input (recording) device supports.
Definition: AudioIO.cpp:3039
double mT1
Playback ends at offset of mT1, which is measured in seconds. Note that mT1 may be less than mT0 duri...
Definition: AudioIO.h:652
void Reset(double sampleRate, bool resetClipping)
This method is thread-safe! Feel free to call from a different thread (like from an audio I/O callbac...
Definition: Meter.cpp:863
ExitCode Entry() override
Definition: AudioIO.cpp:3251
void create(Args &&...args)
Definition: MemoryX.h:632
volatile bool mAudioThreadFillBuffersLoopRunning
Definition: AudioIO.h:683
virtual int GetChannel() const override
Definition: WaveTrack.cpp:209
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:676
void SetRecordingException()
Definition: AudioIO.h:795
bool mSilentScrub
Definition: AudioIO.h:788
bool IsMeterDisabled() const
Find out if the level meter is disabled or not.
Definition: Meter.cpp:1810
double GetStartTime() const
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1832
static int getRecordDevIndex(const wxString &devName=wxEmptyString)
get the index of the supplied (named) recording device, or the device selected in the preferences if ...
Definition: AudioIO.cpp:3393
WaveTrackConstArray mPlaybackTracks
Definition: AudioIO.h:641
void InitSilent(const Entry &previous, sampleCount duration)
Definition: AudioIO.cpp:909
void Flush()
Flush must be called after last Append.
Definition: WaveTrack.cpp:1629
static wxArrayLong mCachedCaptureRates
Definition: AudioIO.h:747
static double MinAllowedScrubSpeed()
Definition: Scrubbing.h:65
friend int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
void RealtimeProcessStart()
a class wrapping reading and writing of arbitrary data in text or binary format to a file...
Definition: AutoRecovery.h:80
bool mSimulateRecordingErrors
Definition: AudioIO.h:809
A Track that is used for Midi notes. (Somewhat old code).
double mPlaybackRingBufferSecs
Definition: AudioIO.h:667
Defined different on Mac and other platforms (on Mac it does not use wxWidgets wxThread), this class sits in a thread loop reading and writing audio.
Definition: AudioIO.cpp:1091