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