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