Allow the option to select sample rate to stream at rather than have it hard coded to 48000hz

This commit is contained in:
jp9000 2013-09-02 18:40:15 -07:00
parent 8fd7282cb8
commit 3520b15ca4
13 changed files with 51 additions and 26 deletions

View File

@ -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
View File

@ -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

View File

@ -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();}

View File

@ -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();

View File

@ -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();

View File

@ -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()

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;}

View File

@ -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);

View File

@ -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);

View File

@ -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);