add WASAPI exclusive mode flag to PortAudio backen
d
This commit is contained in:
		
							parent
							
								
									be38b992e3
								
							
						
					
					
						commit
						fa7405090e
					
				| 
						 | 
					@ -21,6 +21,9 @@
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include "../ta-log.h"
 | 
					#include "../ta-log.h"
 | 
				
			||||||
#include "pa.h"
 | 
					#include "pa.h"
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#include <pa_win_wasapi.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int taPAProcess(const void* in, void* out, unsigned long nframes, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags flags, void* inst) {
 | 
					int taPAProcess(const void* in, void* out, unsigned long nframes, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags flags, void* inst) {
 | 
				
			||||||
  TAAudioPA* instance=(TAAudioPA*)inst;
 | 
					  TAAudioPA* instance=(TAAudioPA*)inst;
 | 
				
			||||||
| 
						 | 
					@ -117,8 +120,18 @@ std::vector<String> TAAudioPA::listAudioDevices() {
 | 
				
			||||||
    if (devInfo==NULL) continue;
 | 
					    if (devInfo==NULL) continue;
 | 
				
			||||||
    if (devInfo->maxOutputChannels<1) continue;
 | 
					    if (devInfo->maxOutputChannels<1) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String devName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const PaHostApiInfo* driverInfo=Pa_GetHostApiInfo(devInfo->hostApi);
 | 
				
			||||||
 | 
					    if (driverInfo==NULL) {
 | 
				
			||||||
 | 
					      devName+="[???] ";
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      devName+=fmt::sprintf("[%s] ",driverInfo->name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (devInfo->name!=NULL) {
 | 
					    if (devInfo->name!=NULL) {
 | 
				
			||||||
      ret.push_back(String(devInfo->name));
 | 
					      devName+=devInfo->name;
 | 
				
			||||||
 | 
					      ret.push_back(devName);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -146,11 +159,15 @@ bool TAAudioPA::init(TAAudioDesc& request, TAAudioDesc& response) {
 | 
				
			||||||
  desc.outFormat=TA_AUDIO_FORMAT_F32;
 | 
					  desc.outFormat=TA_AUDIO_FORMAT_F32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const PaDeviceInfo* devInfo=NULL;
 | 
					  const PaDeviceInfo* devInfo=NULL;
 | 
				
			||||||
 | 
					  const PaHostApiInfo* driverInfo=NULL;
 | 
				
			||||||
  int outDeviceID=0;
 | 
					  int outDeviceID=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (desc.deviceName.empty()) {
 | 
					  if (desc.deviceName.empty()) {
 | 
				
			||||||
    outDeviceID=Pa_GetDefaultOutputDevice();
 | 
					    outDeviceID=Pa_GetDefaultOutputDevice();
 | 
				
			||||||
    devInfo=Pa_GetDeviceInfo(outDeviceID);
 | 
					    devInfo=Pa_GetDeviceInfo(outDeviceID);
 | 
				
			||||||
 | 
					    if (devInfo!=NULL) {
 | 
				
			||||||
 | 
					      driverInfo=Pa_GetHostApiInfo(devInfo->hostApi);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    int count=Pa_GetDeviceCount();
 | 
					    int count=Pa_GetDeviceCount();
 | 
				
			||||||
    bool found=false;
 | 
					    bool found=false;
 | 
				
			||||||
| 
						 | 
					@ -164,12 +181,25 @@ bool TAAudioPA::init(TAAudioDesc& request, TAAudioDesc& response) {
 | 
				
			||||||
      if (devInfo==NULL) continue;
 | 
					      if (devInfo==NULL) continue;
 | 
				
			||||||
      if (devInfo->maxOutputChannels<1) continue;
 | 
					      if (devInfo->maxOutputChannels<1) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      String devName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      driverInfo=Pa_GetHostApiInfo(devInfo->hostApi);
 | 
				
			||||||
 | 
					      if (driverInfo==NULL) {
 | 
				
			||||||
 | 
					        devName+="[???] ";
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        devName+=fmt::sprintf("[%s] ",driverInfo->name);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (devInfo->name!=NULL) {
 | 
					      if (devInfo->name!=NULL) {
 | 
				
			||||||
        if (strcmp(devInfo->name,desc.deviceName.c_str())==0) {
 | 
					        devName+=devInfo->name;
 | 
				
			||||||
          outDeviceID=i;
 | 
					      } else {
 | 
				
			||||||
          found=true;
 | 
					        continue;
 | 
				
			||||||
          break;
 | 
					      }
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
 | 
					      if (devName==desc.deviceName) {
 | 
				
			||||||
 | 
					        outDeviceID=i;
 | 
				
			||||||
 | 
					        found=true;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!found) {
 | 
					    if (!found) {
 | 
				
			||||||
| 
						 | 
					@ -190,6 +220,27 @@ bool TAAudioPA::init(TAAudioDesc& request, TAAudioDesc& response) {
 | 
				
			||||||
  outParams.suggestedLatency=(double)(desc.bufsize*desc.fragments)/desc.rate;
 | 
					  outParams.suggestedLatency=(double)(desc.bufsize*desc.fragments)/desc.rate;
 | 
				
			||||||
  outParams.hostApiSpecificStreamInfo=NULL;
 | 
					  outParams.hostApiSpecificStreamInfo=NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (driverInfo!=NULL) {
 | 
				
			||||||
 | 
					    if (driverInfo->type==paWASAPI) {
 | 
				
			||||||
 | 
					      logV("setting WASAPI-specific flags");
 | 
				
			||||||
 | 
					      PaWasapiStreamInfo* wasapiInfo=new PaWasapiStreamInfo;
 | 
				
			||||||
 | 
					      memset(wasapiInfo,0,sizeof(PaWasapiStreamInfo));
 | 
				
			||||||
 | 
					      wasapiInfo->size=sizeof(PaWasapiStreamInfo);
 | 
				
			||||||
 | 
					      wasapiInfo->hostApiType=paWASAPI;
 | 
				
			||||||
 | 
					      wasapiInfo->version=1;
 | 
				
			||||||
 | 
					      wasapiInfo->flags=paWinWasapiThreadPriority;
 | 
				
			||||||
 | 
					      wasapiInfo->threadPriority=eThreadPriorityProAudio;
 | 
				
			||||||
 | 
					      wasapiInfo->streamCategory=eAudioCategoryMedia;
 | 
				
			||||||
 | 
					      wasapiInfo->streamOption=eStreamOptionRaw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (desc.wasapiEx) {
 | 
				
			||||||
 | 
					        wasapiInfo->flags|=paWinWasapiExclusive;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      outParams.hostApiSpecificStreamInfo=wasapiInfo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logV("opening audio device...");
 | 
					  logV("opening audio device...");
 | 
				
			||||||
  status=Pa_OpenStream(
 | 
					  status=Pa_OpenStream(
 | 
				
			||||||
    &ac,
 | 
					    &ac,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,13 +58,16 @@ struct TAAudioDesc {
 | 
				
			||||||
  unsigned char inChans, outChans;
 | 
					  unsigned char inChans, outChans;
 | 
				
			||||||
  TAAudioFormat outFormat;
 | 
					  TAAudioFormat outFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool wasapiEx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TAAudioDesc():
 | 
					  TAAudioDesc():
 | 
				
			||||||
    rate(0.0),
 | 
					    rate(0.0),
 | 
				
			||||||
    bufsize(0),
 | 
					    bufsize(0),
 | 
				
			||||||
    fragments(0),
 | 
					    fragments(0),
 | 
				
			||||||
    inChans(0),
 | 
					    inChans(0),
 | 
				
			||||||
    outChans(0),
 | 
					    outChans(0),
 | 
				
			||||||
    outFormat(TA_AUDIO_FORMAT_F32) {}
 | 
					    outFormat(TA_AUDIO_FORMAT_F32),
 | 
				
			||||||
 | 
					    wasapiEx(false) {}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3370,6 +3370,7 @@ bool DivEngine::initAudioBackend() {
 | 
				
			||||||
  want.inChans=0;
 | 
					  want.inChans=0;
 | 
				
			||||||
  want.outChans=getConfInt("audioChans",2);
 | 
					  want.outChans=getConfInt("audioChans",2);
 | 
				
			||||||
  want.outFormat=TA_AUDIO_FORMAT_F32;
 | 
					  want.outFormat=TA_AUDIO_FORMAT_F32;
 | 
				
			||||||
 | 
					  want.wasapiEx=getConfInt("wasapiEx",0);
 | 
				
			||||||
  want.name="Furnace";
 | 
					  want.name="Furnace";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (want.outChans<1) want.outChans=1;
 | 
					  if (want.outChans<1) want.outChans=1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1571,6 +1571,7 @@ class FurnaceGUI {
 | 
				
			||||||
    int centerPopup;
 | 
					    int centerPopup;
 | 
				
			||||||
    int insIconsStyle;
 | 
					    int insIconsStyle;
 | 
				
			||||||
    int classicChipOptions;
 | 
					    int classicChipOptions;
 | 
				
			||||||
 | 
					    int wasapiEx;
 | 
				
			||||||
    unsigned int maxUndoSteps;
 | 
					    unsigned int maxUndoSteps;
 | 
				
			||||||
    String mainFontPath;
 | 
					    String mainFontPath;
 | 
				
			||||||
    String headFontPath;
 | 
					    String headFontPath;
 | 
				
			||||||
| 
						 | 
					@ -1745,6 +1746,7 @@ class FurnaceGUI {
 | 
				
			||||||
      centerPopup(1),
 | 
					      centerPopup(1),
 | 
				
			||||||
      insIconsStyle(1),
 | 
					      insIconsStyle(1),
 | 
				
			||||||
      classicChipOptions(0),
 | 
					      classicChipOptions(0),
 | 
				
			||||||
 | 
					      wasapiEx(0),
 | 
				
			||||||
      maxUndoSteps(100),
 | 
					      maxUndoSteps(100),
 | 
				
			||||||
      mainFontPath(""),
 | 
					      mainFontPath(""),
 | 
				
			||||||
      headFontPath(""),
 | 
					      headFontPath(""),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -872,11 +872,11 @@ void FurnaceGUI::drawSettings() {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool lowLatencyB=settings.lowLatency;
 | 
					        bool lowLatencyB=settings.lowLatency;
 | 
				
			||||||
        if (ImGui::Checkbox("Low-latency mode (experimental!)",&lowLatencyB)) {
 | 
					        if (ImGui::Checkbox("Low-latency mode",&lowLatencyB)) {
 | 
				
			||||||
          settings.lowLatency=lowLatencyB;
 | 
					          settings.lowLatency=lowLatencyB;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (ImGui::IsItemHovered()) {
 | 
					        if (ImGui::IsItemHovered()) {
 | 
				
			||||||
          ImGui::SetTooltip("reduces latency by running the engine faster than the tick rate.\nuseful for live playback/jam mode.\n\nwarning: experimental! may produce glitches.\nonly enable if your buffer size is small (10ms or less).");
 | 
					          ImGui::SetTooltip("reduces latency by running the engine faster than the tick rate.\nuseful for live playback/jam mode.\n\nwarning: nonly enable if your buffer size is small (10ms or less).");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool forceMonoB=settings.forceMono;
 | 
					        bool forceMonoB=settings.forceMono;
 | 
				
			||||||
| 
						 | 
					@ -884,6 +884,15 @@ void FurnaceGUI::drawSettings() {
 | 
				
			||||||
          settings.forceMono=forceMonoB;
 | 
					          settings.forceMono=forceMonoB;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (settings.audioEngine==DIV_AUDIO_PORTAUDIO) {
 | 
				
			||||||
 | 
					          if (settings.audioDevice.find("[Windows WASAPI] ")==0) {
 | 
				
			||||||
 | 
					            bool wasapiExB=settings.wasapiEx;
 | 
				
			||||||
 | 
					            if (ImGui::Checkbox("Exclusive mode",&wasapiExB)) {
 | 
				
			||||||
 | 
					              settings.wasapiEx=wasapiExB;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TAAudioDesc& audioWant=e->getAudioDescWant();
 | 
					        TAAudioDesc& audioWant=e->getAudioDescWant();
 | 
				
			||||||
        TAAudioDesc& audioGot=e->getAudioDescGot();
 | 
					        TAAudioDesc& audioGot=e->getAudioDescGot();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3252,6 +3261,7 @@ void FurnaceGUI::syncSettings() {
 | 
				
			||||||
  settings.centerPopup=e->getConfInt("centerPopup",1);
 | 
					  settings.centerPopup=e->getConfInt("centerPopup",1);
 | 
				
			||||||
  settings.insIconsStyle=e->getConfInt("insIconsStyle",1);
 | 
					  settings.insIconsStyle=e->getConfInt("insIconsStyle",1);
 | 
				
			||||||
  settings.classicChipOptions=e->getConfInt("classicChipOptions",0);
 | 
					  settings.classicChipOptions=e->getConfInt("classicChipOptions",0);
 | 
				
			||||||
 | 
					  settings.wasapiEx=e->getConfInt("wasapiEx",0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  clampSetting(settings.mainFontSize,2,96);
 | 
					  clampSetting(settings.mainFontSize,2,96);
 | 
				
			||||||
  clampSetting(settings.headFontSize,2,96);
 | 
					  clampSetting(settings.headFontSize,2,96);
 | 
				
			||||||
| 
						 | 
					@ -3399,6 +3409,7 @@ void FurnaceGUI::syncSettings() {
 | 
				
			||||||
  clampSetting(settings.centerPopup,0,1);
 | 
					  clampSetting(settings.centerPopup,0,1);
 | 
				
			||||||
  clampSetting(settings.insIconsStyle,0,2);
 | 
					  clampSetting(settings.insIconsStyle,0,2);
 | 
				
			||||||
  clampSetting(settings.classicChipOptions,0,1);
 | 
					  clampSetting(settings.classicChipOptions,0,1);
 | 
				
			||||||
 | 
					  clampSetting(settings.wasapiEx,0,1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (settings.exportLoops<0.0) settings.exportLoops=0.0;
 | 
					  if (settings.exportLoops<0.0) settings.exportLoops=0.0;
 | 
				
			||||||
  if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
 | 
					  if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
 | 
				
			||||||
| 
						 | 
					@ -3653,6 +3664,7 @@ void FurnaceGUI::commitSettings() {
 | 
				
			||||||
  e->setConf("centerPopup",settings.centerPopup);
 | 
					  e->setConf("centerPopup",settings.centerPopup);
 | 
				
			||||||
  e->setConf("insIconsStyle",settings.insIconsStyle);
 | 
					  e->setConf("insIconsStyle",settings.insIconsStyle);
 | 
				
			||||||
  e->setConf("classicChipOptions",settings.classicChipOptions);
 | 
					  e->setConf("classicChipOptions",settings.classicChipOptions);
 | 
				
			||||||
 | 
					  e->setConf("wasapiEx",settings.wasapiEx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // colors
 | 
					  // colors
 | 
				
			||||||
  for (int i=0; i<GUI_COLOR_MAX; i++) {
 | 
					  for (int i=0; i<GUI_COLOR_MAX; i++) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue