Audacity  3.0.3
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 
417 #include "AudioIO.h"
418 
419 
420 
421 #include "AudioIOListener.h"
422 
423 #include "float_cast.h"
424 #include "DeviceManager.h"
425 
426 #include <cfloat>
427 #include <math.h>
428 #include <stdlib.h>
429 #include <algorithm>
430 
431 #ifdef __WXMSW__
432 #include <malloc.h>
433 #endif
434 
435 #ifdef HAVE_ALLOCA_H
436 #include <alloca.h>
437 #endif
438 
439 #include "portaudio.h"
440 
441 #if USE_PORTMIXER
442 #include "portmixer.h"
443 #endif
444 
445 #include <wx/app.h>
446 #include <wx/frame.h>
447 #include <wx/wxcrtvararg.h>
448 #include <wx/log.h>
449 #include <wx/textctrl.h>
450 #include <wx/timer.h>
451 #include <wx/intl.h>
452 #include <wx/debug.h>
453 
454 #if defined(__WXMAC__) || defined(__WXMSW__)
455 #include <wx/power.h>
456 #endif
457 
458 #include "Mix.h"
459 #include "Resample.h"
460 #include "RingBuffer.h"
461 #include "prefs/GUISettings.h"
462 #include "Prefs.h"
463 #include "Project.h"
464 #include "DBConnection.h"
465 #include "ProjectFileIO.h"
466 #include "WaveTrack.h"
467 
469 #include "prefs/QualityPrefs.h"
470 #include "prefs/RecordingPrefs.h"
471 #include "widgets/MeterPanelBase.h"
473 #include "widgets/ErrorDialog.h"
474 
475 #ifdef EXPERIMENTAL_MIDI_OUT
476 
477 #include "../lib-src/portmidi/pm_common/portmidi.h"
478 #include "../lib-src/portmidi/porttime/porttime.h"
479 #include "../lib-src/header-substitutes/allegro.h"
480 
481  #define MIDI_SLEEP 10 /* milliseconds */
482  // how long do we think the thread that fills MIDI buffers,
483  // if it is separate from the portaudio thread,
484  // might be delayed due to other threads?
485  #ifdef USE_MIDI_THREAD
486  #define THREAD_LATENCY 10 /* milliseconds */
487  #else
488  #define THREAD_LATENCY 0 /* milliseconds */
489  #endif
490  #define ROUND(x) (int) ((x)+0.5)
491  //#include <string.h>
492 // #include "../lib-src/portmidi/pm_common/portmidi.h"
493  #include "../lib-src/portaudio-v19/src/common/pa_util.h"
494  #include "NoteTrack.h"
495 #endif
496 
497 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
498  #define LOWER_BOUND 0.0
499  #define UPPER_BOUND 1.0
500 #endif
501 
502 using std::max;
503 using std::min;
504 
506 {
507  return static_cast< AudioIO* >( AudioIOBase::Get() );
508 }
509 
510 wxDEFINE_EVENT(EVT_AUDIOIO_PLAYBACK, wxCommandEvent);
511 wxDEFINE_EVENT(EVT_AUDIOIO_CAPTURE, wxCommandEvent);
512 wxDEFINE_EVENT(EVT_AUDIOIO_MONITOR, wxCommandEvent);
513 
514 // static
519 
520 enum {
521  // This is the least positive latency we can
522  // specify to Pm_OpenOutput, 1 ms, which prevents immediate
523  // scheduling of events:
525 };
526 
527 constexpr size_t TimeQueueGrainSize = 2000;
528 
529 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
530 
531 #ifdef __WXGTK__
532  // Might #define this for a useful thing on Linux
533  #undef REALTIME_ALSA_THREAD
534 #else
535  // never on the other operating systems
536  #undef REALTIME_ALSA_THREAD
537 #endif
538 
539 #ifdef REALTIME_ALSA_THREAD
540 #include "pa_linux_alsa.h"
541 #endif
542 
543 
544 struct AudioIoCallback::ScrubState
545 {
546  ScrubState(double t0,
547  double rate,
548  const ScrubbingOptions &options)
549  : mRate(rate)
550  , mStartTime( t0 )
551  {
552  const double t1 = options.bySpeed ? options.initSpeed : t0;
553  Update( t1, options );
554  }
555 
556  void Update(double end, const ScrubbingOptions &options)
557  {
558  // Called by another thread
559  mMessage.Write({ end, options });
560  }
561 
562  void Get(sampleCount &startSample, sampleCount &endSample,
563  sampleCount inDuration, sampleCount &duration)
564  {
565  // Called by the thread that calls AudioIO::FillBuffers
566  startSample = endSample = duration = -1LL;
567  sampleCount s0Init;
568 
569  Message message( mMessage.Read() );
570  if ( !mStarted ) {
571  s0Init = llrint( mRate *
572  std::max( message.options.minTime,
573  std::min( message.options.maxTime, mStartTime ) ) );
574 
575  // Make some initial silence. This is not needed in the case of
576  // keyboard scrubbing or play-at-speed, because the initial speed
577  // is known when this function is called the first time.
578  if ( !(message.options.isKeyboardScrubbing ||
579  message.options.isPlayingAtSpeed) ) {
580  mData.mS0 = mData.mS1 = s0Init;
581  mData.mGoal = -1;
582  mData.mDuration = duration = inDuration;
583  mData.mSilence = 0;
584  }
585  }
586 
587  if (mStarted || message.options.isKeyboardScrubbing ||
588  message.options.isPlayingAtSpeed) {
589  Data newData;
590  inDuration += mAccumulatedSeekDuration;
591 
592  // If already started, use the previous end as NEW start.
593  const auto s0 = mStarted ? mData.mS1 : s0Init;
594  const sampleCount s1 ( message.options.bySpeed
595  ? s0.as_double() +
596  lrint(inDuration.as_double() * message.end) // end is a speed
597  : lrint(message.end * mRate) // end is a time
598  );
599  auto success =
600  newData.Init(mData, s0, s1, inDuration, message.options, mRate);
601  if (success)
602  mAccumulatedSeekDuration = 0;
603  else {
604  mAccumulatedSeekDuration += inDuration;
605  return;
606  }
607  mData = newData;
608  };
609 
610  mStarted = true;
611 
612  Data &entry = mData;
613  if ( mStopped.load( std::memory_order_relaxed ) ) {
614  // We got the shut-down signal, or we discarded all the work.
615  // Output the -1 values.
616  }
617  else if (entry.mDuration > 0) {
618  // First use of the entry
619  startSample = entry.mS0;
620  endSample = entry.mS1;
621  duration = entry.mDuration;
622  entry.mDuration = 0;
623  }
624  else if (entry.mSilence > 0) {
625  // Second use of the entry
626  startSample = endSample = entry.mS1;
627  duration = entry.mSilence;
628  entry.mSilence = 0;
629  }
630  }
631 
632  void Stop()
633  {
634  mStopped.store( true, std::memory_order_relaxed );
635  }
636 
637 #if 0
638  // Needed only for the DRAG_SCRUB experiment
639  // Should make mS1 atomic then?
640  double LastTrackTime() const
641  {
642  // Needed by the main thread sometimes
643  return mData.mS1.as_double() / mRate;
644  }
645 #endif
646 
647  ~ScrubState() {}
648 
649 private:
650  struct Data
651  {
652  Data()
653  : mS0(0)
654  , mS1(0)
655  , mGoal(0)
656  , mDuration(0)
657  , mSilence(0)
658  {}
659 
660  bool Init(Data &rPrevious, sampleCount s0, sampleCount s1,
661  sampleCount duration,
662  const ScrubbingOptions &options, double rate)
663  {
664  auto previous = &rPrevious;
665  auto origDuration = duration;
666  mSilence = 0;
667 
668  const bool &adjustStart = options.adjustStart;
669 
670  wxASSERT(duration > 0);
671  double speed =
672  (std::abs((s1 - s0).as_long_long())) / duration.as_double();
673  bool adjustedSpeed = false;
674 
675  auto minSpeed = std::min(options.minSpeed, options.maxSpeed);
676  wxASSERT(minSpeed == options.minSpeed);
677 
678  // May change the requested speed and duration
679  if (!adjustStart && speed > options.maxSpeed)
680  {
681  // Reduce speed to the maximum selected in the user interface.
682  speed = options.maxSpeed;
683  mGoal = s1;
684  adjustedSpeed = true;
685  }
686  else if (!adjustStart &&
687  previous->mGoal >= 0 &&
688  previous->mGoal == s1)
689  {
690  // In case the mouse has not moved, and playback
691  // is catching up to the mouse at maximum speed,
692  // continue at no less than maximum. (Without this
693  // the final catch-up can make a slow scrub interval
694  // that drops the pitch and sounds wrong.)
695  minSpeed = options.maxSpeed;
696  mGoal = s1;
697  adjustedSpeed = true;
698  }
699  else
700  mGoal = -1;
701 
702  if (speed < minSpeed) {
703  if (s0 != s1 && adjustStart)
704  // Do not trim the duration.
705  ;
706  else
707  // Trim the duration.
708  duration =
709  std::max(0L, lrint(speed * duration.as_double() / minSpeed));
710 
711  speed = minSpeed;
712  adjustedSpeed = true;
713  }
714 
716  // Mixers were set up to go only so slowly, not slower.
717  // This will put a request for some silence in the work queue.
718  adjustedSpeed = true;
719  speed = 0.0;
720  }
721 
722  // May change s1 or s0 to match speed change or stay in bounds of the project
723 
724  if (adjustedSpeed && !adjustStart)
725  {
726  // adjust s1
727  const sampleCount diff = lrint(speed * duration.as_double());
728  if (s0 < s1)
729  s1 = s0 + diff;
730  else
731  s1 = s0 - diff;
732  }
733 
734  bool silent = false;
735 
736  // Adjust s1 (again), and duration, if s1 is out of bounds,
737  // or abandon if a stutter is too short.
738  // (Assume s0 is in bounds, because it equals the last scrub's s1 which was checked.)
739  if (s1 != s0)
740  {
741  // When playback follows a fast mouse movement by "stuttering"
742  // at maximum playback, don't make stutters too short to be useful.
743  if (options.adjustStart &&
744  duration < llrint( options.minStutterTime * rate ) )
745  return false;
746 
747  sampleCount minSample { llrint(options.minTime * rate) };
748  sampleCount maxSample { llrint(options.maxTime * rate) };
749  auto newDuration = duration;
750  const auto newS1 = std::max(minSample, std::min(maxSample, s1));
751  if(s1 != newS1)
752  newDuration = std::max( sampleCount{ 0 },
753  sampleCount(
754  duration.as_double() * (newS1 - s0).as_double() /
755  (s1 - s0).as_double()
756  )
757  );
758  if (newDuration == 0) {
759  // A silent scrub with s0 == s1
760  silent = true;
761  s1 = s0;
762  }
763  else if (s1 != newS1) {
764  // Shorten
765  duration = newDuration;
766  s1 = newS1;
767  }
768  }
769 
770  if (adjustStart && !silent)
771  {
772  // Limit diff because this is seeking.
773  const sampleCount diff =
774  lrint(std::min(options.maxSpeed, speed) * duration.as_double());
775  if (s0 < s1)
776  s0 = s1 - diff;
777  else
778  s0 = s1 + diff;
779  }
780 
781  mS0 = s0;
782  mS1 = s1;
783  mDuration = duration;
784  if (duration < origDuration)
785  mSilence = origDuration - duration;
786 
787  return true;
788  }
789 
790  sampleCount mS0;
791  sampleCount mS1;
792  sampleCount mGoal;
793  sampleCount mDuration;
794  sampleCount mSilence;
795  };
796 
797  double mStartTime;
798  bool mStarted{ false };
799  std::atomic<bool> mStopped { false };
800  Data mData;
801  const double mRate;
802  struct Message {
803  Message() = default;
804  Message(const Message&) = default;
805  double end;
806  ScrubbingOptions options;
807  };
808  MessageBuffer<Message> mMessage;
809  sampleCount mAccumulatedSeekDuration{};
810 };
811 #endif
812 
813 #ifdef EXPERIMENTAL_MIDI_OUT
814 // return the system time as a double
815 static double streamStartTime = 0; // bias system time to small number
816 
817 static double SystemTime(bool usingAlsa)
818 {
819 #ifdef __WXGTK__
820  if (usingAlsa) {
821  struct timespec now;
822  // CLOCK_MONOTONIC_RAW is unaffected by NTP or adj-time
823  clock_gettime(CLOCK_MONOTONIC_RAW, &now);
824  //return now.tv_sec + now.tv_nsec * 0.000000001;
825  return (now.tv_sec + now.tv_nsec * 0.000000001) - streamStartTime;
826  }
827 #else
828  static_cast<void>(usingAlsa);//compiler food.
829 #endif
830 
831  return PaUtil_GetTime() - streamStartTime;
832 }
833 #endif
834 
835 int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
836  unsigned long framesPerBuffer,
837  const PaStreamCallbackTimeInfo *timeInfo,
838  PaStreamCallbackFlags statusFlags, void *userData );
839 
841 //
842 // class AudioThread - declaration and glue code
843 //
845 
846 #include <thread>
847 
848 #ifdef __WXMAC__
849 
850 // On Mac OS X, it's better not to use the wxThread class.
851 // We use our own implementation based on pthreads instead.
852 
853 #include <pthread.h>
854 #include <time.h>
855 
856 class AudioThread {
857  public:
858  typedef int ExitCode;
859  AudioThread() { mDestroy = false; mThread = NULL; }
860  virtual ExitCode Entry();
861  void Create() {}
862  void Delete() {
863  mDestroy = true;
864  pthread_join(mThread, NULL);
865  }
866  bool TestDestroy() { return mDestroy; }
867  void Sleep(int ms) {
868  struct timespec spec;
869  spec.tv_sec = 0;
870  spec.tv_nsec = ms * 1000 * 1000;
871  nanosleep(&spec, NULL);
872  }
873  static void *callback(void *p) {
874  AudioThread *th = (AudioThread *)p;
875  return reinterpret_cast<void *>( th->Entry() );
876  }
877  void Run() {
878  pthread_create(&mThread, NULL, callback, this);
879  }
880  private:
881  bool mDestroy;
882  pthread_t mThread;
883 };
884 
885 #else
886 
887 // The normal wxThread-derived AudioThread class for all other
888 // platforms:
889 class AudioThread /* not final */ : public wxThread {
890  public:
891  AudioThread():wxThread(wxTHREAD_JOINABLE) {}
892  ExitCode Entry() override;
893 };
894 
895 #endif
896 
897 #ifdef EXPERIMENTAL_MIDI_OUT
898 class MidiThread final : public AudioThread {
899  public:
900  ExitCode Entry() override;
901 };
902 #endif
903 
904 
906 //
907 // UI Thread Context
908 //
910 
912 {
913  ugAudioIO.reset(safenew AudioIO());
914  Get()->mThread->Run();
915 #ifdef EXPERIMENTAL_MIDI_OUT
916 #ifdef USE_MIDI_THREAD
917  Get()->mMidiThread->Run();
918 #endif
919 #endif
920 
921  // Make sure device prefs are initialized
922  if (gPrefs->Read(wxT("AudioIO/RecordingDevice"), wxT("")).empty()) {
923  int i = getRecordDevIndex();
924  const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
925  if (info) {
926  gPrefs->Write(wxT("/AudioIO/RecordingDevice"), DeviceName(info));
927  gPrefs->Write(wxT("/AudioIO/Host"), HostName(info));
928  }
929  }
930 
931  if (gPrefs->Read(wxT("AudioIO/PlaybackDevice"), wxT("")).empty()) {
932  int i = getPlayDevIndex();
933  const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
934  if (info) {
935  gPrefs->Write(wxT("/AudioIO/PlaybackDevice"), DeviceName(info));
936  gPrefs->Write(wxT("/AudioIO/Host"), HostName(info));
937  }
938  }
939 
940  gPrefs->Flush();
941 }
942 
944 {
945  ugAudioIO.reset();
946 }
947 
948 bool AudioIO::ValidateDeviceNames(const wxString &play, const wxString &rec)
949 {
950  const PaDeviceInfo *pInfo = Pa_GetDeviceInfo(getPlayDevIndex(play));
951  const PaDeviceInfo *rInfo = Pa_GetDeviceInfo(getRecordDevIndex(rec));
952 
953  // Valid iff both defined and the same api.
954  return pInfo != nullptr && rInfo != nullptr && pInfo->hostApi == rInfo->hostApi;
955 }
956 
958 {
959  if (!std::atomic<double>{}.is_lock_free()) {
960  // If this check fails, then the atomic<double> members in AudioIO.h
961  // might be changed to atomic<float> to be more efficient with some
962  // loss of precision. That could be conditionally compiled depending
963  // on the platform.
964  wxASSERT(false);
965  }
966 
967  // This ASSERT because of casting in the callback
968  // functions where we cast a tempFloats buffer to a (short*) buffer.
969  // We have to ASSERT in the GUI thread, if we are to see it properly.
970  wxASSERT( sizeof( short ) <= sizeof( float ));
971 
975  mPortStreamV19 = NULL;
976 
977 #ifdef EXPERIMENTAL_MIDI_OUT
978  mMidiStream = NULL;
979  mMidiThreadFillBuffersLoopRunning = false;
980  mMidiThreadFillBuffersLoopActive = false;
981  mMidiStreamActive = false;
982  mSendMidiState = false;
983  mIterator = NULL;
984 
985  mNumFrames = 0;
986  mNumPauseFrames = 0;
987 #endif
988 
989 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
990  mAILAActive = false;
991 #endif
992  mStreamToken = 0;
993 
994  mLastPaError = paNoError;
995 
996  mLastRecordingOffset = 0.0;
998  mPaused = false;
999  mSilenceLevel = 0.0;
1000 
1001  mUpdateMeters = false;
1002  mUpdatingMeters = false;
1003 
1004  mOwningProject = NULL;
1005  mOutputMeter.Release();
1006 
1007  PaError err = Pa_Initialize();
1008 
1009  if (err != paNoError) {
1010  auto errStr = XO("Could not find any audio devices.\n");
1011  errStr += XO("You will not be able to play or record audio.\n\n");
1012  wxString paErrStr = LAT1CTOWX(Pa_GetErrorText(err));
1013  if (!paErrStr.empty())
1014  errStr += XO("Error: %s").Format( paErrStr );
1015  // XXX: we are in libaudacity, popping up dialogs not allowed! A
1016  // long-term solution will probably involve exceptions
1018  errStr,
1019  XO("Error Initializing Audio"),
1020  wxICON_ERROR|wxOK);
1021 
1022  // Since PortAudio is not initialized, all calls to PortAudio
1023  // functions will fail. This will give reasonable behavior, since
1024  // the user will be able to do things not relating to audio i/o,
1025  // but any attempt to play or record will simply fail.
1026  }
1027 
1028 #ifdef EXPERIMENTAL_MIDI_OUT
1029  PmError pmErr = Pm_Initialize();
1030 
1031  if (pmErr != pmNoError) {
1032  auto errStr =
1033  XO("There was an error initializing the midi i/o layer.\n");
1034  errStr += XO("You will not be able to play midi.\n\n");
1035  wxString pmErrStr = LAT1CTOWX(Pm_GetErrorText(pmErr));
1036  if (!pmErrStr.empty())
1037  errStr += XO("Error: %s").Format( pmErrStr );
1038  // XXX: we are in libaudacity, popping up dialogs not allowed! A
1039  // long-term solution will probably involve exceptions
1041  errStr,
1042  XO("Error Initializing Midi"),
1043  wxICON_ERROR|wxOK);
1044 
1045  // Same logic for PortMidi as described above for PortAudio
1046  }
1047 
1048 #ifdef USE_MIDI_THREAD
1049  mMidiThread = std::make_unique<MidiThread>();
1050  mMidiThread->Create();
1051 #endif
1052 
1053 #endif
1054 
1055  // Start thread
1056  mThread = std::make_unique<AudioThread>();
1057  mThread->Create();
1058 
1059 #if defined(USE_PORTMIXER)
1060  mPortMixer = NULL;
1061  mPreviousHWPlaythrough = -1.0;
1063 #else
1064  mEmulateMixerOutputVol = true;
1065  mMixerOutputVol = 1.0;
1066  mInputMixerWorks = false;
1067 #endif
1068 
1070 
1071 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
1072  mScrubState = NULL;
1073  mScrubDuration = 0;
1074  mSilentScrub = false;
1075 #endif
1076 }
1077 
1079 {
1080 #if defined(USE_PORTMIXER)
1081  if (mPortMixer) {
1082  #if __WXMAC__
1083  if (Px_SupportsPlaythrough(mPortMixer) && mPreviousHWPlaythrough >= 0.0)
1084  Px_SetPlaythrough(mPortMixer, mPreviousHWPlaythrough);
1085  mPreviousHWPlaythrough = -1.0;
1086  #endif
1087  Px_CloseMixer(mPortMixer);
1088  mPortMixer = NULL;
1089  }
1090 #endif
1091 
1092  // FIXME: ? TRAP_ERR. Pa_Terminate probably OK if err without reporting.
1093  Pa_Terminate();
1094 
1095 #ifdef EXPERIMENTAL_MIDI_OUT
1096  Pm_Terminate();
1097 
1098  /* Delete is a "graceful" way to stop the thread.
1099  (Kill is the not-graceful way.) */
1100 
1101 #ifdef USE_MIDI_THREAD
1102  mMidiThread->Delete();
1103  mMidiThread.reset();
1104 #endif
1105 
1106 #endif
1107 
1108  /* Delete is a "graceful" way to stop the thread.
1109  (Kill is the not-graceful way.) */
1110 
1111  // This causes reentrancy issues during application shutdown
1112  // wxTheApp->Yield();
1113 
1114  mThread->Delete();
1115  mThread.reset();
1116 }
1117 
1118 void AudioIO::SetMixer(int inputSource, float recordVolume,
1119  float playbackVolume)
1120 {
1121  mMixerOutputVol = playbackVolume;
1122 #if defined(USE_PORTMIXER)
1123  PxMixer *mixer = mPortMixer;
1124  if( !mixer )
1125  return;
1126 
1127  float oldRecordVolume = Px_GetInputVolume(mixer);
1128  float oldPlaybackVolume = Px_GetPCMOutputVolume(mixer);
1129 
1130  AudioIoCallback::SetMixer(inputSource);
1131  if( oldRecordVolume != recordVolume )
1132  Px_SetInputVolume(mixer, recordVolume);
1133  if( oldPlaybackVolume != playbackVolume )
1134  Px_SetPCMOutputVolume(mixer, playbackVolume);
1135 
1136 #endif
1137 }
1138 
1139 void AudioIO::GetMixer(int *recordDevice, float *recordVolume,
1140  float *playbackVolume)
1141 {
1142 #if defined(USE_PORTMIXER)
1143 
1144  PxMixer *mixer = mPortMixer;
1145 
1146  if( mixer )
1147  {
1148  *recordDevice = Px_GetCurrentInputSource(mixer);
1149 
1150  if (mInputMixerWorks)
1151  *recordVolume = Px_GetInputVolume(mixer);
1152  else
1153  *recordVolume = 1.0f;
1154 
1156  *playbackVolume = mMixerOutputVol;
1157  else
1158  *playbackVolume = Px_GetPCMOutputVolume(mixer);
1159 
1160  return;
1161  }
1162 
1163 #endif
1164 
1165  *recordDevice = 0;
1166  *recordVolume = 1.0f;
1167  *playbackVolume = mMixerOutputVol;
1168 }
1169 
1171 {
1172  return mInputMixerWorks;
1173 }
1174 
1176 {
1177  return mEmulateMixerOutputVol;
1178 }
1179 
1181 {
1182 #if defined(USE_PORTMIXER)
1183 
1184  wxArrayString deviceNames;
1185 
1186  if( mPortMixer )
1187  {
1188  int numSources = Px_GetNumInputSources(mPortMixer);
1189  for( int source = 0; source < numSources; source++ )
1190  deviceNames.push_back(wxString(wxSafeConvertMB2WX(Px_GetInputSourceName(mPortMixer, source))));
1191  }
1192  else
1193  {
1194  wxLogDebug(wxT("AudioIO::GetInputSourceNames(): PortMixer not initialised!"));
1195  }
1196 
1197  return deviceNames;
1198 
1199 #else
1200 
1201  wxArrayString blank;
1202 
1203  return blank;
1204 
1205 #endif
1206 }
1207 
1209 {
1210  switch(format) {
1211  case int16Sample:
1212  return paInt16;
1213  case int24Sample:
1214  return paInt24;
1215  case floatSample:
1216  default:
1217  return paFloat32;
1218  }
1219 }
1220 
1222  unsigned int numPlaybackChannels,
1223  unsigned int numCaptureChannels,
1224  sampleFormat captureFormat)
1225 {
1226  auto sampleRate = options.rate;
1227 #ifdef EXPERIMENTAL_MIDI_OUT
1228  mNumFrames = 0;
1229  mNumPauseFrames = 0;
1230  // we want this initial value to be way high. It should be
1231  // sufficient to assume AudioTime is zero and therefore
1232  // mSystemMinusAudioTime is SystemTime(), but we'll add 1000s
1233  // for good measure. On the first callback, this should be
1234  // reduced to SystemTime() - mT0, and note that mT0 is always
1235  // positive.
1236  mSystemMinusAudioTimePlusLatency =
1237  mSystemMinusAudioTime = SystemTime(mUsingAlsa) + 1000;
1238  mAudioOutLatency = 0.0; // set when stream is opened
1239  mCallbackCount = 0;
1240  mAudioFramesPerBuffer = 0;
1241 #endif
1242  mOwningProject = options.pProject;
1243 
1244  // PRL: Protection from crash reported by David Bailes, involving starting
1245  // and stopping with frequent changes of active window, hard to reproduce
1246  if (!mOwningProject)
1247  return false;
1248 
1249  mInputMeter.Release();
1250  mOutputMeter.Release();
1251 
1252  mLastPaError = paNoError;
1253  // pick a rate to do the audio I/O at, from those available. The project
1254  // rate is suggested, but we may get something else if it isn't supported
1255  mRate = GetBestRate(numCaptureChannels > 0, numPlaybackChannels > 0, sampleRate);
1256 
1257  // July 2016 (Carsten and Uwe)
1258  // BUG 193: Tell PortAudio sound card will handle 24 bit (under DirectSound) using
1259  // userData.
1260  int captureFormat_saved = captureFormat;
1261  // Special case: Our 24-bit sample format is different from PortAudio's
1262  // 3-byte packed format. So just make PortAudio return float samples,
1263  // since we need float values anyway to apply the gain.
1264  // ANSWER-ME: So we *never* actually handle 24-bit?! This causes mCapture to
1265  // be set to floatSample below.
1266  // JKC: YES that's right. Internally Audacity uses float, and float has space for
1267  // 24 bits as well as exponent. Actual 24 bit would require packing and
1268  // unpacking unaligned bytes and would be inefficient.
1269  // ANSWER ME: is floatSample 64 bit on 64 bit machines?
1270  if (captureFormat == int24Sample)
1271  captureFormat = floatSample;
1272 
1273  mNumPlaybackChannels = numPlaybackChannels;
1274  mNumCaptureChannels = numCaptureChannels;
1275 
1276  bool usePlayback = false, useCapture = false;
1277  PaStreamParameters playbackParameters{};
1278  PaStreamParameters captureParameters{};
1279 
1280  double latencyDuration = DEFAULT_LATENCY_DURATION;
1281  gPrefs->Read(wxT("/AudioIO/LatencyDuration"), &latencyDuration);
1282 
1283  if( numPlaybackChannels > 0)
1284  {
1285  usePlayback = true;
1286 
1287  // this sets the device index to whatever is "right" based on preferences,
1288  // then defaults
1289  playbackParameters.device = getPlayDevIndex();
1290 
1291  const PaDeviceInfo *playbackDeviceInfo;
1292  playbackDeviceInfo = Pa_GetDeviceInfo( playbackParameters.device );
1293 
1294  if( playbackDeviceInfo == NULL )
1295  return false;
1296 
1297  // regardless of source formats, we always mix to float
1298  playbackParameters.sampleFormat = paFloat32;
1299  playbackParameters.hostApiSpecificStreamInfo = NULL;
1300  playbackParameters.channelCount = mNumPlaybackChannels;
1301 
1303  playbackParameters.suggestedLatency =
1304  playbackDeviceInfo->defaultLowOutputLatency;
1305  else {
1306  // When using WASAPI, the suggested latency does not affect
1307  // the latency of the playback, but the position of playback is given as if
1308  // there was the suggested latency. This results in the last "suggested latency"
1309  // of a selection not being played. So for WASAPI use 0.0 for the suggested
1310  // latency regardless of user setting. See bug 1949.
1311  const PaHostApiInfo* hostInfo = Pa_GetHostApiInfo(playbackDeviceInfo->hostApi);
1312  bool isWASAPI = (hostInfo && hostInfo->type == paWASAPI);
1313  playbackParameters.suggestedLatency = isWASAPI ? 0.0 : latencyDuration/1000.0;
1314  }
1315 
1316  if ( options.playbackMeter )
1317  mOutputMeter = options.playbackMeter;
1318  else
1319  mOutputMeter.Release();
1320  }
1321 
1322  if( numCaptureChannels > 0)
1323  {
1324  useCapture = true;
1325  mCaptureFormat = captureFormat;
1326 
1327  const PaDeviceInfo *captureDeviceInfo;
1328  // retrieve the index of the device set in the prefs, or a sensible
1329  // default if it isn't set/valid
1330  captureParameters.device = getRecordDevIndex();
1331 
1332  captureDeviceInfo = Pa_GetDeviceInfo( captureParameters.device );
1333 
1334  if( captureDeviceInfo == NULL )
1335  return false;
1336 
1337  captureParameters.sampleFormat =
1339 
1340  captureParameters.hostApiSpecificStreamInfo = NULL;
1341  captureParameters.channelCount = mNumCaptureChannels;
1342 
1344  captureParameters.suggestedLatency =
1345  captureDeviceInfo->defaultHighInputLatency;
1346  else
1347  captureParameters.suggestedLatency = latencyDuration/1000.0;
1348 
1350  }
1351 
1352  SetMeters();
1353 
1354 #ifdef USE_PORTMIXER
1355 #ifdef __WXMSW__
1356  //mchinen nov 30 2010. For some reason Pa_OpenStream resets the input volume on windows.
1357  //so cache and restore after it.
1358  //The actual problem is likely in portaudio's pa_win_wmme.c OpenStream().
1359  float oldRecordVolume = Px_GetInputVolume(mPortMixer);
1360 #endif
1361 #endif
1362 
1363  // July 2016 (Carsten and Uwe)
1364  // BUG 193: Possibly tell portAudio to use 24 bit with DirectSound.
1365  int userData = 24;
1366  int* lpUserData = (captureFormat_saved == int24Sample) ? &userData : NULL;
1367 
1368  // (Linux, bug 1885) After scanning devices it takes a little time for the
1369  // ALSA device to be available, so allow retries.
1370  // On my test machine, no more than 3 attempts are required.
1371  unsigned int maxTries = 1;
1372 #ifdef __WXGTK__
1374  maxTries = 5;
1375 #endif
1376 
1377  for (unsigned int tries = 0; tries < maxTries; tries++) {
1378  mLastPaError = Pa_OpenStream( &mPortStreamV19,
1379  useCapture ? &captureParameters : NULL,
1380  usePlayback ? &playbackParameters : NULL,
1381  mRate, paFramesPerBufferUnspecified,
1382  paNoFlag,
1383  audacityAudioCallback, lpUserData );
1384  if (mLastPaError == paNoError) {
1385  break;
1386  }
1387  wxLogDebug("Attempt %u to open capture stream failed with: %d", 1 + tries, mLastPaError);
1388  wxMilliSleep(1000);
1389  }
1390 
1391 
1392 #if USE_PORTMIXER
1393 #ifdef __WXMSW__
1394  Px_SetInputVolume(mPortMixer, oldRecordVolume);
1395 #endif
1396  if (mPortStreamV19 != NULL && mLastPaError == paNoError) {
1397 
1398  #ifdef __WXMAC__
1399  if (mPortMixer) {
1400  if (Px_SupportsPlaythrough(mPortMixer)) {
1401  bool playthrough = false;
1402 
1403  mPreviousHWPlaythrough = Px_GetPlaythrough(mPortMixer);
1404 
1405  // Bug 388. Feature not supported.
1406  //gPrefs->Read(wxT("/AudioIO/Playthrough"), &playthrough, false);
1407  if (playthrough)
1408  Px_SetPlaythrough(mPortMixer, 1.0);
1409  else
1410  Px_SetPlaythrough(mPortMixer, 0.0);
1411  }
1412  }
1413  #endif
1414  }
1415 #endif
1416 
1417 #ifdef EXPERIMENTAL_MIDI_OUT
1418  // We use audio latency to estimate how far ahead of DACS we are writing
1419  if (mPortStreamV19 != NULL && mLastPaError == paNoError) {
1420  const PaStreamInfo* info = Pa_GetStreamInfo(mPortStreamV19);
1421  // this is an initial guess, but for PA/Linux/ALSA it's wrong and will be
1422  // updated with a better value:
1423  mAudioOutLatency = info->outputLatency;
1424  mSystemMinusAudioTimePlusLatency += mAudioOutLatency;
1425  }
1426 #endif
1427 
1428 #if (defined(__WXMAC__) || defined(__WXMSW__)) && wxCHECK_VERSION(3,1,0)
1429  // Don't want the system to sleep while audio I/O is active
1430  if (mPortStreamV19 != NULL && mLastPaError == paNoError) {
1431  wxPowerResource::Acquire(wxPOWER_RESOURCE_SCREEN, _("Audacity Audio"));
1432  }
1433 #endif
1434 
1435  return (mLastPaError == paNoError);
1436 }
1437 
1439 {
1440  return wxString::Format(wxT("%d %s."), (int) mLastPaError, Pa_GetErrorText(mLastPaError));
1441 }
1442 
1444 {
1445  if ( mPortStreamV19 || mStreamToken )
1446  return;
1447 
1448  bool success;
1449  long captureChannels;
1450  auto captureFormat = QualityPrefs::SampleFormatChoice();
1451  gPrefs->Read(wxT("/AudioIO/RecordChannels"), &captureChannels, 2L);
1452  gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &mSoftwarePlaythrough, false);
1453  int playbackChannels = 0;
1454 
1456  playbackChannels = 2;
1457 
1458  // FIXME: TRAP_ERR StartPortAudioStream (a PaError may be present)
1459  // but StartPortAudioStream function only returns true or false.
1460  mUsingAlsa = false;
1461  success = StartPortAudioStream(options, (unsigned int)playbackChannels,
1462  (unsigned int)captureChannels,
1463  captureFormat);
1464 
1465  if (!success) {
1466  auto msg = XO("Error opening recording device.\nError code: %s")
1467  .Format( Get()->LastPaErrorString() );
1469  XO("Error"), msg, wxT("Error_opening_sound_device"));
1470  return;
1471  }
1472 
1473  wxCommandEvent e(EVT_AUDIOIO_MONITOR);
1474  e.SetEventObject(mOwningProject);
1475  e.SetInt(true);
1476  wxTheApp->ProcessEvent(e);
1477 
1478  // FIXME: TRAP_ERR PaErrorCode 'noted' but not reported in StartMonitoring.
1479  // Now start the PortAudio stream!
1480  // TODO: ? Factor out and reuse error reporting code from end of
1481  // AudioIO::StartStream?
1482  mLastPaError = Pa_StartStream( mPortStreamV19 );
1483 
1484  // Update UI display only now, after all possibilities for error are past.
1485  auto pListener = GetListener();
1486  if ((mLastPaError == paNoError) && pListener) {
1487  // advertise the chosen I/O sample rate to the UI
1488  pListener->OnAudioIORate((int)mRate);
1489  }
1490 }
1491 
1493  double t0, double t1,
1494  const AudioIOStartStreamOptions &options)
1495 {
1496  mLostSamples = 0;
1497  mLostCaptureIntervals.clear();
1498  mDetectDropouts =
1499  gPrefs->Read( WarningDialogKey(wxT("DropoutDetected")), true ) != 0;
1500  auto cleanup = finally ( [this] { ClearRecordingException(); } );
1501 
1502  if( IsBusy() )
1503  return 0;
1504 
1505  // We just want to set mStreamToken to -1 - this way avoids
1506  // an extremely rare but possible race condition, if two functions
1507  // somehow called StartStream at the same time...
1508  mStreamToken--;
1509  if (mStreamToken != -1)
1510  return 0;
1511 
1512  // TODO: we don't really need to close and reopen stream if the
1513  // format matches; however it's kind of tricky to keep it open...
1514  //
1515  // if (sampleRate == mRate &&
1516  // playbackChannels == mNumPlaybackChannels &&
1517  // captureChannels == mNumCaptureChannels &&
1518  // captureFormat == mCaptureFormat) {
1519 
1520  if (mPortStreamV19) {
1521  StopStream();
1522  while(mPortStreamV19)
1523  wxMilliSleep( 50 );
1524  }
1525 
1526 #ifdef __WXGTK__
1527  // Detect whether ALSA is the chosen host, and do the various involved MIDI
1528  // timing compensations only then.
1529  mUsingAlsa = (gPrefs->Read(wxT("/AudioIO/Host"), wxT("")) == "ALSA");
1530 #endif
1531 
1532  gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &mSoftwarePlaythrough, false);
1533  gPrefs->Read(wxT("/AudioIO/SoundActivatedRecord"), &mPauseRec, false);
1534  gPrefs->Read(wxT("/AudioIO/Microfades"), &mbMicroFades, false);
1535  int silenceLevelDB;
1536  gPrefs->Read(wxT("/AudioIO/SilenceLevel"), &silenceLevelDB, -50);
1537  int dBRange;
1538  dBRange = gPrefs->Read(ENV_DB_KEY, ENV_DB_RANGE);
1539  if(silenceLevelDB < -dBRange)
1540  {
1541  silenceLevelDB = -dBRange + 3;
1542  // meter range was made smaller than SilenceLevel
1543  // so set SilenceLevel reasonable
1544 
1545  // PRL: update prefs, or correct it only in-session?
1546  // The behavior (as of 2.3.1) was the latter, the code suggested that
1547  // the intent was the former; I preserve the behavior, but uncomment
1548  // this if you disagree.
1549  // gPrefs->Write(wxT("/AudioIO/SilenceLevel"), silenceLevelDB);
1550  // gPrefs->Flush();
1551  }
1552  mSilenceLevel = DB_TO_LINEAR(silenceLevelDB); // meter goes -dBRange dB -> 0dB
1553 
1554  // Clamp pre-roll so we don't play before time 0
1555  const auto preRoll = std::max(0.0, std::min(t0, options.preRoll));
1556  mRecordingSchedule = {};
1557  mRecordingSchedule.mPreRoll = preRoll;
1559  (gPrefs->ReadDouble(wxT("/AudioIO/LatencyCorrection"),
1561  / 1000.0;
1562  mRecordingSchedule.mDuration = t1 - t0;
1563  if (options.pCrossfadeData)
1565 
1566  mListener = options.listener;
1567  mRate = options.rate;
1568 
1569  mSeek = 0;
1571  mCaptureTracks = tracks.captureTracks;
1573 #ifdef EXPERIMENTAL_MIDI_OUT
1574  mMidiPlaybackTracks = tracks.midiTracks;
1575 #endif
1576 
1577  bool commit = false;
1578  auto cleanupTracks = finally([&]{
1579  if (!commit) {
1580  // Don't keep unnecessary shared pointers to tracks
1581  mPlaybackTracks.clear();
1582  mCaptureTracks.clear();
1583 #ifdef EXPERIMENTAL_MIDI_OUT
1584  mMidiPlaybackTracks.clear();
1585 #endif
1586 
1587  // Don't cause a busy wait in the audio thread after stopping scrubbing
1589  }
1590  });
1591 
1592  mPlaybackBuffers.reset();
1593  mPlaybackMixers.reset();
1594  mCaptureBuffers.reset();
1595  mResample.reset();
1596  mTimeQueue.mData.reset();
1597 
1598 #ifdef EXPERIMENTAL_MIDI_OUT
1599  streamStartTime = 0;
1600  streamStartTime = SystemTime(mUsingAlsa);
1601 #endif
1602 
1604  t0, t1, options, mCaptureTracks.empty() ? nullptr : &mRecordingSchedule );
1605  const bool scrubbing = mPlaybackSchedule.Interactive();
1606 
1607  unsigned int playbackChannels = 0;
1608  unsigned int captureChannels = 0;
1609  sampleFormat captureFormat = floatSample;
1610 
1611  auto pListener = GetListener();
1612 
1613  if (tracks.playbackTracks.size() > 0
1614 #ifdef EXPERIMENTAL_MIDI_OUT
1615  || tracks.midiTracks.size() > 0
1616 #endif
1617  )
1618  playbackChannels = 2;
1619 
1621  playbackChannels = 2;
1622 
1623  if (tracks.captureTracks.size() > 0)
1624  {
1625  // For capture, every input channel gets its own track
1626  captureChannels = mCaptureTracks.size();
1627  // I don't deal with the possibility of the capture tracks
1628  // having different sample formats, since it will never happen
1629  // with the current code. This code wouldn't *break* if this
1630  // assumption was false, but it would be sub-optimal. For example,
1631  // if the first track was 16-bit and the second track was 24-bit,
1632  // we would set the sound card to capture in 16 bits and the second
1633  // track wouldn't get the benefit of all 24 bits the card is capable
1634  // of.
1635  captureFormat = mCaptureTracks[0]->GetSampleFormat();
1636 
1637  // Tell project that we are about to start recording
1638  if (pListener)
1639  pListener->OnAudioIOStartRecording();
1640  }
1641 
1642  bool successAudio;
1643 
1644  successAudio = StartPortAudioStream(options, playbackChannels,
1645  captureChannels, captureFormat);
1646 #ifdef EXPERIMENTAL_MIDI_OUT
1647 
1648  // TODO: it may be that midi out will not work unless audio in or out is
1649  // active -- this would be a bug and may require a change in the
1650  // logic here.
1651 
1652  bool successMidi = true;
1653 
1654  if(!mMidiPlaybackTracks.empty()){
1655  successMidi = StartPortMidiStream();
1656  }
1657 
1658  // On the other hand, if MIDI cannot be opened, we will not complain
1659 #endif
1660 
1661  if (!successAudio) {
1662  if (pListener && captureChannels > 0)
1663  pListener->OnAudioIOStopRecording();
1664  mStreamToken = 0;
1665 
1666  return 0;
1667  }
1668 
1669  if ( ! AllocateBuffers( options, tracks, t0, t1, options.rate, scrubbing ) )
1670  return 0;
1671 
1672  if (mNumPlaybackChannels > 0)
1673  {
1674  auto & em = RealtimeEffectManager::Get();
1675  // Setup for realtime playback at the rate of the realtime
1676  // stream, not the rate of the track.
1677  em.RealtimeInitialize(mRate);
1678 
1679  // The following adds a NEW effect processor for each logical track and the
1680  // group determination should mimic what is done in audacityAudioCallback()
1681  // when calling RealtimeProcess().
1682  int group = 0;
1683  for (size_t i = 0, cnt = mPlaybackTracks.size(); i < cnt;)
1684  {
1685  const WaveTrack *vt = mPlaybackTracks[i].get();
1686 
1687  // TODO: more-than-two-channels
1688  unsigned chanCnt = TrackList::Channels(vt).size();
1689  i += chanCnt;
1690 
1691  // Setup for realtime playback at the rate of the realtime
1692  // stream, not the rate of the track.
1693  em.RealtimeAddProcessor(group++, std::min(2u, chanCnt), mRate);
1694  }
1695  }
1696 
1697 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1698  AILASetStartTime();
1699 #endif
1700 
1701  if (options.pStartTime)
1702  {
1703  // Calculate the NEW time position
1704  const auto time = mPlaybackSchedule.ClampTrackTime( *options.pStartTime );
1705 
1706  // Main thread's initialization of mTime
1708 
1709  // Reset mixer positions for all playback tracks
1710  unsigned numMixers = mPlaybackTracks.size();
1711  for (unsigned ii = 0; ii < numMixers; ++ii)
1712  mPlaybackMixers[ii]->Reposition( time );
1714  }
1715 
1716  // Now that we are done with SetTrackTime():
1718  if (mTimeQueue.mData)
1720  // else recording only without overdub
1721 
1722 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
1723  if (scrubbing)
1724  {
1725  const auto &scrubOptions = *options.pScrubbingOptions;
1726  mScrubState =
1727  std::make_unique<ScrubState>(
1729  mRate,
1730  scrubOptions);
1731  mScrubDuration = 0;
1732  mSilentScrub = false;
1733  }
1734  else
1735  mScrubState.reset();
1736 #endif
1737 
1738  // We signal the audio thread to call FillBuffers, to prime the RingBuffers
1739  // so that they will have data in them when the stream starts. Having the
1740  // audio thread call FillBuffers here makes the code more predictable, since
1741  // FillBuffers will ALWAYS get called from the Audio thread.
1743 
1745  auto interval = 50ull;
1746  if (options.playbackStreamPrimer) {
1747  interval = options.playbackStreamPrimer();
1748  }
1749  wxMilliSleep( interval );
1750  }
1751 
1752  if(mNumPlaybackChannels > 0 || mNumCaptureChannels > 0) {
1753 
1754 #ifdef REALTIME_ALSA_THREAD
1755  // PRL: Do this in hope of less thread scheduling jitter in calls to
1756  // audacityAudioCallback.
1757  // Not needed to make audio playback work smoothly.
1758  // But needed in case we also play MIDI, so that the variable "offset"
1759  // in AudioIO::MidiTime() is a better approximation of the duration
1760  // between the call of audacityAudioCallback and the actual output of
1761  // the first audio sample.
1762  // (Which we should be able to determine from fields of
1763  // PaStreamCallbackTimeInfo, but that seems not to work as documented with
1764  // ALSA.)
1765  if (mUsingAlsa)
1766  // Perhaps we should do this only if also playing MIDI ?
1767  PaAlsa_EnableRealtimeScheduling( mPortStreamV19, 1 );
1768 #endif
1769 
1770  //
1771  // Generate a unique value each time, to be returned to
1772  // clients accessing the AudioIO API, so they can query if they
1773  // are the ones who have reserved AudioIO or not.
1774  //
1775  // It is important to set this before setting the portaudio stream in
1776  // motion -- otherwise it may play an unspecified number of leading
1777  // zeroes.
1779 
1780  // This affects the AudioThread (not the portaudio callback).
1781  // Probably not needed so urgently before portaudio thread start for usual
1782  // playback, since our ring buffers have been primed already with 4 sec
1783  // of audio, but then we might be scrubbing, so do it.
1785 
1786  // Now start the PortAudio stream!
1787  PaError err;
1788  err = Pa_StartStream( mPortStreamV19 );
1789 
1790  if( err != paNoError )
1791  {
1792  mStreamToken = 0;
1794  if (pListener && mNumCaptureChannels > 0)
1795  pListener->OnAudioIOStopRecording();
1797  // PRL: PortAudio error messages are sadly not internationalized
1799  Verbatim( LAT1CTOWX(Pa_GetErrorText(err)) ) );
1800  return 0;
1801  }
1802  }
1803 
1804  // Update UI display only now, after all possibilities for error are past.
1805  if (pListener) {
1806  // advertise the chosen I/O sample rate to the UI
1807  pListener->OnAudioIORate((int)mRate);
1808  }
1809 
1810  if (mNumPlaybackChannels > 0)
1811  {
1812  wxCommandEvent e(EVT_AUDIOIO_PLAYBACK);
1813  e.SetEventObject(mOwningProject);
1814  e.SetInt(true);
1815  wxTheApp->ProcessEvent(e);
1816  }
1817 
1818  if (mNumCaptureChannels > 0)
1819  {
1820  wxCommandEvent e(EVT_AUDIOIO_CAPTURE);
1821  e.SetEventObject(mOwningProject);
1822  e.SetInt(true);
1823  wxTheApp->ProcessEvent(e);
1824  }
1825 
1826  commit = true;
1827  return mStreamToken;
1828 }
1829 
1831  const AudioIOStartStreamOptions &options,
1832  const TransportTracks &tracks, double t0, double t1, double sampleRate,
1833  bool scrubbing )
1834 {
1835  bool success = false;
1836  auto cleanup = finally([&]{
1837  if (!success) StartStreamCleanup( false );
1838  });
1839 
1840  //
1841  // The (audio) stream has been opened successfully (assuming we tried
1842  // to open it). We now proceed to
1843  // allocate the memory structures the stream will need.
1844  //
1845 
1846  //
1847  // The RingBuffer sizes, and the max amount of the buffer to
1848  // fill at a time, both grow linearly with the number of
1849  // tracks. This allows us to scale up to many tracks without
1850  // killing performance.
1851  //
1852 
1853  // real playback time to produce with each filling of the buffers
1854  // by the Audio thread (except at the end of playback):
1855  // usually, make fillings fewer and longer for less CPU usage.
1856  // But for useful scrubbing, we can't run too far ahead without checking
1857  // mouse input, so make fillings more and shorter.
1858  // What Audio thread produces for playback is then consumed by the PortAudio
1859  // thread, in many smaller pieces.
1860  double playbackTime = 4.0;
1861  if (scrubbing)
1862  // Specify a very short minimum batch for non-seek scrubbing, to allow
1863  // more frequent polling of the mouse
1864  playbackTime =
1865  lrint(options.pScrubbingOptions->delay * mRate) / mRate;
1866 
1867  wxASSERT( playbackTime >= 0 );
1868  mPlaybackSamplesToCopy = playbackTime * mRate;
1869 
1870  // Capacity of the playback buffer.
1871  mPlaybackRingBufferSecs = 10.0;
1872 
1874  4.5 + 0.5 * std::min(size_t(16), mCaptureTracks.size());
1876  0.2 + 0.2 * std::min(size_t(16), mCaptureTracks.size());
1877 
1878  mTimeQueue.mHead = {};
1879  mTimeQueue.mTail = {};
1880  bool bDone;
1881  do
1882  {
1883  bDone = true; // assume success
1884  try
1885  {
1886  if( mNumPlaybackChannels > 0 ) {
1887  // Allocate output buffers. For every output track we allocate
1888  // a ring buffer of ten seconds
1889  auto playbackBufferSize =
1890  (size_t)lrint(mRate * mPlaybackRingBufferSecs);
1891 
1894 
1895  const Mixer::WarpOptions &warpOptions =
1896 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
1897  scrubbing
1901  :
1902 #endif
1904 
1906  if (scrubbing)
1907  // Specify enough playback RingBuffer latency so we can refill
1908  // once every seek stutter without falling behind the demand.
1909  // (Scrub might switch in and out of seeking with left mouse
1910  // presses in the ruler)
1912  2 * options.pScrubbingOptions->minStutterTime * mRate );
1914  std::min( mPlaybackQueueMinimum, playbackBufferSize );
1915 
1916  for (unsigned int i = 0; i < mPlaybackTracks.size(); i++)
1917  {
1918  // Bug 1763 - We must fade in from zero to avoid a click on starting.
1919  mPlaybackTracks[i]->SetOldChannelGain(0, 0.0);
1920  mPlaybackTracks[i]->SetOldChannelGain(1, 0.0);
1921 
1922  mPlaybackBuffers[i] =
1923  std::make_unique<RingBuffer>(floatSample, playbackBufferSize);
1924  const auto timeQueueSize = 1 +
1925  (playbackBufferSize + TimeQueueGrainSize - 1)
1927  mTimeQueue.mData.reinit( timeQueueSize );
1928  mTimeQueue.mSize = timeQueueSize;
1929 
1930  // use track time for the end time, not real time!
1931  WaveTrackConstArray mixTracks;
1932  mixTracks.push_back(mPlaybackTracks[i]);
1933 
1934  double endTime;
1936  .contains(mPlaybackTracks[i]))
1937  // Stop playing this track after pre-roll
1938  endTime = t0;
1939  else
1940  // Pass t1 -- not mT1 as may have been adjusted for latency
1941  // -- so that overdub recording stops playing back samples
1942  // at the right time, though transport may continue to record
1943  endTime = t1;
1944 
1945  mPlaybackMixers[i] = std::make_unique<Mixer>
1946  (mixTracks,
1947  // Don't throw for read errors, just play silence:
1948  false,
1949  warpOptions,
1951  endTime,
1952  1,
1954  false,
1955  mRate, floatSample,
1956  false, // low quality dithering and resampling
1957  nullptr,
1958  false // don't apply track gains
1959  );
1960  }
1961  }
1962 
1963  if( mNumCaptureChannels > 0 )
1964  {
1965  // Allocate input buffers. For every input track we allocate
1966  // a ring buffer of five seconds
1967  auto captureBufferSize =
1968  (size_t)(mRate * mCaptureRingBufferSecs + 0.5);
1969 
1970  // In the extraordinarily rare case that we can't even afford
1971  // 100 samples, just give up.
1972  if(captureBufferSize < 100)
1973  {
1974  AudacityMessageBox( XO("Out of memory!") );
1975  return false;
1976  }
1977 
1980  mFactor = sampleRate / mRate;
1981 
1982  for( unsigned int i = 0; i < mCaptureTracks.size(); i++ )
1983  {
1984  mCaptureBuffers[i] = std::make_unique<RingBuffer>(
1985  mCaptureTracks[i]->GetSampleFormat(), captureBufferSize );
1986  mResample[i] =
1987  std::make_unique<Resample>(true, mFactor, mFactor);
1988  // constant rate resampling
1989  }
1990  }
1991  }
1992  catch(std::bad_alloc&)
1993  {
1994  // Oops! Ran out of memory. This is pretty rare, so we'll just
1995  // try deleting everything, halving our buffer size, and try again.
1996  StartStreamCleanup(true);
1997  mPlaybackRingBufferSecs *= 0.5;
1999  mCaptureRingBufferSecs *= 0.5;
2000  mMinCaptureSecsToCopy *= 0.5;
2001  bDone = false;
2002 
2003  // In the extraordinarily rare case that we can't even afford 100
2004  // samples, just give up.
2005  auto playbackBufferSize =
2006  (size_t)lrint(mRate * mPlaybackRingBufferSecs);
2007  if(playbackBufferSize < 100 || mPlaybackSamplesToCopy < 100)
2008  {
2009  AudacityMessageBox( XO("Out of memory!") );
2010  return false;
2011  }
2012  }
2013  } while(!bDone);
2014 
2015  success = true;
2016  return true;
2017 }
2018 
2019 void AudioIO::StartStreamCleanup(bool bOnlyBuffers)
2020 {
2021  if (mNumPlaybackChannels > 0)
2022  {
2024  }
2025 
2026  mPlaybackBuffers.reset();
2027  mPlaybackMixers.reset();
2028  mCaptureBuffers.reset();
2029  mResample.reset();
2030  mTimeQueue.mData.reset();
2031 
2032  if(!bOnlyBuffers)
2033  {
2034  Pa_AbortStream( mPortStreamV19 );
2035  Pa_CloseStream( mPortStreamV19 );
2036  mPortStreamV19 = NULL;
2037  mStreamToken = 0;
2038  }
2039 
2040 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2041  mScrubState.reset();
2042 #endif
2043 }
2044 
2045 #ifdef EXPERIMENTAL_MIDI_OUT
2046 
2047 PmTimestamp MidiTime(void *WXUNUSED(info))
2048 {
2049  return AudioIO::Get()->MidiTime();
2050 }
2051 
2052 // Set up state to iterate NoteTrack events in sequence.
2053 // Sends MIDI control changes up to the starting point mT0
2054 // if send is true. Output is delayed by offset to facilitate
2055 // looping (each iteration is delayed more).
2056 void AudioIoCallback::PrepareMidiIterator(bool send, double offset)
2057 {
2058  int i;
2059  int nTracks = mMidiPlaybackTracks.size();
2060  // instead of initializing with an Alg_seq, we use begin_seq()
2061  // below to add ALL Alg_seq's.
2062  mIterator = std::make_unique<Alg_iterator>(nullptr, false);
2063  // Iterator not yet initialized, must add each track...
2064  for (i = 0; i < nTracks; i++) {
2065  const auto t = mMidiPlaybackTracks[i].get();
2066  Alg_seq_ptr seq = &t->GetSeq();
2067  // mark sequence tracks as "in use" since we're handing this
2068  // off to another thread and want to make sure nothing happens
2069  // to the data until playback finishes. This is just a sanity check.
2070  seq->set_in_use(true);
2071  mIterator->begin_seq(seq,
2072  // casting away const, but allegro just uses the pointer as an opaque "cookie"
2073  (void*)t, t->GetOffset() + offset);
2074  }
2075  GetNextEvent(); // prime the pump for FillMidiBuffers
2076 
2077  // Start MIDI from current cursor position
2078  mSendMidiState = true;
2079  while (mNextEvent &&
2080  mNextEventTime < mPlaybackSchedule.mT0 + offset) {
2081  if (send) OutputEvent();
2082  GetNextEvent();
2083  }
2084  mSendMidiState = false;
2085 }
2086 
2087 bool AudioIoCallback::StartPortMidiStream()
2088 {
2089  int i;
2090  int nTracks = mMidiPlaybackTracks.size();
2091  // Only start MIDI stream if there is an open track
2092  if (nTracks == 0)
2093  return false;
2094 
2095  //wxPrintf("StartPortMidiStream: mT0 %g mTime %g\n",
2096  // mT0, mTime);
2097 
2098  /* get midi playback device */
2099  PmDeviceID playbackDevice = Pm_GetDefaultOutputDeviceID();
2100  wxString playbackDeviceName = gPrefs->Read(wxT("/MidiIO/PlaybackDevice"),
2101  wxT(""));
2102  mSynthLatency = gPrefs->Read(wxT("/MidiIO/SynthLatency"),
2104  if (wxStrcmp(playbackDeviceName, wxT("")) != 0) {
2105  for (i = 0; i < Pm_CountDevices(); i++) {
2106  const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
2107  if (!info) continue;
2108  if (!info->output) continue;
2109  wxString interf = wxSafeConvertMB2WX(info->interf);
2110  wxString name = wxSafeConvertMB2WX(info->name);
2111  interf.Append(wxT(": ")).Append(name);
2112  if (wxStrcmp(interf, playbackDeviceName) == 0) {
2113  playbackDevice = i;
2114  }
2115  }
2116  } // (else playback device has Pm_GetDefaultOuputDeviceID())
2117 
2118  if (playbackDevice < 0)
2119  return false;
2120 
2121  /* open output device */
2122  mLastPmError = Pm_OpenOutput(&mMidiStream,
2123  playbackDevice,
2124  NULL,
2125  0,
2126  &::MidiTime,
2127  NULL,
2129  if (mLastPmError == pmNoError) {
2130  mMidiStreamActive = true;
2131  mMidiPaused = false;
2132  mMidiLoopPasses = 0;
2133  mMidiOutputComplete = false;
2134  mMaxMidiTimestamp = 0;
2135  PrepareMidiIterator();
2136 
2137  // It is ok to call this now, but do not send timestamped midi
2138  // until after the first audio callback, which provides necessary
2139  // data for MidiTime().
2140  Pm_Synchronize(mMidiStream); // start using timestamps
2141  // start midi output flowing (pending first audio callback)
2142  mMidiThreadFillBuffersLoopRunning = true;
2143  }
2144  return (mLastPmError == pmNoError);
2145 }
2146 #endif
2147 
2149 {
2150  return mOwningProject == NULL || mOwningProject == project;
2151 }
2152 
2154 {
2155  if (mInputMeter)
2156  mInputMeter->Reset(mRate, true);
2157  if (mOutputMeter)
2158  mOutputMeter->Reset(mRate, true);
2159 
2160  mUpdateMeters = true;
2161 }
2162 
2164 {
2165  auto cleanup = finally ( [this] {
2167  mRecordingSchedule.mCrossfadeData.clear(); // free arrays
2168  } );
2169 
2170  if( mPortStreamV19 == NULL
2171 #ifdef EXPERIMENTAL_MIDI_OUT
2172  && mMidiStream == NULL
2173 #endif
2174  )
2175  return;
2176 
2177  if( Pa_IsStreamStopped( mPortStreamV19 )
2178 #ifdef EXPERIMENTAL_MIDI_OUT
2179  && !mMidiStreamActive
2180 #endif
2181  )
2182  return;
2183 
2184 #if (defined(__WXMAC__) || defined(__WXMSW__)) && wxCHECK_VERSION(3,1,0)
2185  // Re-enable system sleep
2186  wxPowerResource::Release(wxPOWER_RESOURCE_SCREEN);
2187 #endif
2188 
2190  {
2191  // PortAudio callback can use the information that we are stopping to fade
2192  // out the audio. Give PortAudio callback a chance to do so.
2194  long latency;
2195  gPrefs->Read( wxT("/AudioIO/LatencyDuration"), &latency, DEFAULT_LATENCY_DURATION );
2196  // If we can gracefully fade out in 200ms, with the faded-out play buffers making it through
2197  // the sound card, then do so. If we can't, don't wait around. Just stop quickly and accept
2198  // there will be a click.
2199  if( mbMicroFades && (latency < 150 ))
2200  wxMilliSleep( latency + 50);
2201  }
2202 
2203  wxMutexLocker locker(mSuspendAudioThread);
2204 
2205  // No longer need effects processing
2206  if (mNumPlaybackChannels > 0)
2207  {
2209  }
2210 
2211  //
2212  // We got here in one of two ways:
2213  //
2214  // 1. The user clicked the stop button and we therefore want to stop
2215  // as quickly as possible. So we use AbortStream(). If this is
2216  // the case the portaudio stream is still in the Running state
2217  // (see PortAudio state machine docs).
2218  //
2219  // 2. The callback told PortAudio to stop the stream since it had
2220  // reached the end of the selection. The UI thread discovered
2221  // this by noticing that AudioIO::IsActive() returned false.
2222  // IsActive() (which calls Pa_GetStreamActive()) will not return
2223  // false until all buffers have finished playing, so we can call
2224  // AbortStream without losing any samples. If this is the case
2225  // we are in the "callback finished state" (see PortAudio state
2226  // machine docs).
2227  //
2228  // The moral of the story: We can call AbortStream safely, without
2229  // losing samples.
2230  //
2231  // DMM: This doesn't seem to be true; it seems to be necessary to
2232  // call StopStream if the callback brought us here, and AbortStream
2233  // if the user brought us here.
2234  //
2235 
2237 
2238  // Audacity can deadlock if it tries to update meters while
2239  // we're stopping PortAudio (because the meter updating code
2240  // tries to grab a UI mutex while PortAudio tries to join a
2241  // pthread). So we tell the callback to stop updating meters,
2242  // and wait until the callback has left this part of the code
2243  // if it was already there.
2244  mUpdateMeters = false;
2245  while(mUpdatingMeters) {
2246  ::wxSafeYield();
2247  wxMilliSleep( 50 );
2248  }
2249 
2250  // Turn off HW playthrough if PortMixer is being used
2251 
2252  #if defined(USE_PORTMIXER)
2253  if( mPortMixer ) {
2254  #if __WXMAC__
2255  if (Px_SupportsPlaythrough(mPortMixer) && mPreviousHWPlaythrough >= 0.0)
2256  Px_SetPlaythrough(mPortMixer, mPreviousHWPlaythrough);
2257  mPreviousHWPlaythrough = -1.0;
2258  #endif
2259  }
2260  #endif
2261 
2262  if (mPortStreamV19) {
2263  Pa_AbortStream( mPortStreamV19 );
2264  Pa_CloseStream( mPortStreamV19 );
2265  mPortStreamV19 = NULL;
2266  }
2267 
2268 #ifdef EXPERIMENTAL_MIDI_OUT
2269  /* Stop Midi playback */
2270  if ( mMidiStream ) {
2271 
2272  mMidiStreamActive = false;
2273 
2274 #ifdef USE_MIDI_THREAD
2275  mMidiThreadFillBuffersLoopRunning = false; // stop output to stream
2276  // but output is in another thread. Wait for output to stop...
2277  while (mMidiThreadFillBuffersLoopActive) {
2278  wxMilliSleep(1);
2279  }
2280 #endif
2281 
2282  mMidiOutputComplete = true;
2283 
2284  // now we can assume "ownership" of the mMidiStream
2285  // if output in progress, send all off, etc.
2286  AllNotesOff();
2287  // AllNotesOff() should be sufficient to stop everything, but
2288  // in Linux, if you Pm_Close() immediately, it looks like
2289  // messages are dropped. ALSA then seems to send All Sound Off
2290  // and Reset All Controllers messages, but not all synthesizers
2291  // respond to these messages. This is probably a bug in PortMidi
2292  // if the All Off messages do not get out, but for security,
2293  // delay a bit so that messages can be delivered before closing
2294  // the stream. Add 2ms of "padding" to avoid any rounding errors.
2295  while (mMaxMidiTimestamp + 2 > MidiTime()) {
2296  wxMilliSleep(1); // deliver the all-off messages
2297  }
2298  Pm_Close(mMidiStream);
2299  mMidiStream = NULL;
2300  mIterator->end();
2301 
2302  // set in_use flags to false
2303  int nTracks = mMidiPlaybackTracks.size();
2304  for (int i = 0; i < nTracks; i++) {
2305  const auto t = mMidiPlaybackTracks[i].get();
2306  Alg_seq_ptr seq = &t->GetSeq();
2307  seq->set_in_use(false);
2308  }
2309 
2310  mIterator.reset(); // just in case someone tries to reference it
2311  }
2312 #endif
2313 
2314  auto pListener = GetListener();
2315 
2316  // If there's no token, we were just monitoring, so we can
2317  // skip this next part...
2318  if (mStreamToken > 0) {
2319  // In either of the above cases, we want to make sure that any
2320  // capture data that made it into the PortAudio callback makes it
2321  // to the target WaveTrack. To do this, we ask the audio thread to
2322  // call FillBuffers one last time (it normally would not do so since
2323  // Pa_GetStreamActive() would now return false
2325 
2327  {
2328  // LLL: Experienced recursive yield here...once.
2329  wxTheApp->Yield(true); // Pass true for onlyIfNeeded to avoid recursive call error.
2330  wxMilliSleep( 50 );
2331  }
2332 
2333  //
2334  // Everything is taken care of. Now, just free all the resources
2335  // we allocated in StartStream()
2336  //
2337 
2338  if (mPlaybackTracks.size() > 0)
2339  {
2340  mPlaybackBuffers.reset();
2341  mPlaybackMixers.reset();
2342  mTimeQueue.mData.reset();
2343  }
2344 
2345  //
2346  // Offset all recorded tracks to account for latency
2347  //
2348  if (mCaptureTracks.size() > 0)
2349  {
2350  mCaptureBuffers.reset();
2351  mResample.reset();
2352 
2353  //
2354  // We only apply latency correction when we actually played back
2355  // tracks during the recording. If we did not play back tracks,
2356  // there's nothing we could be out of sync with. This also covers the
2357  // case that we do not apply latency correction when recording the
2358  // first track in a project.
2359  //
2360 
2361  for (unsigned int i = 0; i < mCaptureTracks.size(); i++) {
2362  // The calls to Flush
2363  // may cause exceptions because of exhaustion of disk space.
2364  // Stop those exceptions here, or else they propagate through too
2365  // many parts of Audacity that are not effects or editing
2366  // operations. GuardedCall ensures that the user sees a warning.
2367 
2368  // Also be sure to Flush each track, at the top of the guarded call,
2369  // relying on the guarantee that the track will be left in a flushed
2370  // state, though the append buffer may be lost.
2371 
2372  GuardedCall( [&] {
2373  WaveTrack* track = mCaptureTracks[i].get();
2374 
2375  // use No-fail-guarantee that track is flushed,
2376  // Partial-guarantee that some initial length of the recording
2377  // is saved.
2378  // See comments in FillBuffers().
2379  track->Flush();
2380  } );
2381  }
2382 
2383 
2384  if (!mLostCaptureIntervals.empty())
2385  {
2386  // This scope may combine many splittings of wave tracks
2387  // into one transaction, lessening the number of checkpoints
2389  if (mOwningProject) {
2390  auto &pIO = ProjectFileIO::Get(*mOwningProject);
2391  pScope.emplace(pIO.GetConnection(), "Dropouts");
2392  }
2393  for (auto &interval : mLostCaptureIntervals) {
2394  auto &start = interval.first;
2395  auto duration = interval.second;
2396  for (auto &track : mCaptureTracks) {
2397  GuardedCall([&] {
2398  track->SyncLockAdjust(start, start + duration);
2399  });
2400  }
2401  }
2402  if (pScope)
2403  pScope->Commit();
2404  }
2405 
2406  if (pListener)
2407  pListener->OnCommitRecording();
2408  }
2409  }
2410 
2411  if (mInputMeter)
2412  mInputMeter->Reset(mRate, false);
2413 
2414  if (mOutputMeter)
2415  mOutputMeter->Reset(mRate, false);
2416 
2417  mInputMeter.Release();
2418  mOutputMeter.Release();
2419  mOwningProject = nullptr;
2420 
2421  if (pListener && mNumCaptureChannels > 0)
2422  pListener->OnAudioIOStopRecording();
2423 
2424  //
2425  // Only set token to 0 after we're totally finished with everything
2426  //
2427  bool wasMonitoring = mStreamToken == 0;
2428  mStreamToken = 0;
2429 
2430  if (mNumPlaybackChannels > 0)
2431  {
2432  wxCommandEvent e(EVT_AUDIOIO_PLAYBACK);
2433  e.SetEventObject(mOwningProject);
2434  e.SetInt(false);
2435  wxTheApp->ProcessEvent(e);
2436  }
2437 
2438  if (mNumCaptureChannels > 0)
2439  {
2440  wxCommandEvent e(wasMonitoring ? EVT_AUDIOIO_MONITOR : EVT_AUDIOIO_CAPTURE);
2441  e.SetEventObject(mOwningProject);
2442  e.SetInt(false);
2443  wxTheApp->ProcessEvent(e);
2444  }
2445 
2446  mNumCaptureChannels = 0;
2448 
2449  mPlaybackTracks.clear();
2450  mCaptureTracks.clear();
2451 #ifdef USE_MIDI
2452  mMidiPlaybackTracks.clear();
2453 #endif
2454 
2455 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2456  mScrubState.reset();
2457 #endif
2458 
2459  if (pListener) {
2460  // Tell UI to hide sample rate
2461  pListener->OnAudioIORate(0);
2462  }
2463 
2464  // Don't cause a busy wait in the audio thread after stopping scrubbing
2466 }
2467 
2468 void AudioIO::SetPaused(bool state)
2469 {
2470  if (state != mPaused)
2471  {
2472  if (state)
2473  {
2475  }
2476  else
2477  {
2479  }
2480  }
2481 
2482  mPaused = state;
2483 }
2484 
2485 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2486 void AudioIO::UpdateScrub
2487  (double endTimeOrSpeed, const ScrubbingOptions &options)
2488 {
2489  if (mScrubState)
2490  mScrubState->Update(endTimeOrSpeed, options);
2491 }
2492 
2493 void AudioIO::StopScrub()
2494 {
2495  if (mScrubState)
2496  mScrubState->Stop();
2497 }
2498 
2499 #if 0
2500 // Only for DRAG_SCRUB
2501 double AudioIO::GetLastScrubTime() const
2502 {
2503  if (mScrubState)
2504  return mScrubState->LastTrackTime();
2505  else
2506  return -1.0;
2507 }
2508 #endif
2509 
2510 #endif
2511 
2512 double AudioIO::GetBestRate(bool capturing, bool playing, double sampleRate)
2513 {
2514  // Check if we can use the cached value
2515  if (mCachedBestRateIn != 0.0 && mCachedBestRateIn == sampleRate
2516  && mCachedBestRatePlaying == playing && mCachedBestRateCapturing == capturing) {
2517  return mCachedBestRateOut;
2518  }
2519 
2520  // In order to cache the value, all early returns should instead set retval
2521  // and jump to finished
2522  double retval;
2523 
2524  std::vector<long> rates;
2525  if (capturing) wxLogDebug(wxT("AudioIO::GetBestRate() for capture"));
2526  if (playing) wxLogDebug(wxT("AudioIO::GetBestRate() for playback"));
2527  wxLogDebug(wxT("GetBestRate() suggested rate %.0lf Hz"), sampleRate);
2528 
2529  if (capturing && !playing) {
2530  rates = GetSupportedCaptureRates(-1, sampleRate);
2531  }
2532  else if (playing && !capturing) {
2533  rates = GetSupportedPlaybackRates(-1, sampleRate);
2534  }
2535  else { // we assume capturing and playing - the alternative would be a
2536  // bit odd
2537  rates = GetSupportedSampleRates(-1, -1, sampleRate);
2538  }
2539  /* rem rates is the array of hardware-supported sample rates (in the current
2540  * configuration), sampleRate is the Project Rate (desired sample rate) */
2541  long rate = (long)sampleRate;
2542 
2543  if (make_iterator_range(rates).contains(rate)) {
2544  wxLogDebug(wxT("GetBestRate() Returning %.0ld Hz"), rate);
2545  retval = rate;
2546  goto finished;
2547  /* the easy case - the suggested rate (project rate) is in the list, and
2548  * we can just accept that and send back to the caller. This should be
2549  * the case for most users most of the time (all of the time on
2550  * Win MME as the OS does resampling) */
2551  }
2552 
2553  /* if we get here, there is a problem - the project rate isn't supported
2554  * on our hardware, so we can't us it. Need to come up with an alternative
2555  * rate to use. The process goes like this:
2556  * * If there are no rates to pick from, we're stuck and return 0 (error)
2557  * * If there are some rates, we pick the next one higher than the requested
2558  * rate to use.
2559  * * If there aren't any higher, we use the highest available rate */
2560 
2561  if (rates.empty()) {
2562  /* we're stuck - there are no supported rates with this hardware. Error */
2563  wxLogDebug(wxT("GetBestRate() Error - no supported sample rates"));
2564  retval = 0.0;
2565  goto finished;
2566  }
2567  int i;
2568  for (i = 0; i < (int)rates.size(); i++) // for each supported rate
2569  {
2570  if (rates[i] > rate) {
2571  // supported rate is greater than requested rate
2572  wxLogDebug(wxT("GetBestRate() Returning next higher rate - %.0ld Hz"), rates[i]);
2573  retval = rates[i];
2574  goto finished;
2575  }
2576  }
2577 
2578  wxLogDebug(wxT("GetBestRate() Returning highest rate - %.0ld Hz"), rates.back());
2579  retval = rates.back(); // the highest available rate
2580  goto finished;
2581 
2582 finished:
2583  mCachedBestRateIn = sampleRate;
2584  mCachedBestRateOut = retval;
2585  mCachedBestRatePlaying = playing;
2586  mCachedBestRateCapturing = capturing;
2587  return retval;
2588 }
2589 
2590 
2592 //
2593 // Audio Thread Context
2594 //
2596 
2597 AudioThread::ExitCode AudioThread::Entry()
2598 {
2599  AudioIO *gAudioIO;
2600  while( !TestDestroy() &&
2601  nullptr != ( gAudioIO = AudioIO::Get() ) )
2602  {
2603  using Clock = std::chrono::steady_clock;
2604  auto loopPassStart = Clock::now();
2605  const auto interval = ScrubPollInterval_ms;
2606 
2607  // Set LoopActive outside the tests to avoid race condition
2608  gAudioIO->mAudioThreadFillBuffersLoopActive = true;
2610  {
2611  gAudioIO->FillBuffers();
2612  gAudioIO->mAudioThreadShouldCallFillBuffersOnce = false;
2613  }
2614  else if( gAudioIO->mAudioThreadFillBuffersLoopRunning )
2615  {
2616  gAudioIO->FillBuffers();
2617  }
2618  gAudioIO->mAudioThreadFillBuffersLoopActive = false;
2619 
2620  if ( gAudioIO->mPlaybackSchedule.Interactive() )
2621  std::this_thread::sleep_until(
2622  loopPassStart + std::chrono::milliseconds( interval ) );
2623  else
2624  Sleep(10);
2625  }
2626 
2627  return 0;
2628 }
2629 
2630 
2631 #ifdef EXPERIMENTAL_MIDI_OUT
2632 MidiThread::ExitCode MidiThread::Entry()
2633 {
2634  AudioIO *gAudioIO;
2635  while( !TestDestroy() &&
2636  nullptr != ( gAudioIO = AudioIO::Get() ) )
2637  {
2638  // Set LoopActive outside the tests to avoid race condition
2639  gAudioIO->mMidiThreadFillBuffersLoopActive = true;
2640  if( gAudioIO->mMidiThreadFillBuffersLoopRunning &&
2641  // mNumFrames signals at least one callback, needed for MidiTime()
2642  gAudioIO->mNumFrames > 0)
2643  {
2644  gAudioIO->FillMidiBuffers();
2645  }
2646  gAudioIO->mMidiThreadFillBuffersLoopActive = false;
2647  Sleep(MIDI_SLEEP);
2648  }
2649  return 0;
2650 }
2651 #endif
2652 
2654 {
2655  auto commonlyAvail = mPlaybackBuffers[0]->AvailForPut();
2656  for (unsigned i = 1; i < mPlaybackTracks.size(); ++i)
2657  commonlyAvail = std::min(commonlyAvail,
2658  mPlaybackBuffers[i]->AvailForPut());
2659  // MB: subtract a few samples because the code in FillBuffers has rounding
2660  // errors
2661  return commonlyAvail - std::min(size_t(10), commonlyAvail);
2662 }
2663 
2665 {
2666  if (mPlaybackTracks.empty())
2667  return 0;
2668 
2669  auto commonlyAvail = mPlaybackBuffers[0]->AvailForGet();
2670  for (unsigned i = 1; i < mPlaybackTracks.size(); ++i)
2671  commonlyAvail = std::min(commonlyAvail,
2672  mPlaybackBuffers[i]->AvailForGet());
2673  return commonlyAvail;
2674 }
2675 
2677 {
2678  auto commonlyAvail = mCaptureBuffers[0]->AvailForGet();
2679  for (unsigned i = 1; i < mCaptureTracks.size(); ++i)
2680  commonlyAvail = std::min(commonlyAvail,
2681  mCaptureBuffers[i]->AvailForGet());
2682  return commonlyAvail;
2683 }
2684 
2685 // This method is the data gateway between the audio thread (which
2686 // communicates with the disk) and the PortAudio callback thread
2687 // (which communicates with the audio device).
2689 {
2690  unsigned int i;
2691 
2692  auto delayedHandler = [this] ( AudacityException * pException ) {
2693  // In the main thread, stop recording
2694  // This is one place where the application handles disk
2695  // exhaustion exceptions from wave track operations, without rolling
2696  // back to the last pushed undo state. Instead, partial recording
2697  // results are pushed as a NEW undo state. For this reason, as
2698  // commented elsewhere, we want an exception safety guarantee for
2699  // the output wave tracks, after the failed append operation, that
2700  // the tracks remain as they were after the previous successful
2701  // (block-level) appends.
2702 
2703  // Note that the Flush in StopStream() may throw another exception,
2704  // but StopStream() contains that exception, and the logic in
2705  // AudacityException::DelayedHandlerAction prevents redundant message
2706  // boxes.
2707  StopStream();
2708  DefaultDelayedHandlerAction{}( pException );
2709  };
2710 
2711  if (mPlaybackTracks.size() > 0)
2712  {
2713  // Though extremely unlikely, it is possible that some buffers
2714  // will have more samples available than others. This could happen
2715  // if we hit this code during the PortAudio callback. To keep
2716  // things simple, we only write as much data as is vacant in
2717  // ALL buffers, and advance the global time by that much.
2718  auto nAvailable = GetCommonlyFreePlayback();
2719 
2720  //
2721  // Don't fill the buffers at all unless we can do the
2722  // full mMaxPlaybackSecsToCopy. This improves performance
2723  // by not always trying to process tiny chunks, eating the
2724  // CPU unnecessarily.
2725  //
2726  // The exception is if we're at the end of the selected
2727  // region - then we should just fill the buffer.
2728  //
2729  // May produce a larger amount when initially priming the buffer, or
2730  // perhaps again later in play to avoid underfilling the queue and falling
2731  // behind the real-time demand on the consumer side in the callback.
2732  auto nReady = GetCommonlyReadyPlayback();
2733  auto nNeeded =
2735 
2736  // wxASSERT( nNeeded <= nAvailable );
2737 
2738  auto realTimeRemaining = mPlaybackSchedule.RealTimeRemaining();
2739  if (nAvailable >= mPlaybackSamplesToCopy ||
2741  nAvailable / mRate >= realTimeRemaining))
2742  {
2743  // Limit maximum buffer size (increases performance)
2744  auto available = std::min( nAvailable,
2745  std::max( nNeeded, mPlaybackSamplesToCopy ) );
2746 
2747  // msmeyer: When playing a very short selection in looped
2748  // mode, the selection must be copied to the buffer multiple
2749  // times, to ensure, that the buffer has a reasonable size
2750  // This is the purpose of this loop.
2751  // PRL: or, when scrubbing, we may get work repeatedly from the
2752  // user interface.
2753  bool done = false;
2754  do {
2755  // How many samples to produce for each channel.
2756  auto frames = available;
2757  bool progress = true;
2758  auto toProcess = frames;
2759 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2761  // scrubbing and play-at-speed are not limited by the real time
2762  // and length accumulators
2763  toProcess =
2764  frames = limitSampleBufferSize(frames, mScrubDuration);
2765  else
2766 #endif
2767  {
2768  double deltat = frames / mRate;
2769  if (deltat > realTimeRemaining)
2770  {
2771  frames = realTimeRemaining * mRate;
2772  toProcess = frames;
2773  // Don't fall into an infinite loop, if loop-playing a selection
2774  // that is so short, it has no samples: detect that case
2775  progress =
2776  !(mPlaybackSchedule.Looping() &&
2777  mPlaybackSchedule.mWarpedTime == 0.0 && frames == 0);
2778  mPlaybackSchedule.RealTimeAdvance( realTimeRemaining );
2779  }
2780  else
2782  realTimeRemaining = mPlaybackSchedule.RealTimeRemaining();
2783  }
2784 
2785  if (!progress)
2786  frames = available, toProcess = 0;
2787 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2788  else if ( mPlaybackSchedule.Interactive() && mSilentScrub)
2789  toProcess = 0;
2790 #endif
2791 
2792  // Update the time queue. This must be done before writing to the
2793  // ring buffers of samples, for proper synchronization with the
2794  // consumer side in the PortAudio thread, which reads the time
2795  // queue after reading the sample queues. The sample queues use
2796  // atomic variables, the time queue doesn't.
2798  (mPlaybackSchedule.Interactive() ? mScrubSpeed : 1.0),
2799  frames);
2800 
2801  for (i = 0; i < mPlaybackTracks.size(); i++)
2802  {
2803  // The mixer here isn't actually mixing: it's just doing
2804  // resampling, format conversion, and possibly time track
2805  // warping
2806  samplePtr warpedSamples;
2807 
2808  if (frames > 0)
2809  {
2810  size_t processed = 0;
2811  if ( toProcess )
2812  processed = mPlaybackMixers[i]->Process( toProcess );
2813  //wxASSERT(processed <= toProcess);
2814  warpedSamples = mPlaybackMixers[i]->GetBuffer();
2815  const auto put = mPlaybackBuffers[i]->Put(
2816  warpedSamples, floatSample, processed, frames - processed);
2817  // wxASSERT(put == frames);
2818  // but we can't assert in this thread
2819  wxUnusedVar(put);
2820  }
2821  }
2822 
2823  available -= frames;
2824  wxASSERT(available >= 0);
2825 
2826  switch (mPlaybackSchedule.mPlayMode)
2827  {
2828 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
2829  case PlaybackSchedule::PLAY_SCRUB:
2830  case PlaybackSchedule::PLAY_AT_SPEED:
2831  case PlaybackSchedule::PLAY_KEYBOARD_SCRUB:
2832  {
2833  mScrubDuration -= frames;
2834  wxASSERT(mScrubDuration >= 0);
2835  done = (available == 0);
2836  if (!done && mScrubDuration <= 0)
2837  {
2838  sampleCount startSample, endSample;
2839  mScrubState->Get(
2840  startSample, endSample, available, mScrubDuration);
2841  if (mScrubDuration < 0)
2842  {
2843  // Can't play anything
2844  // Stop even if we don't fill up available
2845  mScrubDuration = 0;
2846  done = true;
2847  }
2848  else
2849  {
2850  mSilentScrub = (endSample == startSample);
2851  double startTime, endTime;
2852  startTime = startSample.as_double() / mRate;
2853  endTime = endSample.as_double() / mRate;
2854  auto diff = (endSample - startSample).as_long_long();
2855  if (mScrubDuration == 0)
2856  mScrubSpeed = 0;
2857  else
2858  mScrubSpeed =
2859  double(diff) / mScrubDuration.as_double();
2860  if (!mSilentScrub)
2861  {
2862  for (i = 0; i < mPlaybackTracks.size(); i++) {
2863  if (mPlaybackSchedule.mPlayMode == PlaybackSchedule::PLAY_AT_SPEED)
2864  mPlaybackMixers[i]->SetSpeedForPlayAtSpeed(mScrubSpeed);
2865  else if (mPlaybackSchedule.mPlayMode == PlaybackSchedule::PLAY_KEYBOARD_SCRUB)
2866  mPlaybackMixers[i]->SetSpeedForKeyboardScrubbing(mScrubSpeed, startTime);
2867  else
2868  mPlaybackMixers[i]->SetTimesAndSpeed(
2869  startTime, endTime, fabs( mScrubSpeed ));
2870  }
2871  }
2872  mTimeQueue.mLastTime = startTime;
2873  }
2874  }
2875  }
2876  break;
2877 #endif
2879  {
2880  done = !progress || (available == 0);
2881  // msmeyer: If playing looped, check if we are at the end of the buffer
2882  // and if yes, restart from the beginning.
2883  if (realTimeRemaining <= 0)
2884  {
2885  for (i = 0; i < mPlaybackTracks.size(); i++)
2886  mPlaybackMixers[i]->Restart();
2888  realTimeRemaining = mPlaybackSchedule.RealTimeRemaining();
2889  }
2890  }
2891  break;
2892  default:
2893  done = true;
2894  break;
2895  }
2896  } while (!done);
2897  }
2898  } // end of playback buffering
2899 
2900  if (!mRecordingException &&
2901  mCaptureTracks.size() > 0)
2902  GuardedCall( [&] {
2903  // start record buffering
2904  const auto avail = GetCommonlyAvailCapture(); // samples
2905  const auto remainingTime =
2906  std::max(0.0, mRecordingSchedule.ToConsume());
2907  // This may be a very big double number:
2908  const auto remainingSamples = remainingTime * mRate;
2909  bool latencyCorrected = true;
2910 
2911  double deltat = avail / mRate;
2912 
2914  deltat >= mMinCaptureSecsToCopy)
2915  {
2916  // This scope may combine many appendings of wave tracks,
2917  // and also an autosave, into one transaction,
2918  // lessening the number of checkpoints
2920  if (mOwningProject) {
2921  auto &pIO = ProjectFileIO::Get(*mOwningProject);
2922  pScope.emplace(pIO.GetConnection(), "Recording");
2923  }
2924 
2925  bool newBlocks = false;
2926 
2927  // Append captured samples to the end of the WaveTracks.
2928  // The WaveTracks have their own buffering for efficiency.
2929  auto numChannels = mCaptureTracks.size();
2930 
2931  for( i = 0; i < numChannels; i++ )
2932  {
2933  sampleFormat trackFormat = mCaptureTracks[i]->GetSampleFormat();
2934 
2935  size_t discarded = 0;
2936 
2938  const auto correction = mRecordingSchedule.TotalCorrection();
2939  if (correction >= 0) {
2940  // Rightward shift
2941  // Once only (per track per recording), insert some initial
2942  // silence.
2943  size_t size = floor( correction * mRate * mFactor);
2944  SampleBuffer temp(size, trackFormat);
2945  ClearSamples(temp.ptr(), trackFormat, 0, size);
2946  mCaptureTracks[i]->Append(temp.ptr(), trackFormat, size, 1);
2947  }
2948  else {
2949  // Leftward shift
2950  // discard some samples from the ring buffers.
2951  size_t size = floor(
2953 
2954  // The ring buffer might have grown concurrently -- don't discard more
2955  // than the "avail" value noted above.
2956  discarded = mCaptureBuffers[i]->Discard(std::min(avail, size));
2957 
2958  if (discarded < size)
2959  // We need to visit this again to complete the
2960  // discarding.
2961  latencyCorrected = false;
2962  }
2963  }
2964 
2965  const float *pCrossfadeSrc = nullptr;
2966  size_t crossfadeStart = 0, totalCrossfadeLength = 0;
2967  if (i < mRecordingSchedule.mCrossfadeData.size())
2968  {
2969  // Do crossfading
2970  // The supplied crossfade samples are at the same rate as the track
2971  const auto &data = mRecordingSchedule.mCrossfadeData[i];
2972  totalCrossfadeLength = data.size();
2973  if (totalCrossfadeLength) {
2974  crossfadeStart =
2975  floor(mRecordingSchedule.Consumed() * mCaptureTracks[i]->GetRate());
2976  if (crossfadeStart < totalCrossfadeLength)
2977  pCrossfadeSrc = data.data() + crossfadeStart;
2978  }
2979  }
2980 
2981  wxASSERT(discarded <= avail);
2982  size_t toGet = avail - discarded;
2983  SampleBuffer temp;
2984  size_t size;
2986  if( mFactor == 1.0 )
2987  {
2988  // Take captured samples directly
2989  size = toGet;
2990  if (pCrossfadeSrc)
2991  // Change to float for crossfade calculation
2992  format = floatSample;
2993  else
2994  format = trackFormat;
2995  temp.Allocate(size, format);
2996  const auto got =
2997  mCaptureBuffers[i]->Get(temp.ptr(), format, toGet);
2998  // wxASSERT(got == toGet);
2999  // but we can't assert in this thread
3000  wxUnusedVar(got);
3001  if (double(size) > remainingSamples)
3002  size = floor(remainingSamples);
3003  }
3004  else
3005  {
3006  size = lrint(toGet * mFactor);
3007  format = floatSample;
3008  SampleBuffer temp1(toGet, floatSample);
3009  temp.Allocate(size, format);
3010  const auto got =
3011  mCaptureBuffers[i]->Get(temp1.ptr(), floatSample, toGet);
3012  // wxASSERT(got == toGet);
3013  // but we can't assert in this thread
3014  wxUnusedVar(got);
3015  /* we are re-sampling on the fly. The last resampling call
3016  * must flush any samples left in the rate conversion buffer
3017  * so that they get recorded
3018  */
3019  if (toGet > 0 ) {
3020  if (double(toGet) > remainingSamples)
3021  toGet = floor(remainingSamples);
3022  const auto results =
3023  mResample[i]->Process(mFactor, (float *)temp1.ptr(), toGet,
3024  !IsStreamActive(), (float *)temp.ptr(), size);
3025  size = results.second;
3026  }
3027  }
3028 
3029  if (pCrossfadeSrc) {
3030  wxASSERT(format == floatSample);
3031  size_t crossfadeLength = std::min(size, totalCrossfadeLength - crossfadeStart);
3032  if (crossfadeLength) {
3033  auto ratio = double(crossfadeStart) / totalCrossfadeLength;
3034  auto ratioStep = 1.0 / totalCrossfadeLength;
3035  auto pCrossfadeDst = (float*)temp.ptr();
3036 
3037  // Crossfade loop here
3038  for (size_t ii = 0; ii < crossfadeLength; ++ii) {
3039  *pCrossfadeDst = ratio * *pCrossfadeDst + (1.0 - ratio) * *pCrossfadeSrc;
3040  ++pCrossfadeSrc, ++pCrossfadeDst;
3041  ratio += ratioStep;
3042  }
3043  }
3044  }
3045 
3046  // Now append
3047  // see comment in second handler about guarantee
3048  newBlocks = mCaptureTracks[i]->Append(temp.ptr(), format, size, 1)
3049  || newBlocks;
3050  } // end loop over capture channels
3051 
3052  // Now update the recording schedule position
3053  mRecordingSchedule.mPosition += avail / mRate;
3054  mRecordingSchedule.mLatencyCorrected = latencyCorrected;
3055 
3056  auto pListener = GetListener();
3057  if (pListener && newBlocks)
3058  pListener->OnAudioIONewBlocks(&mCaptureTracks);
3059 
3060  if (pScope)
3061  pScope->Commit();
3062  }
3063  // end of record buffering
3064  },
3065  // handler
3066  [this] ( AudacityException *pException ) {
3067  if ( pException ) {
3068  // So that we don't attempt to fill the recording buffer again
3069  // before the main thread stops recording
3071  return ;
3072  }
3073  else
3074  // Don't want to intercept other exceptions (?)
3075  throw;
3076  },
3077  delayedHandler
3078  );
3079 }
3080 
3082  const std::shared_ptr< AudioIOListener > &listener)
3083 {
3084  if (IsBusy())
3085  return;
3086 
3087  mListener = listener;
3088 }
3089 
3090 #ifdef EXPERIMENTAL_MIDI_OUT
3091 
3092 static Alg_update gAllNotesOff; // special event for loop ending
3093 // the fields of this event are never used, only the address is important
3094 
3095 double AudioIoCallback::UncorrectedMidiEventTime()
3096 {
3097  double time;
3099  time =
3100  mPlaybackSchedule.RealDuration(mNextEventTime - MidiLoopOffset())
3101  + mPlaybackSchedule.mT0 + (mMidiLoopPasses *
3103  else
3104  time = mNextEventTime;
3105 
3106  return time + PauseTime();
3107 }
3108 
3109 void AudioIoCallback::OutputEvent()
3110 {
3111  int channel = (mNextEvent->chan) & 0xF; // must be in [0..15]
3112  int command = -1;
3113  int data1 = -1;
3114  int data2 = -1;
3115 
3116  double eventTime = UncorrectedMidiEventTime();
3117 
3118  // 0.0005 is for rounding
3119  double time = eventTime + 0.0005 -
3120  (mSynthLatency * 0.001);
3121 
3122  time += 1; // MidiTime() has a 1s offset
3123  // state changes have to go out without delay because the
3124  // midi stream time gets reset when playback starts, and
3125  // we don't want to leave any control changes scheduled for later
3126  if (time < 0 || mSendMidiState) time = 0;
3127  PmTimestamp timestamp = (PmTimestamp) (time * 1000); /* s to ms */
3128 
3129  // The special event gAllNotesOff means "end of playback, send
3130  // all notes off on all channels"
3131  if (mNextEvent == &gAllNotesOff) {
3132  bool looping = mPlaybackSchedule.Looping();
3133  AllNotesOff(looping);
3134  if (looping) {
3135  // jump back to beginning of loop
3136  ++mMidiLoopPasses;
3137  PrepareMidiIterator(false, MidiLoopOffset());
3138  } else {
3139  mNextEvent = NULL;
3140  }
3141  return;
3142  }
3143 
3144  // if mNextEvent's channel is visible, play it, visibility can
3145  // be updated while playing. Be careful: if we have a note-off,
3146  // then we must not pay attention to the channel selection
3147  // or mute/solo buttons because we must turn the note off
3148  // even if the user changed something after the note began
3149  // Note that because multiple tracks can output to the same
3150  // MIDI channels, it is not a good idea to send "All Notes Off"
3151  // when the user presses the mute button. We have no easy way
3152  // to know what notes are sounding on any given muted track, so
3153  // we'll just wait for the note-off events to happen.
3154  // Also note that note-offs are only sent when we call
3155  // mIterator->request_note_off(), so notes that are not played
3156  // will not generate random note-offs. There is the interesting
3157  // case that if the playback is paused, all-notes-off WILL be sent
3158  // and if playback resumes, the pending note-off events WILL also
3159  // be sent (but if that is a problem, there would also be a problem
3160  // in the non-pause case.
3161  if (((mNextEventTrack->IsVisibleChan(channel)) &&
3162  // only play if note is not muted:
3163  !((mHasSolo || mNextEventTrack->GetMute()) &&
3164  !mNextEventTrack->GetSolo())) ||
3165  (mNextEvent->is_note() && !mNextIsNoteOn)) {
3166  // Note event
3167  if (mNextEvent->is_note() && !mSendMidiState) {
3168  // Pitch and velocity
3169  data1 = mNextEvent->get_pitch();
3170  if (mNextIsNoteOn) {
3171  data2 = mNextEvent->get_loud(); // get velocity
3172  int offset = mNextEventTrack->GetVelocity();
3173  data2 += offset; // offset comes from per-track slider
3174  // clip velocity to insure a legal note-on value
3175  data2 = (data2 < 1 ? 1 : (data2 > 127 ? 127 : data2));
3176  // since we are going to play this note, we need to get a note_off
3177  mIterator->request_note_off();
3178 
3179 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
3180  mPendingNotesOff.push_back(std::make_pair(channel, data1));
3181 #endif
3182  }
3183  else {
3184  data2 = 0; // 0 velocity means "note off"
3185 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
3186  auto end = mPendingNotesOff.end();
3187  auto iter = std::find(
3188  mPendingNotesOff.begin(), end, std::make_pair(channel, data1) );
3189  if (iter != end)
3190  mPendingNotesOff.erase(iter);
3191 #endif
3192  }
3193  command = 0x90; // MIDI NOTE ON (or OFF when velocity == 0)
3194  // Update event
3195  } else if (mNextEvent->is_update()) {
3196  // this code is based on allegrosmfwr.cpp -- it could be improved
3197  // by comparing attribute pointers instead of string compares
3198  Alg_update_ptr update = (Alg_update_ptr) mNextEvent;
3199  const char *name = update->get_attribute();
3200 
3201  if (!strcmp(name, "programi")) {
3202  // Instrument change
3203  data1 = update->parameter.i;
3204  data2 = 0;
3205  command = 0xC0; // MIDI PROGRAM CHANGE
3206  } else if (!strncmp(name, "control", 7)) {
3207  // Controller change
3208 
3209  // The number of the controller being changed is embedded
3210  // in the parameter name.
3211  data1 = atoi(name + 7);
3212  // Allegro normalizes controller values
3213  data2 = ROUND(update->parameter.r * 127);
3214  command = 0xB0;
3215  } else if (!strcmp(name, "bendr")) {
3216  // Bend change
3217 
3218  // Reverse Allegro's post-processing of bend values
3219  int temp = ROUND(0x2000 * (update->parameter.r + 1));
3220  if (temp > 0x3fff) temp = 0x3fff; // 14 bits maximum
3221  if (temp < 0) temp = 0;
3222  data1 = temp & 0x7f; // low 7 bits
3223  data2 = temp >> 7; // high 7 bits
3224  command = 0xE0; // MIDI PITCH BEND
3225  } else if (!strcmp(name, "pressurer")) {
3226  // Pressure change
3227  data1 = (int) (update->parameter.r * 127);
3228  if (update->get_identifier() < 0) {
3229  // Channel pressure
3230  data2 = 0;
3231  command = 0xD0; // MIDI CHANNEL PRESSURE
3232  } else {
3233  // Key pressure
3234  data2 = data1;
3235  data1 = update->get_identifier();
3236  command = 0xA0; // MIDI POLY PRESSURE
3237  }
3238  }
3239  }
3240  if (command != -1) {
3241  // keep track of greatest timestamp used
3242  if (timestamp > mMaxMidiTimestamp) {
3243  mMaxMidiTimestamp = timestamp;
3244  }
3245  Pm_WriteShort(mMidiStream, timestamp,
3246  Pm_Message((int) (command + channel),
3247  (long) data1, (long) data2));
3248  /* wxPrintf("Pm_WriteShort %lx (%p) @ %d, advance %d\n",
3249  Pm_Message((int) (command + channel),
3250  (long) data1, (long) data2),
3251  mNextEvent, timestamp, timestamp - Pt_Time()); */
3252  }
3253  }
3254 }
3255 
3256 void AudioIoCallback::GetNextEvent()
3257 {
3258  mNextEventTrack = NULL; // clear it just to be safe
3259  // now get the next event and the track from which it came
3260  double nextOffset;
3261  if (!mIterator) {
3262  mNextEvent = NULL;
3263  return;
3264  }
3265  auto midiLoopOffset = MidiLoopOffset();
3266  mNextEvent = mIterator->next(&mNextIsNoteOn,
3267  (void **) &mNextEventTrack,
3268  &nextOffset, mPlaybackSchedule.mT1 + midiLoopOffset);
3269 
3270  mNextEventTime = mPlaybackSchedule.mT1 + midiLoopOffset + 1;
3271  if (mNextEvent) {
3272  mNextEventTime = (mNextIsNoteOn ? mNextEvent->time :
3273  mNextEvent->get_end_time()) + nextOffset;;
3274  }
3275  if (mNextEventTime > (mPlaybackSchedule.mT1 + midiLoopOffset)){ // terminate playback at mT1
3276  mNextEvent = &gAllNotesOff;
3277  mNextEventTime = mPlaybackSchedule.mT1 + midiLoopOffset - ALG_EPS;
3278  mNextIsNoteOn = true; // do not look at duration
3279  mIterator->end();
3280  mIterator.reset(); // debugging aid
3281  }
3282 }
3283 
3284 
3285 bool AudioIoCallback::SetHasSolo(bool hasSolo)
3286 {
3287  mHasSolo = hasSolo;
3288  return mHasSolo;
3289 }
3290 
3291 
3292 void AudioIoCallback::FillMidiBuffers()
3293 {
3294  // Keep track of time paused. If not paused, fill buffers.
3295  if (IsPaused()) {
3296  if (!mMidiPaused) {
3297  mMidiPaused = true;
3298  AllNotesOff(); // to avoid hanging notes during pause
3299  }
3300  return;
3301  }
3302 
3303  if (mMidiPaused) {
3304  mMidiPaused = false;
3305  }
3306 
3307  //---- Duplicated code -----
3308  // TODO this code is duplicated. Look for mbHasSoloTracks.
3309  bool hasSolo = false;
3310  auto numPlaybackTracks = mPlaybackTracks.size();
3311  for(unsigned t = 0; t < numPlaybackTracks; t++ )
3312  if( mPlaybackTracks[t]->GetSolo() ) {
3313  hasSolo = true;
3314  break;
3315  }
3316  auto numMidiPlaybackTracks = mMidiPlaybackTracks.size();
3317  for(unsigned t = 0; t < numMidiPlaybackTracks; t++ )
3318  if( mMidiPlaybackTracks[t]->GetSolo() ) {
3319  hasSolo = true;
3320  break;
3321  }
3322  SetHasSolo(hasSolo);
3323  //---- End duplicated code -----
3324 
3325 
3326  // If we compute until mNextEventTime > current audio time,
3327  // we would have a built-in compute-ahead of mAudioOutLatency, and
3328  // it's probably good to compute MIDI when we compute audio (so when
3329  // we stop, both stop about the same time).
3330  double time = AudioTime(); // compute to here
3331  // But if mAudioOutLatency is very low, we might need some extra
3332  // compute-ahead to deal with mSynthLatency or even this thread.
3333  double actual_latency = (MIDI_SLEEP + THREAD_LATENCY +
3334  MIDI_MINIMAL_LATENCY_MS + mSynthLatency) * 0.001;
3335  if (actual_latency > mAudioOutLatency) {
3336  time += actual_latency - mAudioOutLatency;
3337  }
3338  while (mNextEvent &&
3339  UncorrectedMidiEventTime() < time) {
3340  OutputEvent();
3341  GetNextEvent();
3342  }
3343 }
3344 
3345 double AudioIoCallback::PauseTime()
3346 {
3347  return mNumPauseFrames / mRate;
3348 }
3349 
3350 
3351 // MidiTime() is an estimate in milliseconds of the current audio
3352 // output (DAC) time + 1s. In other words, what audacity track time
3353 // corresponds to the audio (including pause insertions) at the output?
3354 //
3355 PmTimestamp AudioIoCallback::MidiTime()
3356 {
3357  // note: the extra 0.0005 is for rounding. Round down by casting to
3358  // unsigned long, then convert to PmTimeStamp (currently signed)
3359 
3360  // PRL: the time correction is really Midi latency achieved by different
3361  // means than specifying it to Pm_OpenStream. The use of the accumulated
3362  // sample count generated by the audio callback (in AudioTime()) might also
3363  // have the virtue of keeping the Midi output synched with audio.
3364 
3365  PmTimestamp ts;
3366  // subtract latency here because mSystemMinusAudioTime gets us
3367  // to the current *write* time, but we're writing ahead by audio output
3368  // latency (mAudioOutLatency).
3369  double now = SystemTime(mUsingAlsa);
3370  ts = (PmTimestamp) ((unsigned long)
3371  (1000 * (now + 1.0005 -
3372  mSystemMinusAudioTimePlusLatency)));
3373  // wxPrintf("AudioIO::MidiTime() %d time %g sys-aud %g\n",
3374  // ts, now, mSystemMinusAudioTime);
3375  return ts + MIDI_MINIMAL_LATENCY_MS;
3376 }
3377 
3378 
3379 void AudioIoCallback::AllNotesOff(bool looping)
3380 {
3381 #ifdef __WXGTK__
3382  bool doDelay = !looping;
3383 #else
3384  bool doDelay = false;
3385  static_cast<void>(looping);// compiler food.
3386 #endif
3387 
3388  // to keep track of when MIDI should all be delivered,
3389  // update mMaxMidiTimestamp to now:
3390  PmTimestamp now = MidiTime();
3391  if (mMaxMidiTimestamp < now) {
3392  mMaxMidiTimestamp = now;
3393  }
3394 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
3395  // PRL:
3396  // Send individual note-off messages for each note-on not yet paired.
3397 
3398  // RBD:
3399  // Even this did not work as planned. My guess is ALSA does not use
3400  // a "stable sort" for timed messages, so that when a note-off is
3401  // added later at the same time as a future note-on, the order is
3402  // not respected, and the note-off can go first, leaving a stuck note.
3403  // The workaround here is to use mMaxMidiTimestamp to ensure that
3404  // note-offs come at least 1ms later than any previous message
3405 
3406  // PRL:
3407  // I think we should do that only when stopping or pausing, not when looping
3408  // Note that on Linux, MIDI always uses ALSA, no matter whether portaudio
3409  // uses some other host api.
3410 
3411  mMaxMidiTimestamp += 1;
3412  for (const auto &pair : mPendingNotesOff) {
3413  Pm_WriteShort(mMidiStream,
3414  (doDelay ? mMaxMidiTimestamp : 0),
3415  Pm_Message(
3416  0x90 + pair.first, pair.second, 0));
3417  mMaxMidiTimestamp++; // allow 1ms per note-off
3418  }
3419  mPendingNotesOff.clear();
3420 
3421  // Proceed to do the usual messages too.
3422 #endif
3423 
3424  for (int chan = 0; chan < 16; chan++) {
3425  Pm_WriteShort(mMidiStream,
3426  (doDelay ? mMaxMidiTimestamp : 0),
3427  Pm_Message(0xB0 + chan, 0x7B, 0));
3428  mMaxMidiTimestamp++; // allow 1ms per all-notes-off
3429  }
3430 }
3431 
3432 #endif
3433 
3434 // Automated Input Level Adjustment - Automatically tries to find an acceptable input volume
3435 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
3436 
3437 #include "ProjectStatus.h"
3438 
3439 void AudioIO::AILAInitialize() {
3440  gPrefs->Read(wxT("/AudioIO/AutomatedInputLevelAdjustment"), &mAILAActive, false);
3441  gPrefs->Read(wxT("/AudioIO/TargetPeak"), &mAILAGoalPoint, AILA_DEF_TARGET_PEAK);
3442  gPrefs->Read(wxT("/AudioIO/DeltaPeakVolume"), &mAILAGoalDelta, AILA_DEF_DELTA_PEAK);
3443  gPrefs->Read(wxT("/AudioIO/AnalysisTime"), &mAILAAnalysisTime, AILA_DEF_ANALYSIS_TIME);
3444  gPrefs->Read(wxT("/AudioIO/NumberAnalysis"), &mAILATotalAnalysis, AILA_DEF_NUMBER_ANALYSIS);
3445  mAILAGoalDelta /= 100.0;
3446  mAILAGoalPoint /= 100.0;
3447  mAILAAnalysisTime /= 1000.0;
3448  mAILAMax = 0.0;
3449  mAILALastStartTime = max(0.0, mPlaybackSchedule.mT0);
3450  mAILAClipped = false;
3451  mAILAAnalysisCounter = 0;
3452  mAILAChangeFactor = 1.0;
3453  mAILALastChangeType = 0;
3454  mAILATopLevel = 1.0;
3455  mAILAAnalysisEndTime = -1.0;
3456 }
3457 
3458 void AudioIO::AILADisable() {
3459  mAILAActive = false;
3460 }
3461 
3462 bool AudioIO::AILAIsActive() {
3463  return mAILAActive;
3464 }
3465 
3466 void AudioIO::AILASetStartTime() {
3467  mAILAAbsolutStartTime = Pa_GetStreamTime(mPortStreamV19);
3468  wxPrintf("START TIME %f\n\n", mAILAAbsolutStartTime);
3469 }
3470 
3471 double AudioIO::AILAGetLastDecisionTime() {
3472  return mAILAAnalysisEndTime;
3473 }
3474 
3475 void AudioIO::AILAProcess(double maxPeak) {
3476  AudacityProject *const proj = mOwningProject;
3477  if (proj && mAILAActive) {
3478  if (mInputMeter && mInputMeter->IsClipping()) {
3479  mAILAClipped = true;
3480  wxPrintf("clipped");
3481  }
3482 
3483  mAILAMax = max(mAILAMax, maxPeak);
3484 
3485  if ((mAILATotalAnalysis == 0 || mAILAAnalysisCounter < mAILATotalAnalysis) && mPlaybackSchedule.GetTrackTime() - mAILALastStartTime >= mAILAAnalysisTime) {
3486  auto ToLinearIfDB = [](double value, int dbRange) {
3487  if (dbRange >= 0)
3488  value = pow(10.0, (-(1.0-value) * dbRange)/20.0);
3489  return value;
3490  };
3491 
3492  putchar('\n');
3493  mAILAMax = mInputMeter ? ToLinearIfDB(mAILAMax, mInputMeter->GetDBRange()) : 0.0;
3494  double iv = (double) Px_GetInputVolume(mPortMixer);
3495  unsigned short changetype = 0; //0 - no change, 1 - increase change, 2 - decrease change
3496  wxPrintf("mAILAAnalysisCounter:%d\n", mAILAAnalysisCounter);
3497  wxPrintf("\tmAILAClipped:%d\n", mAILAClipped);
3498  wxPrintf("\tmAILAMax (linear):%f\n", mAILAMax);
3499  wxPrintf("\tmAILAGoalPoint:%f\n", mAILAGoalPoint);
3500  wxPrintf("\tmAILAGoalDelta:%f\n", mAILAGoalDelta);
3501  wxPrintf("\tiv:%f\n", iv);
3502  wxPrintf("\tmAILAChangeFactor:%f\n", mAILAChangeFactor);
3503  if (mAILAClipped || mAILAMax > mAILAGoalPoint + mAILAGoalDelta) {
3504  wxPrintf("too high:\n");
3505  mAILATopLevel = min(mAILATopLevel, iv);
3506  wxPrintf("\tmAILATopLevel:%f\n", mAILATopLevel);
3507  //if clipped or too high
3508  if (iv <= LOWER_BOUND) {
3509  //we can't improve it more now
3510  if (mAILATotalAnalysis != 0) {
3511  mAILAActive = false;
3512  ProjectStatus::Get( *proj ).Set(
3513  XO(
3514 "Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too high.") );
3515  }
3516  wxPrintf("\talready min vol:%f\n", iv);
3517  }
3518  else {
3519  float vol = (float) max(LOWER_BOUND, iv+(mAILAGoalPoint-mAILAMax)*mAILAChangeFactor);
3520  Px_SetInputVolume(mPortMixer, vol);
3521  auto msg = XO(
3522 "Automated Recording Level Adjustment decreased the volume to %f.").Format( vol );
3523  ProjectStatus::Get( *proj ).Set(msg);
3524  changetype = 1;
3525  wxPrintf("\tnew vol:%f\n", vol);
3526  float check = Px_GetInputVolume(mPortMixer);
3527  wxPrintf("\tverified %f\n", check);
3528  }
3529  }
3530  else if ( mAILAMax < mAILAGoalPoint - mAILAGoalDelta ) {
3531  //if too low
3532  wxPrintf("too low:\n");
3533  if (iv >= UPPER_BOUND || iv + 0.005 > mAILATopLevel) { //condition for too low volumes and/or variable volumes that cause mAILATopLevel to decrease too much
3534  //we can't improve it more
3535  if (mAILATotalAnalysis != 0) {
3536  mAILAActive = false;
3537  ProjectStatus::Get( *proj ).Set(
3538  XO(
3539 "Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too low.") );
3540  }
3541  wxPrintf("\talready max vol:%f\n", iv);
3542  }
3543  else {
3544  float vol = (float) min(UPPER_BOUND, iv+(mAILAGoalPoint-mAILAMax)*mAILAChangeFactor);
3545  if (vol > mAILATopLevel) {
3546  vol = (iv + mAILATopLevel)/2.0;
3547  wxPrintf("\tTruncated vol:%f\n", vol);
3548  }
3549  Px_SetInputVolume(mPortMixer, vol);
3550  auto msg = XO(
3551 "Automated Recording Level Adjustment increased the volume to %.2f.")
3552  .Format( vol );
3553  ProjectStatus::Get( *proj ).Set(msg);
3554  changetype = 2;
3555  wxPrintf("\tnew vol:%f\n", vol);
3556  float check = Px_GetInputVolume(mPortMixer);
3557  wxPrintf("\tverified %f\n", check);
3558  }
3559  }
3560 
3561  mAILAAnalysisCounter++;
3562  //const PaStreamInfo* info = Pa_GetStreamInfo(mPortStreamV19);
3563  //double latency = 0.0;
3564  //if (info)
3565  // latency = info->inputLatency;
3566  //mAILAAnalysisEndTime = mTime+latency;
3567  mAILAAnalysisEndTime = Pa_GetStreamTime(mPortStreamV19) - mAILAAbsolutStartTime;
3568  mAILAMax = 0;
3569  wxPrintf("\tA decision was made @ %f\n", mAILAAnalysisEndTime);
3570  mAILAClipped = false;
3571  mAILALastStartTime = mPlaybackSchedule.GetTrackTime();
3572 
3573  if (changetype == 0)
3574  mAILAChangeFactor *= 0.8; //time factor
3575  else if (mAILALastChangeType == changetype)
3576  mAILAChangeFactor *= 1.1; //concordance factor
3577  else
3578  mAILAChangeFactor *= 0.7; //discordance factor
3579  mAILALastChangeType = changetype;
3580  putchar('\n');
3581  }
3582 
3583  if (mAILAActive && mAILATotalAnalysis != 0 && mAILAAnalysisCounter >= mAILATotalAnalysis) {
3584  mAILAActive = false;
3585  if (mAILAMax > mAILAGoalPoint + mAILAGoalDelta)
3586  ProjectStatus::Get( *proj ).Set(
3587  XO(
3588 "Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too high.") );
3589  else if (mAILAMax < mAILAGoalPoint - mAILAGoalDelta)
3590  ProjectStatus::Get( *proj ).Set(
3591  XO(
3592 "Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too low.") );
3593  else {
3594  auto msg = XO(
3595 "Automated Recording Level Adjustment stopped. %.2f seems an acceptable volume.")
3596  .Format( Px_GetInputVolume(mPortMixer) );
3597  ProjectStatus::Get( *proj ).Set(msg);
3598  }
3599  }
3600  }
3601 }
3602 #endif
3603 
3605 //
3606 // PortAudio callback thread context
3607 //
3609 
3610 #define MAX(a,b) ((a) > (b) ? (a) : (b))
3611 
3612 static void DoSoftwarePlaythrough(const void *inputBuffer,
3613  sampleFormat inputFormat,
3614  unsigned inputChannels,
3615  float *outputBuffer,
3616  int len)
3617 {
3618  for (unsigned int i=0; i < inputChannels; i++) {
3619  samplePtr inputPtr = ((samplePtr)inputBuffer) + (i * SAMPLE_SIZE(inputFormat));
3620  samplePtr outputPtr = ((samplePtr)outputBuffer) + (i * SAMPLE_SIZE(floatSample));
3621 
3622  CopySamples(inputPtr, inputFormat,
3623  (samplePtr)outputPtr, floatSample,
3624  len, true, inputChannels, 2);
3625  }
3626 
3627  // One mono input channel goes to both output channels...
3628  if (inputChannels == 1)
3629  for (int i=0; i < len; i++)
3630  outputBuffer[2*i + 1] = outputBuffer[2*i];
3631 }
3632 
3633 int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
3634  unsigned long framesPerBuffer,
3635  const PaStreamCallbackTimeInfo *timeInfo,
3636  const PaStreamCallbackFlags statusFlags, void *userData )
3637 {
3638  auto gAudioIO = AudioIO::Get();
3639  return gAudioIO->AudioCallback(
3640  inputBuffer, outputBuffer, framesPerBuffer,
3641  timeInfo, statusFlags, userData);
3642 }
3643 
3644 
3646  const PaStreamCallbackTimeInfo *timeInfo,
3647  unsigned long framesPerBuffer
3648  )
3649 {
3650 #ifdef EXPERIMENTAL_MIDI_OUT
3651  if (mCallbackCount++ == 0) {
3652  // This is effectively mSystemMinusAudioTime when the buffer is empty:
3653  mStartTime = SystemTime(mUsingAlsa) - mPlaybackSchedule.mT0;
3654  // later, mStartTime - mSystemMinusAudioTime will tell us latency
3655  }
3656 
3657  /* for Linux, estimate a smooth audio time as a slowly-changing
3658  offset from system time */
3659  // rnow is system time as a double to simplify math
3660  double rnow = SystemTime(mUsingAlsa);
3661  // anow is next-sample-to-be-computed audio time as a double
3662  double anow = AudioTime();
3663 
3664  if (mUsingAlsa) {
3665  // timeInfo's fields are not all reliable.
3666 
3667  // enow is audio time estimated from our clock synchronization protocol,
3668  // which produces mSystemMinusAudioTime. But we want the estimate
3669  // to drift low, so we steadily increase mSystemMinusAudioTime to
3670  // simulate a fast system clock or a slow audio clock. If anow > enow,
3671  // we'll update mSystemMinusAudioTime to keep in sync. (You might think
3672  // we could just use anow as the "truth", but it has a lot of jitter,
3673  // so we are using enow to smooth out this jitter, in fact to < 1ms.)
3674  // Add worst-case clock drift using previous framesPerBuffer:
3675  const auto increase =
3676  mAudioFramesPerBuffer * 0.0002 / mRate;
3677  mSystemMinusAudioTime += increase;
3678  mSystemMinusAudioTimePlusLatency += increase;
3679  double enow = rnow - mSystemMinusAudioTime;
3680 
3681 
3682  // now, use anow instead if it is ahead of enow
3683  if (anow > enow) {
3684  mSystemMinusAudioTime = rnow - anow;
3685  // Update our mAudioOutLatency estimate during the first 20 callbacks.
3686  // During this period, the buffer should fill. Once we have a good
3687  // estimate of mSystemMinusAudioTime (expected in fewer than 20 callbacks)
3688  // we want to stop the updating in case there is clock drift, which would
3689  // cause the mAudioOutLatency estimation to drift as well. The clock drift
3690  // in the first 20 callbacks should be negligible, however.
3691  if (mCallbackCount < 20) {
3692  mAudioOutLatency = mStartTime -
3693  mSystemMinusAudioTime;
3694  }
3695  mSystemMinusAudioTimePlusLatency =
3696  mSystemMinusAudioTime + mAudioOutLatency;
3697  }
3698  }
3699  else {
3700  // If not using Alsa, rely on timeInfo to have meaningful values that are
3701  // more precise than the output latency value reported at stream start.
3702  mSystemMinusAudioTime = rnow - anow;
3703  mSystemMinusAudioTimePlusLatency =
3704  mSystemMinusAudioTime +
3705  (timeInfo->outputBufferDacTime - timeInfo->currentTime);
3706  }
3707 
3708  mAudioFramesPerBuffer = framesPerBuffer;
3709  if (IsPaused()
3710  // PRL: Why was this added? Was it only because of the mysterious
3711  // initial leading zeroes, now solved by setting mStreamToken early?
3712  // JKC: I think it's used for the MIDI time cursor. See comments
3713  // at head of file about AudioTime().
3714  || mStreamToken <= 0
3715  )
3716  mNumPauseFrames += framesPerBuffer;
3717 
3718  // PRL: Note that when there is a separate MIDI thread, it is effectively
3719  // blocked until the first visit to this line during a playback, and will
3720  // not read mSystemMinusAudioTimePlusLatency sooner:
3721  mNumFrames += framesPerBuffer;
3722 #endif
3723 }
3724 
3725 // Stop recording if 'silence' is detected
3726 // Start recording if sound detected.
3727 //
3728 // By using CallAfter(), we can schedule the call to the toolbar
3729 // to run in the main GUI thread after the next event loop iteration.
3730 // That's important, because Pause() updates GUI, such as status bar,
3731 // and that should NOT happen in this audio non-gui thread.
3733  float *inputSamples,
3734  unsigned long framesPerBuffer
3735  )
3736 {
3737  // Quick returns if next to nothing to do.
3738  if( !mPauseRec )
3739  return;
3740 
3741  float maxPeak = 0.;
3742  for( unsigned long i = 0, cnt = framesPerBuffer * mNumCaptureChannels; i < cnt; ++i ) {
3743  float sample = fabs(*(inputSamples++));
3744  if (sample > maxPeak) {
3745  maxPeak = sample;
3746  }
3747  }
3748 
3749  bool bShouldBePaused = maxPeak < mSilenceLevel;
3750  if( bShouldBePaused != IsPaused() )
3751  {
3752  auto pListener = GetListener();
3753  if ( pListener )
3754  pListener->OnSoundActivationThreshold();
3755  }
3756 }
3757 
3758 // A function to apply the requested gain, fading up or down from the
3759 // most recently applied gain.
3760 void AudioIoCallback::AddToOutputChannel( unsigned int chan,
3761  float * outputMeterFloats,
3762  float * outputFloats,
3763  float * tempBuf,
3764  bool drop,
3765  unsigned long len,
3766  WaveTrack *vt
3767  )
3768 {
3769  const auto numPlaybackChannels = mNumPlaybackChannels;
3770 
3771  float gain = vt->GetChannelGain(chan);
3773  gain = 0.0;
3774 
3775  // Output volume emulation: possibly copy meter samples, then
3776  // apply volume, then copy to the output buffer
3777  if (outputMeterFloats != outputFloats)
3778  for ( unsigned i = 0; i < len; ++i)
3779  outputMeterFloats[numPlaybackChannels*i+chan] +=
3780  gain*tempBuf[i];
3781 
3783  gain *= mMixerOutputVol;
3784 
3785  float oldGain = vt->GetOldChannelGain(chan);
3786  if( gain != oldGain )
3787  vt->SetOldChannelGain(chan, gain);
3788  // if no microfades, jump in volume.
3789  if( !mbMicroFades )
3790  oldGain =gain;
3791  wxASSERT(len > 0);
3792 
3793  // Linear interpolate.
3794  float deltaGain = (gain - oldGain) / len;
3795  for (unsigned i = 0; i < len; i++)
3796  outputFloats[numPlaybackChannels*i+chan] += (oldGain + deltaGain * i) *tempBuf[i];
3797 };
3798 
3799 // Limit values to -1.0..+1.0
3800 void ClampBuffer(float * pBuffer, unsigned long len){
3801  for(unsigned i = 0; i < len; i++)
3802  pBuffer[i] = wxClip( pBuffer[i], -1.0f, 1.0f);
3803 };
3804 
3805 
3806 // return true, IFF we have fully handled the callback.
3807 //
3808 // Mix and copy to PortAudio's output buffer
3809 //
3811  void *outputBuffer,
3812  unsigned long framesPerBuffer, float *outputMeterFloats
3813 )
3814 {
3815  const auto numPlaybackTracks = mPlaybackTracks.size();
3816  const auto numPlaybackChannels = mNumPlaybackChannels;
3817  const auto numCaptureChannels = mNumCaptureChannels;
3818 
3819  mMaxFramesOutput = 0;
3820 
3821  // Quick returns if next to nothing to do.
3822  if (mStreamToken <= 0)
3823  return false;
3824  if( !outputBuffer )
3825  return false;
3826  if(numPlaybackChannels <= 0)
3827  return false;
3828 
3829  float *outputFloats = (float *)outputBuffer;
3830 
3831 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
3832  // While scrubbing, ignore seek requests
3834  mSeek = 0.0;
3835 #endif
3836 
3837  if (mSeek){
3839  return true;
3840  }
3841 
3842  // ------ MEMORY ALLOCATION ----------------------
3843  // These are small structures.
3844  WaveTrack **chans = (WaveTrack **) alloca(numPlaybackChannels * sizeof(WaveTrack *));
3845  float **tempBufs = (float **) alloca(numPlaybackChannels * sizeof(float *));
3846 
3847  // And these are larger structures....
3848  for (unsigned int c = 0; c < numPlaybackChannels; c++)
3849  tempBufs[c] = (float *) alloca(framesPerBuffer * sizeof(float));
3850  // ------ End of MEMORY ALLOCATION ---------------
3851 
3852  auto & em = RealtimeEffectManager::Get();
3853  em.RealtimeProcessStart();
3854 
3855  bool selected = false;
3856  int group = 0;
3857  int chanCnt = 0;
3858 
3859  // Choose a common size to take from all ring buffers
3860  const auto toGet =
3861  std::min<size_t>(framesPerBuffer, GetCommonlyReadyPlayback());
3862 
3863  // The drop and dropQuickly booleans are so named for historical reasons.
3864  // JKC: The original code attempted to be faster by doing nothing on silenced audio.
3865  // This, IMHO, is 'premature optimisation'. Instead clearer and cleaner code would
3866  // simply use a gain of 0.0 for silent audio and go on through to the stage of
3867  // applying that 0.0 gain to the data mixed into the buffer.
3868  // Then (and only then) we would have if needed fast paths for:
3869  // - Applying a uniform gain of 0.0.
3870  // - Applying a uniform gain of 1.0.
3871  // - Applying some other uniform gain.
3872  // - Applying a linearly interpolated gain.
3873  // I would expect us not to need the fast paths, since linearly interpolated gain
3874  // is very cheap to process.
3875 
3876  bool drop = false; // Track should become silent.
3877  bool dropQuickly = false; // Track has already been faded to silence.
3878  for (unsigned t = 0; t < numPlaybackTracks; t++)
3879  {
3880  WaveTrack *vt = mPlaybackTracks[t].get();
3881  chans[chanCnt] = vt;
3882 
3883  // TODO: more-than-two-channels
3884  auto nextTrack =
3885  t + 1 < numPlaybackTracks
3886  ? mPlaybackTracks[t + 1].get()
3887  : nullptr;
3888 
3889  // First and last channel in this group (for example left and right
3890  // channels of stereo).
3891  bool firstChannel = vt->IsLeader();
3892  bool lastChannel = !nextTrack || nextTrack->IsLeader();
3893 
3894  if ( firstChannel )
3895  {
3896  selected = vt->GetSelected();
3897  // IF mono THEN clear 'the other' channel.
3898  if ( lastChannel && (numPlaybackChannels>1)) {
3899  // TODO: more-than-two-channels
3900  memset(tempBufs[1], 0, framesPerBuffer * sizeof(float));
3901  }
3902  drop = TrackShouldBeSilent( *vt );
3903  dropQuickly = drop;
3904  }
3905 
3906  if( mbMicroFades )
3907  dropQuickly = dropQuickly && TrackHasBeenFadedOut( *vt );
3908 
3909  decltype(framesPerBuffer) len = 0;
3910 
3911  if (dropQuickly)
3912  {
3913  len = mPlaybackBuffers[t]->Discard(toGet);
3914  // keep going here.
3915  // we may still need to issue a paComplete.
3916  }
3917  else
3918  {
3919  len = mPlaybackBuffers[t]->Get((samplePtr)tempBufs[chanCnt],
3920  floatSample,
3921  toGet);
3922  // wxASSERT( len == toGet );
3923  if (len < framesPerBuffer)
3924  // This used to happen normally at the end of non-looping
3925  // plays, but it can also be an anomalous case where the
3926  // supply from FillBuffers fails to keep up with the
3927  // real-time demand in this thread (see bug 1932). We
3928  // must supply something to the sound card, so pad it with
3929  // zeroes and not random garbage.
3930  memset((void*)&tempBufs[chanCnt][len], 0,
3931  (framesPerBuffer - len) * sizeof(float));
3932  chanCnt++;
3933  }
3934 
3935  // PRL: Bug1104:
3936  // There can be a difference of len in different loop passes if one channel
3937  // of a stereo track ends before the other! Take a max!
3938 
3939  // PRL: More recent rewrites of FillBuffers should guarantee a
3940  // padding out of the ring buffers so that equal lengths are
3941  // available, so maxLen ought to increase from 0 only once
3942  mMaxFramesOutput = std::max(mMaxFramesOutput, len);
3943 
3944  if ( !lastChannel )
3945  continue;
3946 
3947  // Last channel of a track seen now
3948  len = mMaxFramesOutput;
3949 
3950  if( !dropQuickly && selected )
3951  len = em.RealtimeProcess(group, chanCnt, tempBufs, len);
3952  group++;
3953 
3955  if (dropQuickly) // no samples to process, they've been discarded
3956  continue;
3957 
3958  // Our channels aren't silent. We need to pass their data on.
3959  //
3960  // Note that there are two kinds of channel count.
3961  // c and chanCnt are counting channels in the Tracks.
3962  // chan (and numPlayBackChannels) is counting output channels on the device.
3963  // chan = 0 is left channel
3964  // chan = 1 is right channel.
3965  //
3966  // Each channel in the tracks can output to more than one channel on the device.
3967  // For example mono channels output to both left and right output channels.
3968  if (len > 0) for (int c = 0; c < chanCnt; c++)
3969  {
3970  vt = chans[c];
3971 
3974  AddToOutputChannel( 0, outputMeterFloats, outputFloats,
3975  tempBufs[c], drop, len, vt);
3976 
3979  AddToOutputChannel( 1, outputMeterFloats, outputFloats,
3980  tempBufs[c], drop, len, vt);
3981  }
3982 
3983  chanCnt = 0;
3984  }
3985 
3986  // Poke: If there are no playback tracks, then the earlier check
3987  // about the time indicator being past the end won't happen;
3988  // do it here instead (but not if looping or scrubbing)
3989  if (numPlaybackTracks == 0)
3991 
3992  // wxASSERT( maxLen == toGet );
3993 
3994  em.RealtimeProcessEnd();
3995  mLastPlaybackTimeMillis = ::wxGetUTCTimeMillis();
3996 
3997  ClampBuffer( outputFloats, framesPerBuffer*numPlaybackChannels );
3998  if (outputMeterFloats != outputFloats)
3999  ClampBuffer( outputMeterFloats, framesPerBuffer*numPlaybackChannels );
4000 
4001  return false;
4002 }
4003 
4004 void AudioIoCallback::UpdateTimePosition(unsigned long framesPerBuffer)
4005 {
4006  // Quick returns if next to nothing to do.
4007  if (mStreamToken <= 0)
4008  return;
4009 
4010  // Update the position seen by drawing code
4012  // To do: do this in all cases and remove TrackTimeUpdate
4014  else
4015  mPlaybackSchedule.TrackTimeUpdate( framesPerBuffer / mRate );
4016 }
4017 
4018 // return true, IFF we have fully handled the callback.
4019 //
4020 // Copy from PortAudio to our input buffers.
4021 //
4023  const void *inputBuffer,
4024  unsigned long framesPerBuffer,
4025  const PaStreamCallbackFlags statusFlags,
4026  float * tempFloats
4027 )
4028 {
4029  const auto numPlaybackTracks = mPlaybackTracks.size();
4030  const auto numPlaybackChannels = mNumPlaybackChannels;
4031  const auto numCaptureChannels = mNumCaptureChannels;
4032 
4033  // Quick returns if next to nothing to do.
4034  if (mStreamToken <= 0)
4035  return;
4036  if( !inputBuffer )
4037  return;
4038  if( numCaptureChannels <= 0 )
4039  return;
4040 
4041  // If there are no playback tracks, and we are recording, then the
4042  // earlier checks for being past the end won't happen, so do it here.
4044  mCallbackReturn = paComplete;
4045  }
4046 
4047  // The error likely from a too-busy CPU falling behind real-time data
4048  // is paInputOverflow
4049  bool inputError =
4050  (statusFlags & (paInputOverflow))
4051  && !(statusFlags & paPrimingOutput);
4052 
4053  // But it seems it's easy to get false positives, at least on Mac
4054  // So we have not decided to enable this extra detection yet in
4055  // production
4056 
4057  size_t len = framesPerBuffer;
4058  for(unsigned t = 0; t < numCaptureChannels; t++)
4059  len = std::min( len, mCaptureBuffers[t]->AvailForPut() );
4060 
4061  if (mSimulateRecordingErrors && 100LL * rand() < RAND_MAX)
4062  // Make spurious errors for purposes of testing the error
4063  // reporting
4064  len = 0;
4065 
4066  // A different symptom is that len < framesPerBuffer because
4067  // the other thread, executing FillBuffers, isn't consuming fast
4068  // enough from mCaptureBuffers; maybe it's CPU-bound, or maybe the
4069  // storage device it writes is too slow
4070  if (mDetectDropouts &&
4071  ((mDetectUpstreamDropouts && inputError) ||
4072  len < framesPerBuffer) ) {
4073  // Assume that any good partial buffer should be written leftmost
4074  // and zeroes will be padded after; label the zeroes.
4075  auto start = mPlaybackSchedule.GetTrackTime() +
4077  auto duration = (framesPerBuffer - len) / mRate;
4078  auto pLast = mLostCaptureIntervals.empty()
4079  ? nullptr : &mLostCaptureIntervals.back();
4080  if (pLast &&
4081  fabs(pLast->first + pLast->second - start) < 0.5/mRate)
4082  // Make one bigger interval, not two butting intervals
4083  pLast->second = start + duration - pLast->first;
4084  else
4085  mLostCaptureIntervals.emplace_back( start, duration );
4086  }
4087 
4088  if (len < framesPerBuffer)
4089  {
4090  mLostSamples += (framesPerBuffer - len);
4091  wxPrintf(wxT("lost %d samples\n"), (int)(framesPerBuffer - len));
4092  }
4093 
4094  if (len <= 0)
4095  return;
4096 
4097  // We have an ASSERT in the AudioIO constructor to alert us to
4098  // possible issues with the (short*) cast. We'd have a problem if
4099  // sizeof(short) > sizeof(float) since our buffers are sized for floats.
4100  for(unsigned t = 0; t < numCaptureChannels; t++) {
4101 
4102  // dmazzoni:
4103  // Un-interleave. Ugly special-case code required because the
4104  // capture channels could be in three different sample formats;
4105  // it'd be nice to be able to call CopySamples, but it can't
4106  // handle multiplying by the gain and then clipping. Bummer.
4107 
4108  switch(mCaptureFormat) {
4109  case floatSample: {
4110  float *inputFloats = (float *)inputBuffer;
4111  for(unsigned i = 0; i < len; i++)
4112  tempFloats[i] =
4113  inputFloats[numCaptureChannels*i+t];
4114  } break;
4115  case int24Sample:
4116  // We should never get here. Audacity's int24Sample format
4117  // is different from PortAudio's sample format and so we
4118  // make PortAudio return float samples when recording in
4119  // 24-bit samples.
4120  wxASSERT(false);
4121  break;
4122  case int16Sample: {
4123  short *inputShorts = (short *)inputBuffer;
4124  short *tempShorts = (short *)tempFloats;
4125  for( unsigned i = 0; i < len; i++) {
4126  float tmp = inputShorts[numCaptureChannels*i+t];
4127  tmp = wxClip( -32768, tmp, 32767 );
4128  tempShorts[i] = (short)(tmp);
4129  }
4130  } break;
4131  } // switch
4132 
4133  // JKC: mCaptureFormat must be for samples with sizeof(float) or
4134  // fewer bytes (because tempFloats is sized for floats). All
4135  // formats are 2 or 4 bytes, so we are OK.
4136  const auto put =
4137  mCaptureBuffers[t]->Put(
4138  (samplePtr)tempFloats, mCaptureFormat, len);
4139  // wxASSERT(put == len);
4140  // but we can't assert in this thread
4141  wxUnusedVar(put);
4142  }
4143 }
4144 
4145 
4146 #if 0
4147 // Record the reported latency from PortAudio.
4148 // TODO: Don't recalculate this with every callback?
4149 // 01/21/2009: Disabled until a better solution presents itself.
4150 void OldCodeToCalculateLatency()
4151 {
4152  // As of 06/17/2006, portaudio v19 returns inputBufferAdcTime set to
4153  // zero. It is being worked on, but for now we just can't do much
4154  // but follow the leader.
4155  //
4156  // 08/27/2006: too inconsistent for now...just leave it a zero.
4157  //
4158  // 04/16/2008: Looks like si->inputLatency comes back with something useful though.
4159  // This rearranged logic uses si->inputLatency, but if PortAudio fixes inputBufferAdcTime,
4160  // this code won't have to be modified to use it.
4161  // Also avoids setting mLastRecordingOffset except when simultaneously playing and recording.
4162  //
4163  if (numCaptureChannels > 0 && numPlaybackChannels > 0) // simultaneously playing and recording
4164  {
4165  if (timeInfo->inputBufferAdcTime > 0)
4166  mLastRecordingOffset = timeInfo->inputBufferAdcTime - timeInfo->outputBufferDacTime;
4167  else if (mLastRecordingOffset == 0.0)
4168  {
4169  const PaStreamInfo* si = Pa_GetStreamInfo( mPortStreamV19 );
4170  mLastRecordingOffset = -si->inputLatency;
4171  }
4172  }
4173 }
4174 #endif
4175 
4176 
4177 // return true, IFF we have fully handled the callback.
4178 // Prime the output buffer with 0's, optionally adding in the playthrough.
4180  const void *inputBuffer,
4181  void *outputBuffer,
4182  unsigned long framesPerBuffer,
4183  float *outputMeterFloats
4184  )
4185 {
4186  const auto numCaptureChannels = mNumCaptureChannels;
4187  const auto numPlaybackChannels = mNumPlaybackChannels;
4188 
4189  // Quick returns if next to nothing to do.
4190  if( !outputBuffer )
4191  return;
4192  if( numPlaybackChannels <= 0 )
4193  return;
4194 
4195  float *outputFloats = (float *)outputBuffer;
4196  for(unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
4197  outputFloats[i] = 0.0;
4198 
4199  if (inputBuffer && mSoftwarePlaythrough) {
4201  numCaptureChannels,
4202  (float *)outputBuffer, (int)framesPerBuffer);
4203  }
4204 
4205  // Copy the results to outputMeterFloats if necessary
4206  if (outputMeterFloats != outputFloats) {
4207  for (unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; ++i) {
4208  outputMeterFloats[i] = outputFloats[i];
4209  }
4210  }
4211 }
4212 
4213 /* Send data to recording VU meter if applicable */
4214 // Also computes rms
4216  float *inputSamples,
4217  unsigned long framesPerBuffer
4218  )
4219 {
4220  const auto numCaptureChannels = mNumCaptureChannels;
4221 
4222  if (!mInputMeter)
4223  return;
4224  if( mInputMeter->IsMeterDisabled())
4225  return;
4226 
4227  // get here if meters are actually live , and being updated
4228  /* It's critical that we don't update the meters while StopStream is
4229  * trying to stop PortAudio, otherwise it can lead to a freeze. We use
4230  * two variables to synchronize:
4231  * mUpdatingMeters tells StopStream when the callback is about to enter
4232  * the code where it might update the meters, and
4233  * mUpdateMeters is how the rest of the code tells the callback when it
4234  * is allowed to actually do the updating.
4235  * Note that mUpdatingMeters must be set first to avoid a race condition.
4236  */
4237  //TODO use atomics instead.
4238  mUpdatingMeters = true;
4239  if (mUpdateMeters) {
4240  mInputMeter->UpdateDisplay(numCaptureChannels,
4241  framesPerBuffer,
4242  inputSamples);
4243  }
4244  mUpdatingMeters = false;
4245 }
4246 
4247 /* Send data to playback VU meter if applicable */
4249  float *outputMeterFloats,
4250  unsigned long framesPerBuffer)
4251 {
4252  const auto numPlaybackChannels = mNumPlaybackChannels;
4253 
4254  if (!mOutputMeter)
4255  return;
4256  if( mOutputMeter->IsMeterDisabled() )
4257  return;
4258  if( !outputMeterFloats)
4259  return;
4260 
4261  // Get here if playback meter is live
4262  /* It's critical that we don't update the meters while StopStream is
4263  * trying to stop PortAudio, otherwise it can lead to a freeze. We use
4264  * two variables to synchronize:
4265  * mUpdatingMeters tells StopStream when the callback is about to enter
4266  * the code where it might update the meters, and
4267  * mUpdateMeters is how the rest of the code tells the callback when it
4268  * is allowed to actually do the updating.
4269  * Note that mUpdatingMeters must be set first to avoid a race condition.
4270  */
4271  mUpdatingMeters = true;
4272  if (mUpdateMeters) {
4273  mOutputMeter->UpdateDisplay(numPlaybackChannels,
4274  framesPerBuffer,
4275  outputMeterFloats);
4276 
4277  //v Vaughan, 2011-02-25: Moved this update back to TrackPanel::OnTimer()
4278  // as it helps with playback issues reported by Bill and noted on Bug 258.
4279  // The problem there occurs if Software Playthrough is on.
4280  // Could conditionally do the update here if Software Playthrough is off,
4281  // and in TrackPanel::OnTimer() if Software Playthrough is on, but not now.
4282  // PRL 12 Jul 2015: and what was in TrackPanel::OnTimer is now handled by means of event
4283  // type EVT_TRACK_PANEL_TIMER
4284  //MixerBoard* pMixerBoard = mOwningProject->GetMixerBoard();
4285  //if (pMixerBoard)
4286  // pMixerBoard->UpdateMeters(GetStreamTime(),
4287  // (pProj->GetControlToolBar()->GetLastPlayMode() == loopedPlay));
4288  }
4289  mUpdatingMeters = false;
4290 }
4291 
4293  const auto numPlaybackTracks = mPlaybackTracks.size();
4294 
4295  // MOVE_TO: CountSoloedTracks() function
4296  unsigned numSolo = 0;
4297  for(unsigned t = 0; t < numPlaybackTracks; t++ )
4298  if( mPlaybackTracks[t]->GetSolo() )
4299  numSolo++;
4300 #ifdef EXPERIMENTAL_MIDI_OUT
4301  auto numMidiPlaybackTracks = mMidiPlaybackTracks.size();
4302  for( unsigned t = 0; t < numMidiPlaybackTracks; t++ )
4303  if( mMidiPlaybackTracks[t]->GetSolo() )
4304  numSolo++;
4305 #endif
4306  return numSolo;
4307 }
4308 
4309 // TODO: Consider making the two Track status functions into functions of
4310 // WaveTrack.
4311 
4312 // true IFF the track should be silent.
4313 // The track may not yet be silent, since it may still be
4314 // fading out.
4316 {
4317  return mPaused || (!wt.GetSolo() && (
4318  // Cut if somebody else is soloing
4319  mbHasSoloTracks ||
4320  // Cut if we're muted (and not soloing)
4321  wt.GetMute()
4322  ));
4323 }
4324 
4325 // This is about micro-fades.
4327 {
4328  const auto channel = wt.GetChannelIgnoringPan();
4329  if ((channel == Track::LeftChannel || channel == Track::MonoChannel) &&
4330  wt.GetOldChannelGain(0) != 0.0)
4331  return false;
4332  if ((channel == Track::RightChannel || channel == Track::MonoChannel) &&
4333  wt.GetOldChannelGain(1) != 0.0)
4334  return false;
4335  return true;
4336 }
4337 
4339 {
4340  const bool dropAllQuickly = std::all_of(
4341  mPlaybackTracks.begin(), mPlaybackTracks.end(),
4342  [&]( const std::shared_ptr< WaveTrack > &vt )
4343  { return
4344  TrackShouldBeSilent( *vt ) &&
4345  TrackHasBeenFadedOut( *vt ); }
4346  );
4347  return dropAllQuickly;
4348 }
4349 
4351 {
4352 }
4353 
4354 
4356 {
4357 }
4358 
4359 
4360 int AudioIoCallback::AudioCallback(const void *inputBuffer, void *outputBuffer,
4361  unsigned long framesPerBuffer,
4362  const PaStreamCallbackTimeInfo *timeInfo,
4363  const PaStreamCallbackFlags statusFlags, void * WXUNUSED(userData) )
4364 {
4366  mCallbackReturn = paContinue;
4367 
4368 #ifdef EXPERIMENTAL_MIDI_OUT
4369  // MIDI
4370  // ComputeMidiTimings may modify mFramesPerBuffer and mNumFrames,
4371  // but it does nothing unless we have EXPERIMENTAL_MIDI_OUT
4372  // TODO: Possibly rename variables to make it clearer which ones are MIDI specific
4373  // and which ones affect all audio.
4375  timeInfo,
4376  framesPerBuffer
4377  );
4378 #ifndef USE_MIDI_THREAD
4379  if (mMidiStream)
4380  FillMidiBuffers();
4381 #endif
4382 #endif
4383 
4384  // ------ MEMORY ALLOCATIONS -----------------------------------------------
4385  // tempFloats will be a reusable scratch pad for (possibly format converted)
4386  // audio data. One temporary use is for the InputMeter data.
4387  const auto numPlaybackChannels = mNumPlaybackChannels;
4388  const auto numCaptureChannels = mNumCaptureChannels;
4389  float *tempFloats = (float *)alloca(framesPerBuffer*sizeof(float)*
4390  MAX(numCaptureChannels,numPlaybackChannels));
4391 
4392  bool bVolEmulationActive =
4393  (outputBuffer && mEmulateMixerOutputVol && mMixerOutputVol != 1.0);
4394  // outputMeterFloats is the scratch pad for the output meter.
4395  // we can often reuse the existing outputBuffer and save on allocating
4396  // something new.
4397  float *outputMeterFloats = bVolEmulationActive ?
4398  (float *)alloca(framesPerBuffer*numPlaybackChannels * sizeof(float)) :
4399  (float *)outputBuffer;
4400  // ----- END of MEMORY ALLOCATIONS ------------------------------------------
4401 
4402  if (inputBuffer && numCaptureChannels) {
4403  float *inputSamples;
4404 
4405  if (mCaptureFormat == floatSample) {
4406  inputSamples = (float *) inputBuffer;
4407  }
4408  else {
4409  CopySamples((samplePtr)inputBuffer, mCaptureFormat,
4410  (samplePtr)tempFloats, floatSample,
4411  framesPerBuffer * numCaptureChannels);
4412  inputSamples = tempFloats;
4413  }
4414 
4416  inputSamples,
4417  framesPerBuffer);
4418 
4419  // This function may queue up a pause or resume.
4420  // TODO this is a bit dodgy as it toggles the Pause, and
4421  // relies on an idle event to have handled that, so could
4422  // queue up multiple toggle requests and so do nothing.
4423  // Eventually it will sort itself out by random luck, but
4424  // the net effect is a delay in starting/stopping sound activated
4425  // recording.
4427  inputSamples,
4428  framesPerBuffer);
4429  }
4430 
4431  // Even when paused, we do playthrough.
4432  // Initialise output buffer to zero or to playthrough data.
4433  // Initialise output meter values.
4434  DoPlaythrough(
4435  inputBuffer,
4436  outputBuffer,
4437  framesPerBuffer,
4438  outputMeterFloats);
4439 
4440  // Test for no track audio to play (because we are paused and have faded out)
4441  if( mPaused && (( !mbMicroFades ) || AllTracksAlreadySilent() ))
4442  return mCallbackReturn;
4443 
4444  // To add track output to output (to play sound on speaker)
4445  // possible exit, if we were seeking.
4446  if( FillOutputBuffers(
4447  outputBuffer,
4448  framesPerBuffer,
4449  outputMeterFloats))
4450  return mCallbackReturn;
4451 
4452  // To move the cursor onwards. (uses mMaxFramesOutput)
4453  UpdateTimePosition(framesPerBuffer);
4454 
4455  // To capture input into track (sound from microphone)
4457  inputBuffer,
4458  framesPerBuffer,
4459  statusFlags,
4460  tempFloats);
4461 
4462  SendVuOutputMeterData( outputMeterFloats, framesPerBuffer);
4463 
4464  return mCallbackReturn;
4465 }
4466 
4468 {
4469  const int token = mStreamToken;
4470  wxMutexLocker locker(mSuspendAudioThread);
4471  if (token != mStreamToken)
4472  // This stream got destroyed while we waited for it
4473  return paAbort;
4474 
4475  const auto numPlaybackTracks = mPlaybackTracks.size();
4476 
4477  // Pause audio thread and wait for it to finish
4480  {
4481  wxMilliSleep( 50 );
4482  }
4483 
4484  // Calculate the NEW time position, in the PortAudio callback
4485  const auto time = mPlaybackSchedule.ClampTrackTime(
4488  mSeek = 0.0;
4489 
4491 
4492  // Reset mixer positions and flush buffers for all tracks
4493  for (size_t i = 0; i < numPlaybackTracks; i++)
4494  {
4495  const bool skipping = true;
4496  mPlaybackMixers[i]->Reposition( time, skipping );
4497  const auto toDiscard =
4498  mPlaybackBuffers[i]->AvailForGet();
4499  const auto discarded =
4500  mPlaybackBuffers[i]->Discard( toDiscard );
4501  // wxASSERT( discarded == toDiscard );
4502  // but we can't assert in this thread
4503  wxUnusedVar(discarded);
4504  }
4505 
4506  // Reload the ring buffers
4509  {
4510  wxMilliSleep( 50 );
4511  }
4512 
4513  // Reenable the audio thread
4515 
4516  return paContinue;
4517 }
4518 
4520  int &callbackReturn, unsigned long len)
4521 {
4522  if (mPaused)
4523  return;
4524 
4525  bool done = mPlaybackSchedule.PassIsComplete();
4526  if (!done)
4527  return;
4528 
4530  // some leftover length allowed in this case
4531  || (mPlaybackSchedule.PlayingStraight() && len == 0);
4532  if(!done)
4533  return;
4534 
4535 #ifdef EXPERIMENTAL_MIDI_OUT
4536  mMidiOutputComplete = true,
4537 #endif
4538  callbackReturn = paComplete;
4539 }
4540 
4542  const PlaybackSchedule &schedule, double rate, double scrubSpeed,
4543  size_t nSamples )
4544 {
4545  if ( ! mData )
4546  // Recording only. Don't fill the queue.
4547  return;
4548 
4549  // Don't check available space: assume it is enough because of coordination
4550  // with RingBuffer.
4551  auto index = mTail.mIndex;
4552  auto time = mLastTime;
4553  auto remainder = mTail.mRemainder;
4554  auto space = TimeQueueGrainSize - remainder;
4555 
4556  while ( nSamples >= space ) {
4557  time = schedule.AdvancedTrackTime( time, space / rate, scrubSpeed );
4558  index = (index + 1) % mSize;
4559  mData[ index ] = time;
4560  nSamples -= space;
4561  remainder = 0;
4562  space = TimeQueueGrainSize;
4563  }
4564 
4565  // Last odd lot
4566  if ( nSamples > 0 )
4567  time = schedule.AdvancedTrackTime( time, nSamples / rate, scrubSpeed );
4568 
4569  mLastTime = time;
4570  mTail.mRemainder = remainder + nSamples;
4571  mTail.mIndex = index;
4572 }
4573 
4574 double AudioIO::TimeQueue::Consumer( size_t nSamples, double rate )
4575 {
4576  if ( ! mData ) {
4577  // Recording only. No scrub or playback time warp. Don't use the queue.
4578  return ( mLastTime += nSamples / rate );
4579  }
4580 
4581  // Don't check available space: assume it is enough because of coordination
4582  // with RingBuffer.
4583  auto remainder = mHead.mRemainder;
4584  auto space = TimeQueueGrainSize - remainder;
4585  if ( nSamples >= space ) {
4586  remainder = 0,
4587  mHead.mIndex = (mHead.mIndex + 1) % mSize,
4588  nSamples -= space;
4589  if ( nSamples >= TimeQueueGrainSize )
4590  mHead.mIndex =
4591  (mHead.mIndex + ( nSamples / TimeQueueGrainSize ) ) % mSize,
4592  nSamples %= TimeQueueGrainSize;
4593  }
4594  mHead.mRemainder = remainder + nSamples;
4595  return mData[ mHead.mIndex ];
4596 }
4597 
4599 {
4600  // Includes a test of mTime, used in the main thread
4601  return IsStreamActive() &&
4602  GetNumCaptureChannels() > 0 &&
4605 }
WaveTrack.h
AudioIoCallback::mPlaybackQueueMinimum
size_t mPlaybackQueueMinimum
Occupancy of the queue we try to maintain, with bigger batches if needed.
Definition: AudioIO.h:479
WaveTrack::SetOldChannelGain
void SetOldChannelGain(int channel, float gain)
Definition: WaveTrack.cpp:429
AudioIO::IsCapturing
bool IsCapturing() const
Definition: AudioIO.cpp:4598
Optional::emplace
X & emplace(Args &&... args)
Definition: MemoryX.h:259
ClearSamples
void ClearSamples(samplePtr dst, sampleFormat format, size_t start, size_t len)
Definition: SampleFormat.cpp:77
AudioIoCallback::mCaptureFormat
sampleFormat mCaptureFormat
Definition: AudioIO.h:488
AudioIOBase::mPlaybackSchedule
struct AudioIOBase::PlaybackSchedule mPlaybackSchedule
ScrubbingOptions::maxTime
double maxTime
Definition: AudioIOBase.h:49
WaveTrackConstArray
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:63
anonymous_namespace{TrackSelectHandle.cpp}::Message
TranslatableString Message(unsigned trackCount)
Definition: TrackSelectHandle.cpp:38
TransportTracks::playbackTracks
WaveTrackArray playbackTracks
Definition: AudioIO.h:92
WaveTrack::Flush
void Flush()
Flush must be called after last Append.
Definition: WaveTrack.cpp:1608
AudioIOListener.h
SampleBuffer::Allocate
SampleBuffer & Allocate(size_t count, sampleFormat format)
Definition: SampleFormat.h:68
AudioIoCallback::SetListener
void SetListener(const std::shared_ptr< AudioIOListener > &listener)
Definition: AudioIO.cpp:3081
AudioIOBase::PlaybackSchedule::mT0
double mT0
Playback starts at offset of mT0, which is measured in seconds.
Definition: AudioIOBase.h:330
AudioIoCallback::mPlaybackTracks
WaveTrackArray mPlaybackTracks
Definition: AudioIO.h:464
AudioIOStartStreamOptions::rate
double rate
Definition: AudioIOBase.h:93
AudioIoCallback::mbMicroFades
bool mbMicroFades
Definition: AudioIO.h:470
ProjectStatus.h
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:68
AudioIOBase::DeviceName
static wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIOBase.cpp:78
AudioIoCallback::CheckSoundActivatedRecordingLevel
void CheckSoundActivatedRecordingLevel(float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:3732
AudioIO::AllocateBuffers
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:1830
DB_TO_LINEAR
const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB)
AudioIOBase::RecordingSchedule::TotalCorrection
double TotalCorrection() const
Definition: AudioIOBase.h:322
AudioIOBase::PlaybackSchedule::PlayingAtSpeed
bool PlayingAtSpeed() const
Definition: AudioIOBase.h:420
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:625
Track::RightChannel
static const auto RightChannel
Definition: Track.h:266
PlayableTrack::GetSolo
bool GetSolo() const
Definition: Track.h:844
ProjectFileIO.h
DEFAULT_LATENCY_CORRECTION
#define DEFAULT_LATENCY_CORRECTION
Definition: RecordingPrefs.h:34
AudioIO::LastPaErrorString
wxString LastPaErrorString()
Definition: AudioIO.cpp:1438
AudioIOStartStreamOptions::listener
std::shared_ptr< AudioIOListener > listener
Definition: AudioIOBase.h:92
Optional
Like a smart pointer, allows for object to not exist (nullptr)
Definition: MemoryX.h:210
PlayableTrack::GetMute
bool GetMute() const
Definition: Track.h:843
AudioIoCallback::TimeQueue::Cursor::mRemainder
size_t mRemainder
Definition: AudioIO.h:576
AudioIoCallback::mThread
std::unique_ptr< AudioThread > mThread
Definition: AudioIO.h:454
AudioIoCallback::mAudioThreadShouldCallFillBuffersOnce
volatile bool mAudioThreadShouldCallFillBuffersOnce
Definition: AudioIO.h:490
AudioIOBase::RecordingSchedule::mLatencyCorrected
bool mLatencyCorrected
Definition: AudioIOBase.h:320
AudioIOBase::mOwningProject
AudacityProject * mOwningProject
Definition: AudioIOBase.h:266
ScrubbingOptions::MaxAllowedScrubSpeed
static double MaxAllowedScrubSpeed()
Definition: AudioIOBase.h:68
AudioIOBase::mMidiOutputComplete
bool mMidiOutputComplete
True when output reaches mT1.
Definition: AudioIOBase.h:272
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:67
AudioIOBase::mPortStreamV19
PaStream * mPortStreamV19
Definition: AudioIOBase.h:282
AudacityToPortAudioSampleFormat
static PaSampleFormat AudacityToPortAudioSampleFormat(sampleFormat format)
Definition: AudioIO.cpp:1208
AudioIOBase::PlaybackSchedule::PassIsComplete
bool PassIsComplete() const
Definition: AudioIOBase.cpp:1195
ENV_DB_RANGE
#define ENV_DB_RANGE
Definition: GUISettings.h:16
ScrubbingOptions
Definition: AudioIOBase.h:43
AudioIOBase::PlaybackSchedule
Definition: AudioIOBase.h:328
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
AudioIOBase::RecordingSchedule::ToConsume
double ToConsume() const
Definition: AudioIOBase.cpp:1340
TransportTracks::captureTracks
WaveTrackArray captureTracks
Definition: AudioIO.h:93
ScrubbingOptions::minTime
double minTime
Definition: AudioIOBase.h:50
AudioIoCallback::TimeQueue::Cursor::mIndex
size_t mIndex
Definition: AudioIO.h:575
Project.h
AudioIoCallback::mNumPlaybackChannels
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:487
AudioIOBase::mInputMixerWorks
bool mInputMixerWorks
Can we control the hardware input level?
Definition: AudioIOBase.h:300
AudioIoCallback::mNumCaptureChannels
unsigned int mNumCaptureChannels
Definition: AudioIO.h:486
int24Sample
@ int24Sample
Definition: Types.h:713
AudioIOStartStreamOptions::playbackMeter
MeterPanelBase * playbackMeter
Definition: AudioIOBase.h:90
AudioIOBase::getPlayDevIndex
static int getPlayDevIndex(const wxString &devName={})
get the index of the device selected in the preferences.
Definition: AudioIOBase.cpp:727
Mixer::WarpOptions
Definition: Mix.h:83
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1467
Mix.h
AudioIO::GetBestRate
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:2512
AudioIoCallback::mUpdatingMeters
volatile bool mUpdatingMeters
Definition: AudioIO.h:507
ArrayOf::reinit
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:112
AudioIoCallback::mMaxFramesOutput
unsigned long mMaxFramesOutput
Definition: AudioIO.h:469
AudioIOBase::getRecordDevIndex
static int getRecordDevIndex(const wxString &devName={})
get the index of the supplied (named) recording device, or the device selected in the preferences if ...
Definition: AudioIOBase.cpp:784
AudioIoCallback::mPlaybackSamplesToCopy
size_t mPlaybackSamplesToCopy
Preferred batch size for replenishing the playback RingBuffer.
Definition: AudioIO.h:477
XO
#define XO(s)
Definition: Internat.h:32
ProjectFileIO::Get
static ProjectFileIO & Get(AudacityProject &project)
Definition: ProjectFileIO.cpp:267
AudioIOBase::IsStreamActive
bool IsStreamActive() const
Returns true if the audio i/o is running at all, but not during cleanup.
Definition: AudioIOBase.cpp:353
AudioIOBase::PlaybackSchedule::mT1
double mT1
Playback ends at offset of mT1, which is measured in seconds. Note that mT1 may be less than mT0 duri...
Definition: AudioIOBase.h:332
AudioIOBase::SetCaptureMeter
void SetCaptureMeter(AudacityProject *project, MeterPanelBase *meter)
Definition: AudioIOBase.cpp:312
ScrubbingOptions::MinAllowedScrubSpeed
static double MinAllowedScrubSpeed()
Definition: AudioIOBase.h:70
AudioIOStartStreamOptions::preRoll
double preRoll
Definition: AudioIOBase.h:98
NoteTrack.h
AudioIoCallback::mPlaybackBuffers
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:463
AudioIoCallback::AudioCallback
int AudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:4360
floatSample
@ floatSample
Definition: Types.h:714
AudioThread::Entry
ExitCode Entry() override
Definition: AudioIO.cpp:2597
AudioIO::ValidateDeviceNames
static bool ValidateDeviceNames(const wxString &play, const wxString &rec)
Ensure selected device names are valid.
Definition: AudioIO.cpp:948
AudioIoCallback::ComputeMidiTimings
void ComputeMidiTimings(const PaStreamCallbackTimeInfo *timeInfo, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:3645
DBConnection.h
Declare DBConnection, which maintains database connection and associated status and background thread...
AudioIOBase::RecordingSchedule::mLatencyCorrection
double mLatencyCorrection
Definition: AudioIOBase.h:313
AudioIoCallback::mUpdateMeters
bool mUpdateMeters
Definition: AudioIO.h:506
AudioIoCallback::mSimulateRecordingErrors
bool mSimulateRecordingErrors
Definition: AudioIO.h:555
AudioIoCallback::mRecordingException
wxAtomicInt mRecordingException
Definition: AudioIO.h:540
AudioIoCallback::mDetectDropouts
bool mDetectDropouts
Definition: AudioIO.h:547
ClampBuffer
void ClampBuffer(float *pBuffer, unsigned long len)
Definition: AudioIO.cpp:3800
AudioIOBase::GetSupportedPlaybackRates
static std::vector< long > GetSupportedPlaybackRates(int DevIndex=-1, double rate=0.0)
Get a list of sample rates the output (playback) device supports.
Definition: AudioIOBase.cpp:513
AudioIoCallback::AddToOutputChannel
void AddToOutputChannel(unsigned int chan, float *outputMeterFloats, float *outputFloats, float *tempBuf, bool drop, unsigned long len, WaveTrack *vt)
Definition: AudioIO.cpp:3760
AudioIOBase::IsPaused
bool IsPaused() const
Find out if playback / recording is currently paused.
Definition: AudioIOBase.cpp:340
QualityPrefs.h
ScrubPollInterval_ms
static constexpr unsigned ScrubPollInterval_ms
Definition: AudioIO.h:788
AudioIOBase::ugAudioIO
static std::unique_ptr< AudioIOBase > ugAudioIO
Definition: AudioIOBase.h:262
AudioIoCallback::mAudioThreadFillBuffersLoopActive
volatile bool mAudioThreadFillBuffersLoopActive
Definition: AudioIO.h:492
MAX
#define MAX(a, b)
Definition: AudioIO.cpp:3610
AudioIOBase::RecordingSchedule::ToDiscard
double ToDiscard() const
Definition: AudioIOBase.cpp:1350
AudioIOBase::IsBusy
bool IsBusy() const
Returns true if audio i/o is busy starting, stopping, playing, or recording.
Definition: AudioIOBase.cpp:345
ScrubbingOptions::maxSpeed
double maxSpeed
Definition: AudioIOBase.h:61
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:698
AudioIO::SetPaused
void SetPaused(bool state)
Pause and un-pause playback and recording.
Definition: AudioIO.cpp:2468
AudioIOBase::PlaybackSchedule::AdvancedTrackTime
double AdvancedTrackTime(double trackTime, double realElapsed, double speed) const
Definition: AudioIOBase.cpp:1237
ScrubbingOptions::minStutterTime
double minStutterTime
Definition: AudioIOBase.h:66
AudioIO::IsAvailable
bool IsAvailable(AudacityProject *projecT) const
Function to automatically set an acceptable volume.
Definition: AudioIO.cpp:2148
AudioIoCallback::AudioIoCallback
AudioIoCallback()
Definition: AudioIO.cpp:4350
ScrubbingOptions::minSpeed
double minSpeed
Definition: AudioIOBase.h:60
ScrubbingOptions::adjustStart
bool adjustStart
Definition: AudioIOBase.h:46
AudacityException
Base class for exceptions specially processed by the application.
Definition: AudacityException.h:25
AudioIoCallback::mDetectUpstreamDropouts
bool mDetectUpstreamDropouts
Definition: AudioIO.h:559
ProjectStatus::Set
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)
Definition: ProjectStatus.cpp:65
AudioIoCallback::mSoftwarePlaythrough
bool mSoftwarePlaythrough
Definition: AudioIO.h:482
samplePtr
char * samplePtr
Definition: Types.h:729
sampleFormat
sampleFormat
Definition: Types.h:709
AudioIOBase::PlaybackSchedule::Init
void Init(double t0, double t1, const AudioIOStartStreamOptions &options, const RecordingSchedule *pRecordingSchedule)
Definition: AudioIOBase.cpp:382
AudioIOBase::mPaused
bool mPaused
True if audio playback is paused.
Definition: AudioIOBase.h:269
AudioIoCallback::CallbackDoSeek
int CallbackDoSeek()
Definition: AudioIO.cpp:4467
sampleCount::as_double
double as_double() const
Definition: Types.h:608
AudioIoCallback::mPauseRec
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:484
RealtimeEffectManager.h
AudioIO::StartStream
int StartStream(const TransportTracks &tracks, double t0, double t1, const AudioIOStartStreamOptions &options)
Start recording or playing back audio.
Definition: AudioIO.cpp:1492
AudioIOBase::PlaybackSchedule::RealTimeRestart
void RealTimeRestart()
Definition: AudioIOBase.cpp:1335
AudioIOBase::PlaybackSchedule::RealTimeAdvance
void RealTimeAdvance(double increment)
Definition: AudioIOBase.cpp:1322
RealtimeEffectManager::RealtimeFinalize
void RealtimeFinalize()
Definition: RealtimeEffectManager.cpp:197
AudioIoCallback::mCaptureBuffers
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:461
AudioIO::GetCommonlyAvailCapture
size_t GetCommonlyAvailCapture()
Get the number of audio samples ready in all of the recording buffers.
Definition: AudioIO.cpp:2676
AudioIOBase::mMixerOutputVol
float mMixerOutputVol
Definition: AudioIOBase.h:301
DoSoftwarePlaythrough
static void DoSoftwarePlaythrough(const void *inputBuffer, sampleFormat inputFormat, unsigned inputChannels, float *outputBuffer, int len)
Definition: AudioIO.cpp:3612
AudioIOBase::mOutputMeter
wxWeakRef< MeterPanelBase > mOutputMeter
Definition: AudioIOBase.h:285
AudioIoCallback::mLastPlaybackTimeMillis
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:494
PaError
int PaError
Definition: AudioIO.h:67
Track::MonoChannel
static const auto MonoChannel
Definition: Track.h:267
FindProjectFrame
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null.
Definition: Project.h:172
AudioIOBase::PlaybackSchedule::PlayingStraight
bool PlayingStraight() const
Definition: AudioIOBase.h:417
AudioIoCallback::mRecordingSchedule
RecordingSchedule mRecordingSchedule
Definition: AudioIO.h:562
AudioIOBase::PlaybackSchedule::Interactive
bool Interactive() const
Definition: AudioIOBase.h:421
AudioIO::OutputMixerEmulated
bool OutputMixerEmulated()
Find out if the output level control is being emulated via software attenuation.
Definition: AudioIO.cpp:1175
MessageBuffer
Definition: AudioIO.h:139
name
const TranslatableString name
Definition: Distortion.cpp:98
AudioIoCallback::UpdateTimePosition
void UpdateTimePosition(unsigned long framesPerBuffer)
Definition: AudioIO.cpp:4004
AudioIoCallback::mCallbackReturn
int mCallbackReturn
Definition: AudioIO.h:300
AudioIOStartStreamOptions::captureMeter
MeterPanelBase * captureMeter
Definition: AudioIOBase.h:90
format
int format
Definition: ExportPCM.cpp:54
AudioIOBase::PlaybackSchedule::SetTrackTime
void SetTrackTime(double time)
Set current track time value, unadjusted.
Definition: AudioIOBase.h:391
DeviceManager::GetTimeSinceRescan
float GetTimeSinceRescan()
Definition: DeviceManager.cpp:313
AudioIoCallback::mLostSamples
unsigned long long mLostSamples
Definition: AudioIO.h:489
AudioIOBase::Get
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:94
AudioIoCallback::mPlaybackMixers
ArrayOf< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:466
AudioIOBase::mRate
double mRate
Audio playback rate in samples per second.
Definition: AudioIOBase.h:280
AudioIoCallback::mSuspendAudioThread
wxMutex mSuspendAudioThread
Definition: AudioIO.h:525
AudioIoCallback::mLastRecordingOffset
volatile double mLastRecordingOffset
Definition: AudioIO.h:501
DEFAULT_SYNTH_LATENCY
#define DEFAULT_SYNTH_LATENCY
Definition: AudioIO.h:72
AudioIOBase::mMidiStreamActive
bool mMidiStreamActive
mMidiStreamActive tells when mMidiStream is open for output
Definition: AudioIOBase.h:275
Track::LeftChannel
static const auto LeftChannel
Definition: Track.h:265
AudioIoCallback::TimeQueue::mTail
struct AudioIoCallback::TimeQueue::Cursor mTail
AudioIOBase::PlaybackSchedule::PLAY_LOOPED
@ PLAY_LOOPED
Definition: AudioIOBase.h:361
AudioIOBase::GetSupportedSampleRates
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: AudioIOBase.cpp:648
AudioIOBase::PlaybackSchedule::ResetMode
void ResetMode()
Definition: AudioIOBase.h:415
AudioIOBase::SetMixer
void SetMixer(int inputSource)
Definition: AudioIOBase.cpp:101
AudioIoCallback::mAudioThreadFillBuffersLoopRunning
volatile bool mAudioThreadFillBuffersLoopRunning
Definition: AudioIO.h:491
AudioIOStartStreamOptions
struct holding stream options, including a pointer to the time warp info and AudioIOListener and whet...
Definition: AudioIOBase.h:76
AudioIOBase::HostName
static wxString HostName(const PaDeviceInfo *info)
Definition: AudioIOBase.cpp:85
AudioIO::StartMonitoring
void StartMonitoring(const AudioIOStartStreamOptions &options)
Start up Portaudio for capture and recording as needed for input monitoring and software playthrough ...
Definition: AudioIO.cpp:1443
AudioIoCallback::mNextStreamToken
static int mNextStreamToken
Definition: AudioIO.h:467
AudioIO::GetInputSourceNames
wxArrayString GetInputSourceNames()
Get the list of inputs to the current mixer device.
Definition: AudioIO.cpp:1180
AudioIoCallback::DoPlaythrough
void DoPlaythrough(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:4179
AudioIoCallback::mCachedBestRateCapturing
static bool mCachedBestRateCapturing
Definition: AudioIO.h:521
AudioIOBase::mInputMeter
wxWeakRef< MeterPanelBase > mInputMeter
Definition: AudioIOBase.h:284
ENV_DB_KEY
#define ENV_DB_KEY
Definition: GUISettings.h:15
KeyboardCapture::Release
void Release(wxWindow *handler)
Definition: KeyboardCapture.cpp:74
audacityAudioCallback
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:3633
AudioIO::StartPortAudioStream
bool StartPortAudioStream(const AudioIOStartStreamOptions &options, unsigned int numPlaybackChannels, unsigned int numCaptureChannels, sampleFormat captureFormat)
Opens the portaudio stream(s) used to do playback or recording (or both) through.
Definition: AudioIO.cpp:1221
RealtimeEffectManager::Get
static RealtimeEffectManager & Get()
Definition: RealtimeEffectManager.cpp:43
RealtimeEffectManager::RealtimeSuspend
void RealtimeSuspend()
Definition: RealtimeEffectManager.cpp:217
TransportTracks
Definition: AudioIO.h:91
AudioIoCallback::TimeQueue::Producer
void Producer(const PlaybackSchedule &schedule, double rate, double scrubSpeed, size_t nSamples)
Definition: AudioIO.cpp:4541
RecordingPrefs.h
AudioIoCallback::ClearRecordingException
void ClearRecordingException()
Definition: AudioIO.h:543
QualityPrefs::SampleFormatChoice
static sampleFormat SampleFormatChoice()
Definition: QualityPrefs.cpp:246
Track::GetSelected
bool GetSelected() const
Definition: Track.h:414
CopySamples
void CopySamples(constSamplePtr src, sampleFormat srcFormat, samplePtr dst, sampleFormat dstFormat, unsigned int len, bool highQuality, unsigned int srcStride, unsigned int dstStride)
Definition: SampleFormat.cpp:102
DeviceManager.h
ShowErrorDialog
void ShowErrorDialog(wxWindow *parent, const TranslatableString &dlogTitle, const TranslatableString &message, const wxString &helpPage, const bool Close, const wxString &log)
Displays an error dialog with a button that offers help.
Definition: ErrorDialog.cpp:148
SampleBuffer
Definition: SampleFormat.h:53
AudioIOStartStreamOptions::pStartTime
double * pStartTime
Definition: AudioIOBase.h:97
AudioIOBase::RecordingSchedule::mCrossfadeData
PRCrossfadeData mCrossfadeData
Definition: AudioIOBase.h:315
GUISettings.h
AudioIoCallback::FillOutputBuffers
bool FillOutputBuffers(void *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:3810
LAT1CTOWX
#define LAT1CTOWX(X)
Definition: Internat.h:161
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
WaveTrack::GetChannelIgnoringPan
virtual ChannelType GetChannelIgnoringPan() const
Definition: WaveTrack.cpp:223
AudioIoCallback::mCaptureRingBufferSecs
double mCaptureRingBufferSecs
Definition: AudioIO.h:474
AudioIOBase::RecordingSchedule::mDuration
double mDuration
Definition: AudioIOBase.h:314
AudioIoCallback::mTimeQueue
struct AudioIoCallback::TimeQueue mTimeQueue
PaStreamCallbackFlags
unsigned long PaStreamCallbackFlags
Definition: AudioIO.h:65
WaveTrack::GetOldChannelGain
float GetOldChannelGain(int channel) const
Definition: WaveTrack.cpp:424
AudioIOBase::PlaybackSchedule::mWarpedLength
double mWarpedLength
Definition: AudioIOBase.h:347
AudioIoCallback::FillInputBuffers
void FillInputBuffers(const void *inputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackFlags statusFlags, float *tempFloats)
Definition: AudioIO.cpp:4022
AudioIoCallback::GetCommonlyReadyPlayback
size_t GetCommonlyReadyPlayback()
Get the number of audio samples ready in all of the playback buffers.
Definition: AudioIO.cpp:2664
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:151
AudioIO::~AudioIO
~AudioIO()
Definition: AudioIO.cpp:1078
AudioIOBase::GetSupportedCaptureRates
static std::vector< long > GetSupportedCaptureRates(int devIndex=-1, double rate=0.0)
Get a list of sample rates the input (recording) device supports.
Definition: AudioIOBase.cpp:578
AudioIOStartStreamOptions::pCrossfadeData
PRCrossfadeData * pCrossfadeData
Definition: AudioIOBase.h:108
AudioIoCallback::mbHasSoloTracks
int mbHasSoloTracks
Definition: AudioIO.h:299
AudioIoCallback::mUsingAlsa
bool mUsingAlsa
Definition: AudioIO.h:516
Track::IsLeader
bool IsLeader() const
Definition: Track.cpp:370
AudioIoCallback::CallbackCheckCompletion
void CallbackCheckCompletion(int &callbackReturn, unsigned long len)
Definition: AudioIO.cpp:4519
AudioIO::StartStreamCleanup
void StartStreamCleanup(bool bOnlyBuffers=false)
Clean up after StartStream if it fails.
Definition: AudioIO.cpp:2019
AudioIO::FillBuffers
void FillBuffers()
Definition: AudioIO.cpp:2688
_
#define _(s)
Definition: Internat.h:76
AudioIO.h
AudioIoCallback::mSilenceLevel
float mSilenceLevel
Definition: AudioIO.h:485
ScrubbingOptions::bySpeed
bool bySpeed
Definition: AudioIOBase.h:52
AudioIOBase::PlaybackSchedule::GetTrackTime
double GetTrackTime() const
Get current track time value, unadjusted.
Definition: AudioIOBase.h:386
sampleCount
Definition: Types.h:581
ProjectStatus::Get
static ProjectStatus & Get(AudacityProject &project)
Definition: ProjectStatus.cpp:23
AudioIoCallback::mSeek
double mSeek
Definition: AudioIO.h:472
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:112
MeterPanelBase.h
AudioIOBase::RecordingSchedule::mPosition
double mPosition
Definition: AudioIOBase.h:319
AudioIO::StopStream
void StopStream() override
Stop recording, playback or input monitoring.
Definition: AudioIO.cpp:2163
AudioIO::SetMeters
void SetMeters()
Set the current VU meters - this should be done once after each call to StartStream currently.
Definition: AudioIO.cpp:2153
Verbatim
TranslatableString Verbatim(wxString str)
Definition: Types.h:573
ErrorDialog.h
AudioIoCallback::AllTracksAlreadySilent
bool AllTracksAlreadySilent()
Definition: AudioIO.cpp:4338
WarningDialogKey
wxString WarningDialogKey(const wxString &internalDialogName)
Definition: Prefs.cpp:368
AudioIoCallback::mLostCaptureIntervals
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:546
AudioIOBase::PlaybackSchedule::ClampTrackTime
double ClampTrackTime(double trackTime) const
Clamps argument to be between mT0 and mT1.
Definition: AudioIOBase.cpp:457
GuardedCall
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
Definition: AudacityException.h:187
AudioIoCallback::mCachedBestRatePlaying
static bool mCachedBestRatePlaying
Definition: AudioIO.h:520
AudacityMessageBox.h
DeviceManager::Instance
static DeviceManager * Instance()
Gets the singleton instance.
Definition: DeviceManager.cpp:47
AudioIOBase::PlaybackSchedule::RealTimeRemaining
double RealTimeRemaining() const
Definition: AudioIOBase.cpp:1317
int16Sample
@ int16Sample
Definition: Types.h:712
AudioIoCallback::mLastPaError
PaError mLastPaError
Definition: AudioIO.h:502
AudioIO::Init
static void Init()
Definition: AudioIO.cpp:911
AudioIoCallback::GetListener
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:288
AudioIOBase::mCachedBestRateIn
static double mCachedBestRateIn
Definition: AudioIOBase.h:309
RealtimeEffectManager::RealtimeResume
void RealtimeResume()
Definition: RealtimeEffectManager.cpp:250
AudioIoCallback::~AudioIoCallback
~AudioIoCallback()
Definition: AudioIO.cpp:4355
AudioIoCallback::TrackShouldBeSilent
bool TrackShouldBeSilent(const WaveTrack &wt)
Definition: AudioIO.cpp:4315
AudioIoCallback::SendVuOutputMeterData
void SendVuOutputMeterData(float *outputMeterFloats, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:4248
AudioIOBase::PlaybackSchedule::Looping
bool Looping() const
Definition: AudioIOBase.h:418
ScrubbingOptions::initSpeed
double initSpeed
Definition: AudioIOBase.h:59
AudioIOBase::PlaybackSchedule::RealTimeInit
void RealTimeInit(double trackTime)
Definition: AudioIOBase.cpp:1327
AudioIoCallback::TimeQueue::mData
Doubles mData
Definition: AudioIO.h:568
AudioIoCallback::mResample
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:460
AudioIOBase::mStreamToken
volatile int mStreamToken
Definition: AudioIOBase.h:277
AudioIoCallback::mListener
std::weak_ptr< AudioIOListener > mListener
Definition: AudioIO.h:509
DefaultDelayedHandlerAction
A default template parameter for GuardedCall.
Definition: AudacityException.h:106
Prefs.h
AudioIOStartStreamOptions::pProject
AudacityProject * pProject
Definition: AudioIOBase.h:89
WaveTrack::GetChannelGain
float GetChannelGain(int channel) const
Definition: WaveTrack.cpp:408
AudioIO::GetCommonlyFreePlayback
size_t GetCommonlyFreePlayback()
Get the number of audio samples free in all of the playback buffers.
Definition: AudioIO.cpp:2653
AudioIOStartStreamOptions::playbackStreamPrimer
std::function< unsigned long() > playbackStreamPrimer
Definition: AudioIOBase.h:113
wxDEFINE_EVENT
wxDEFINE_EVENT(EVT_AUDIOIO_PLAYBACK, wxCommandEvent)
MIDI_MINIMAL_LATENCY_MS
@ MIDI_MINIMAL_LATENCY_MS
Definition: AudioIO.cpp:524
TransactionScope::Commit
bool Commit()
Definition: DBConnection.cpp:623
AudioIO
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:589
AudioThread::AudioThread
AudioThread()
Definition: AudioIO.cpp:891
AudioIoCallback::SendVuInputMeterData
void SendVuInputMeterData(float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:4215
AudioThread
Defined different on Mac and other platforms (on Mac it does not use wxWidgets wxThread),...
Definition: AudioIO.cpp:889
TimeQueueGrainSize
constexpr size_t TimeQueueGrainSize
Definition: AudioIO.cpp:527
AudioIO::Deinit
static void Deinit()
Definition: AudioIO.cpp:943
AudioIOBase::PlaybackSchedule::TrackTimeUpdate
void TrackTimeUpdate(double realElapsed)
Definition: AudioIOBase.cpp:1295
AudioIOBase::HandleDeviceChange
void HandleDeviceChange()
update state after changing what audio devices are selected
Definition: AudioIOBase.cpp:110
AudioIO::InputMixerWorks
bool InputMixerWorks()
Find out if the input hardware level control is available.
Definition: AudioIO.cpp:1170
ROUND
#define ROUND(x)
Definition: NoteTrack.cpp:33
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:505
AudioIoCallback::TrackHasBeenFadedOut
bool TrackHasBeenFadedOut(const WaveTrack &wt)
Definition: AudioIO.cpp:4326
AudioIOBase::PlaybackSchedule::RealDuration
double RealDuration(double trackTime1) const
Definition: AudioIOBase.cpp:1307
safenew
#define safenew
Definition: MemoryX.h:8
AudioIOBase::RecordingSchedule::mPreRoll
double mPreRoll
Definition: AudioIOBase.h:312
AudioIO::GetMixer
void GetMixer(int *inputSource, float *inputVolume, float *playbackVolume)
Definition: AudioIO.cpp:1139
lrint
#define lrint(dbl)
Definition: float_cast.h:148
float_cast.h
AudioIoCallback::CountSoloingTracks
unsigned CountSoloingTracks()
Definition: AudioIO.cpp:4292
AudioIoCallback::mMinCaptureSecsToCopy
double mMinCaptureSecsToCopy
Definition: AudioIO.h:481
AudioIoCallback::TimeQueue::Consumer
double Consumer(size_t nSamples, double rate)
Definition: AudioIO.cpp:4574
RingBuffer.h
DEFAULT_LATENCY_DURATION
#define DEFAULT_LATENCY_DURATION
Definition: RecordingPrefs.h:33
TransportTracks::prerollTracks
WaveTrackConstArray prerollTracks
Definition: AudioIO.h:99
AudioIoCallback::TimeQueue::mHead
struct AudioIoCallback::TimeQueue::Cursor mHead
AudioIoCallback::SetRecordingException
void SetRecordingException()
Definition: AudioIO.h:541
AudioIoCallback::mCaptureTracks
WaveTrackArray mCaptureTracks
Definition: AudioIO.h:462
SAMPLE_SIZE
#define SAMPLE_SIZE(SampleFormat)
Definition: Types.h:724
AudioIOBase::RecordingSchedule::Consumed
double Consumed() const
Definition: AudioIOBase.cpp:1345
AudioIO::AudioIO
AudioIO()
Definition: AudioIO.cpp:957
Resample.h
AudioIoCallback::mFactor
double mFactor
Definition: AudioIO.h:468
AudioIOBase::PlaybackSchedule::mEnvelope
const BoundedEnvelope * mEnvelope
Definition: AudioIOBase.h:357
AudioIO::SetMixer
void SetMixer(int inputSource, float inputVolume, float playbackVolume)
Definition: AudioIO.cpp:1118
AudioIoCallback::TimeQueue::mLastTime
double mLastTime
Definition: AudioIO.h:570
SampleBuffer::ptr
samplePtr ptr() const
Definition: SampleFormat.h:82
AudioIOBase::PlaybackSchedule::mWarpedTime
double mWarpedTime
Definition: AudioIOBase.h:342
AudioIoCallback::mCachedBestRateOut
static double mCachedBestRateOut
Definition: AudioIO.h:519
AudioIoCallback::TimeQueue::mSize
size_t mSize
Definition: AudioIO.h:569
AudioIoCallback::mPlaybackRingBufferSecs
double mPlaybackRingBufferSecs
Definition: AudioIO.h:473
AudioIOBase::mEmulateMixerOutputVol
bool mEmulateMixerOutputVol
Definition: AudioIOBase.h:292