Allow the option to select sample rate to stream at rather than have it hard coded to 48000hz
This commit is contained in:
parent
8fd7282cb8
commit
3520b15ca4
@ -74,8 +74,7 @@ void NoiseGateFilter::ApplyNoiseGate(float *buffer, int totalFloats)
|
||||
if(totalFloats % 2)
|
||||
return; // Odd number of samples
|
||||
|
||||
// OBS is currently hard-coded to 48ksps
|
||||
const float SAMPLE_RATE_F = 48000.0f;
|
||||
const float SAMPLE_RATE_F = float(OBSGetSampleRateHz());
|
||||
const float dtPerSample = 1.0f / SAMPLE_RATE_F;
|
||||
|
||||
// Convert configuration times into per-sample amounts
|
||||
@ -83,10 +82,9 @@ void NoiseGateFilter::ApplyNoiseGate(float *buffer, int totalFloats)
|
||||
const float releaseRate = 1.0f / (parent->releaseTime * SAMPLE_RATE_F);
|
||||
|
||||
// Determine level decay rate. We don't want human voice (75-300Hz) to cross the close
|
||||
// threshold if the previous peak crosses the open threshold. 75Hz at 48ksps is 640
|
||||
// samples between peaks.
|
||||
// threshold if the previous peak crosses the open threshold.
|
||||
const float thresholdDiff = parent->openThreshold - parent->closeThreshold;
|
||||
const float minDecayPeriod = (1.0f / 75.0f) * SAMPLE_RATE_F; // 640 samples
|
||||
const float minDecayPeriod = (1.0f / 75.0f) * SAMPLE_RATE_F;
|
||||
const float decayRate = thresholdDiff / minDecayPeriod;
|
||||
|
||||
// We can't use SSE as the processing of each sample depends on the processed
|
||||
|
2
OBS.rc
2
OBS.rc
@ -126,7 +126,7 @@ BEGIN
|
||||
RTEXT "Settings.Encoding.Audio.Bitrate",IDC_STATIC,221,85,128,8
|
||||
COMBOBOX IDC_AUDIOBITRATE,354,83,61,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
RTEXT "Settings.Encoding.Audio.Format",IDC_STATIC,10,101,138,8
|
||||
COMBOBOX IDC_AUDIOFORMAT,152,99,264,62,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_AUDIOFORMAT,152,99,264,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Settings.Info",IDC_INFO,4,122,417,37,NOT WS_VISIBLE
|
||||
END
|
||||
|
||||
|
@ -141,4 +141,6 @@ void OBSGetCurMicVolumeStats(float *rms, float *max, float *peak) {API->Ge
|
||||
void OBSAddSettingsPane(SettingsPane *pane) {API->AddSettingsPane(pane);}
|
||||
void OBSRemoveSettingsPane(SettingsPane *pane) {API->RemoveSettingsPane(pane);}
|
||||
|
||||
UINT OBSGetAPIVersion() {return 0x0100;}
|
||||
UINT OBSGetAPIVersion() {return 0x0101;}
|
||||
|
||||
UINT OBSGetSampleRateHz() {return API->GetSampleRateHz();}
|
||||
|
@ -172,6 +172,8 @@ public:
|
||||
virtual Vect2 MapFrameToWindowSize(Vect2 frameSize) const=0;
|
||||
virtual Vect2 GetWindowToFrameScale() const=0;
|
||||
virtual Vect2 GetFrameToWindowScale() const=0;
|
||||
|
||||
virtual UINT GetSampleRateHz() const=0;
|
||||
};
|
||||
|
||||
BASE_EXPORT extern APIInterface *API;
|
||||
@ -286,3 +288,5 @@ BASE_EXPORT void OBSRemoveSettingsPane(SettingsPane *pane);
|
||||
|
||||
/** gets API version. version is formatted: 0xMMmm */
|
||||
BASE_EXPORT UINT OBSGetAPIVersion();
|
||||
|
||||
BASE_EXPORT UINT OBSGetSampleRateHz();
|
||||
|
@ -87,7 +87,9 @@ void AudioSource::InitAudioData(bool bFloat, UINT channels, UINT samplesPerSec,
|
||||
|
||||
//-----------------------------
|
||||
|
||||
if(inputSamplesPerSec != 48000)
|
||||
UINT sampleRateHz = OBSGetSampleRateHz();
|
||||
|
||||
if(inputSamplesPerSec != sampleRateHz)
|
||||
{
|
||||
int errVal;
|
||||
|
||||
@ -96,12 +98,11 @@ void AudioSource::InitAudioData(bool bFloat, UINT channels, UINT samplesPerSec,
|
||||
if(!resampler)
|
||||
CrashError(TEXT("AudioSource::InitAudioData: Could not initiate resampler"));
|
||||
|
||||
resampleRatio = 48000.0 / double(inputSamplesPerSec);
|
||||
resampleRatio = double(sampleRateHz) / double(inputSamplesPerSec);
|
||||
bResample = true;
|
||||
|
||||
//----------------------------------------------------
|
||||
// hack to get rid of that weird first quirky resampled packet size
|
||||
// (always returns a non-480 sized packet on the first resample)
|
||||
|
||||
SRC_DATA data;
|
||||
data.src_ratio = resampleRatio;
|
||||
@ -679,7 +680,7 @@ bool AudioSource::GetBuffer(float **buffer, QWORD targetTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
outputBuffer.SetSize(480*2);
|
||||
outputBuffer.SetSize(OBSGetSampleRateHz()/100*2);
|
||||
|
||||
*buffer = outputBuffer.Array();
|
||||
|
||||
|
@ -539,6 +539,8 @@ public:
|
||||
|
||||
virtual void AddSettingsPane(SettingsPane *pane) {App->AddSettingsPane(pane);}
|
||||
virtual void RemoveSettingsPane(SettingsPane *pane) {App->RemoveSettingsPane(pane);}
|
||||
|
||||
virtual UINT GetSampleRateHz() const {return App->GetSampleRateHz();}
|
||||
};
|
||||
|
||||
APIInterface* CreateOBSApiInterface()
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
{
|
||||
curBitRate = bitRate;
|
||||
|
||||
faac = faacEncOpen(48000, 2, &numReadSamples, &outputSize);
|
||||
faac = faacEncOpen(App->GetSampleRateHz(), 2, &numReadSamples, &outputSize);
|
||||
|
||||
//Log(TEXT("numReadSamples: %d"), numReadSamples);
|
||||
aacBuffer.SetSize(outputSize+2);
|
||||
@ -155,7 +155,7 @@ public:
|
||||
inputBuffer.RemoveRange(0, numReadSamples);
|
||||
|
||||
bufferedTimestamps << curEncodeTimestamp;
|
||||
curEncodeTimestamp = curTimestamp + (((numReadSamples-lastSampleSize)/2)/48);
|
||||
curEncodeTimestamp = curTimestamp + (((numReadSamples-lastSampleSize)/2)*1000/App->GetSampleRateHz());
|
||||
}
|
||||
|
||||
return ret > 0;
|
||||
|
@ -59,8 +59,8 @@ public:
|
||||
if(!lgf)
|
||||
CrashError(TEXT("Unable to open mp3 encoder"));
|
||||
|
||||
lame_set_in_samplerate(lgf, 48000);
|
||||
lame_set_out_samplerate(lgf, 48000);
|
||||
lame_set_in_samplerate(lgf, App->GetSampleRateHz());
|
||||
lame_set_out_samplerate(lgf, App->GetSampleRateHz());
|
||||
lame_set_num_channels(lgf, 2);
|
||||
lame_set_mode(lgf, STEREO);
|
||||
lame_set_disable_reservoir(lgf, TRUE); //bit reservoir has to be disabled for seamless streaming
|
||||
@ -102,7 +102,7 @@ public:
|
||||
frameCounter -= outputFrameSize;
|
||||
|
||||
bufferedTimestamps << curEncodeTimestamp;
|
||||
curEncodeTimestamp = timestamp + ((outputFrameSize-lastSampleSize)/48);
|
||||
curEncodeTimestamp = timestamp + ((outputFrameSize-lastSampleSize)*1000/App->GetSampleRateHz());
|
||||
}
|
||||
|
||||
int ret = lame_encode_buffer_interleaved_ieee_float(lgf, (float*)input, numInputFrames, MP3OutputBuffer.Array()+1, dwMP3MaxSize);
|
||||
|
@ -57,7 +57,7 @@ struct MP4AudioFrameInfo
|
||||
|
||||
inline UINT64 ConvertToAudioTime(DWORD timestamp, UINT64 minVal)
|
||||
{
|
||||
UINT val = UINT64(timestamp)*48000/1000;
|
||||
UINT val = UINT64(timestamp)*App->GetSampleRateHz()/1000;
|
||||
return MAX(val, minVal);
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ public:
|
||||
|
||||
DWORD macTime = fastHtonl(DWORD(GetMacTime()));
|
||||
UINT videoDuration = fastHtonl(lastVideoTimestamp + App->GetFrameTime());
|
||||
UINT audioDuration = fastHtonl(lastVideoTimestamp + DWORD(double(audioFrameSize)/48));
|
||||
UINT audioDuration = fastHtonl(lastVideoTimestamp + DWORD(double(audioFrameSize)*1000.0/double(App->GetSampleRateHz())));
|
||||
UINT width, height;
|
||||
App->GetOutputSize(width, height);
|
||||
|
||||
@ -453,7 +453,7 @@ public:
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(macTime); //creation time
|
||||
output.OutputDword(macTime); //modified time
|
||||
output.OutputDword(DWORD_BE(48000)); //time scale
|
||||
output.OutputDword(DWORD_BE(App->GetSampleRateHz())); //time scale
|
||||
output.OutputDword(audioUnitDuration);
|
||||
output.OutputDword(bMP3 ? DWORD_BE(0x55c40000) : DWORD_BE(0x15c70000));
|
||||
PopBox(output); //mdhd
|
||||
@ -495,7 +495,7 @@ public:
|
||||
output.OutputWord(WORD_BE(16)); //sample size
|
||||
output.OutputWord(0); //quicktime audio compression id
|
||||
output.OutputWord(0); //quicktime audio packet size
|
||||
output.OutputDword(DWORD_BE(48000<<16)); //sample rate (fixed point)
|
||||
output.OutputDword(DWORD_BE(App->GetSampleRateHz()<<16)); //sample rate (fixed point)
|
||||
PushBox(output, DWORD_BE('esds'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputByte(3); //ES descriptor type
|
||||
|
@ -499,6 +499,8 @@ class OBS
|
||||
AudioSource *micAudio;
|
||||
List<AudioSource*> auxAudioSources;
|
||||
|
||||
UINT sampleRateHz;
|
||||
|
||||
AudioEncoder *audioEncoder;
|
||||
|
||||
//---------------------------------------------------
|
||||
@ -913,6 +915,8 @@ public:
|
||||
OSLeaveMutex(hAuxAudioMutex);
|
||||
}
|
||||
|
||||
inline UINT GetSampleRateHz() const {return sampleRateHz;}
|
||||
|
||||
inline QWORD GetAudioTime() const {return latestAudioTime;}
|
||||
inline QWORD GetVideoTime() const {return latestVideoTime;}
|
||||
|
||||
|
@ -284,7 +284,20 @@ retryHookTestV2:
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
|
||||
UINT format = AppConfig->GetInt(L"Audio Encoding", L"Format", 1);
|
||||
|
||||
switch (format) {
|
||||
case 0: sampleRateHz = 44100; break;
|
||||
default:
|
||||
case 1: sampleRateHz = 48000; break;
|
||||
}
|
||||
|
||||
Log(L"------------------------------------------");
|
||||
Log(L"Audio Format: %uhz", sampleRateHz);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
AudioDeviceList playbackDevices;
|
||||
GetAudioDevices(playbackDevices, ADT_PLAYBACK);
|
||||
@ -881,11 +894,11 @@ void OBS::EncodeAudioSegment(float *buffer, UINT numFrames, QWORD timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
const int audioSamplesPerSec = 48000;
|
||||
const int audioSampleSize = audioSamplesPerSec/100;
|
||||
|
||||
void OBS::MainAudioLoop()
|
||||
{
|
||||
const unsigned int audioSamplesPerSec = App->GetSampleRateHz();
|
||||
const unsigned int audioSampleSize = audioSamplesPerSec/100;
|
||||
|
||||
DWORD taskID = 0;
|
||||
HANDLE hTask = AvSetMmThreadCharacteristics(TEXT("Pro Audio"), &taskID);
|
||||
|
||||
|
@ -265,7 +265,7 @@ char* OBS::EncMetaData(char *enc, char *pend, bool bFLVFile)
|
||||
enc = AMF_EncodeNamedString(enc, pend, &av_audiocodecid, av_codecFourCC);//audioCodecID);//
|
||||
|
||||
enc = AMF_EncodeNamedNumber(enc, pend, &av_audiodatarate, double(audioBitRate)); //ex. 128kb\s
|
||||
enc = AMF_EncodeNamedNumber(enc, pend, &av_audiosamplerate, 48000.0);
|
||||
enc = AMF_EncodeNamedNumber(enc, pend, &av_audiosamplerate, double(App->GetSampleRateHz()));
|
||||
enc = AMF_EncodeNamedNumber(enc, pend, &av_audiosamplesize, 16.0);
|
||||
enc = AMF_EncodeNamedNumber(enc, pend, &av_audiochannels, 2.0);
|
||||
enc = AMF_EncodeNamedBoolean(enc, pend, &av_stereo, true);
|
||||
|
@ -213,7 +213,8 @@ INT_PTR SettingsEncoding::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam
|
||||
//--------------------------------------------
|
||||
|
||||
hwndTemp = GetDlgItem(hwnd, IDC_AUDIOFORMAT);
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48khz mono"));
|
||||
//SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48khz mono"));
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("44.1khz stereo"));
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("48khz stereo"));
|
||||
|
||||
LoadSettingComboInt(hwndTemp, TEXT("Audio Encoding"), TEXT("Format"), 1, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user