IXAudio2Engine::CreateSourceVoice fails - c++

I receive the Error XAUDIO2_E_INVALID_CALL when I try to call IXAudio2Engine::CreateSourceVoice. My code for creating a source voice is as follows:
auto sample_rate = quality_to_sample_rate(settings.quality, sound_category::effect);
WAVEFORMATEX wave_format{ // 8000Hz 16 bit mono WAV
.wFormatTag = WAVE_FORMAT_PCM,
.nChannels = 1,
.nSamplesPerSec = sample_rate,
.nAvgBytesPerSec = sample_rate* 2,
.wBitsPerSample = 16,
.cbSize = 0,
};
XAUDIO2_SEND_DESCRIPTOR send_descriptor{.Flags = 0, .pOutputVoice = master_voice};
XAUDIO2_VOICE_SENDS sends{.SendCount = 1, .pSends = &send_descriptor};
res = sound_engine->CreateSourceVoice(&v, &wave_format, 0, 2.0f, nullptr, &sends);
if(FAILED(res)) {
log_error("Could not create effect source voice with", sample_rate, "Hz");
throw std::runtime_error("Could not create effect source voice");
}
log_debug("Created effect source voice with ", sample_rate, "Hz at ", (void*)v);
master_voice is not nullptr and is of type IXAudio2MasteringVoice* (i.e. CreateMasteringVoice returned S_OK!)
What am I missing?
Edit:
According to XAudio2 and *.wav loading, HRESULT 0x88960001 ,
it is possible to set pSendList to NULL which would result in using the MasteringVoice. but that does not help either.

Reading the docs helps:
nBlockAlign and nAvgBytesPerSecond need to be set correctly.
nBlockAlign needs to be (nChannels * (nBitsPerSample/8)) / 8 and
nAvgBytesPerSecond is nBlockAlign * nSamplesPerSecond

Related

WinVerifyTrust only works when using a file not a memory blob

I am trying to the WinVerifyTrust function to verify the signature of a msi.
And while this works for files on the file system I cannot get it to work with a memory blob.
This basis of my example to show the problem is the example program from microsoft
BOOL VerifyEmbeddedSignature(LPCWSTR pwszSourceFile)
{
std::basic_ifstream<BYTE> file(pwszSourceFile, std::ios::binary);
std::vector<BYTE> data((std::istreambuf_iterator<BYTE>(file)),std::istreambuf_iterator<BYTE>());
LONG lStatus;
/*
// this works
WINTRUST_FILE_INFO FileData;
memset(&FileData, 0, sizeof(FileData));
FileData.cbStruct = sizeof(WINTRUST_FILE_INFO);
FileData.pcwszFilePath = pwszSourceFile;
FileData.hFile = NULL;
FileData.pgKnownSubject = NULL;
*/
WINTRUST_BLOB_INFO FileData{};
memset(&FileData, 0, sizeof(FileData));
FileData.cbStruct = sizeof(WINTRUST_BLOB_INFO);
FileData.gSubject = WIN_TRUST_SUBJTYPE_RAW_FILE;
FileData.cbMemObject = static_cast<DWORD>(data.size());
FileData.pbMemObject = data.data();
GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA WinTrustData;
memset(&WinTrustData, 0, sizeof(WinTrustData));
WinTrustData.cbStruct = sizeof(WinTrustData);
WinTrustData.pPolicyCallbackData = NULL;
WinTrustData.pSIPClientData = NULL;
WinTrustData.dwUIChoice = WTD_UI_NONE;
WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
//WinTrustData.dwUnionChoice = WTD_CHOICE_FILE; -- works
WinTrustData.dwUnionChoice = WTD_CHOICE_BLOB;
WinTrustData.dwStateAction = WTD_STATEACTION_VERIFY;
WinTrustData.hWVTStateData = NULL;
WinTrustData.pwszURLReference = NULL;
WinTrustData.dwUIContext = 0;
WinTrustData.pBlob = &FileData;
//WinTrustData.pFile = &FileData; -- works
lStatus = WinVerifyTrust(
NULL,
&WVTPolicyGUID,
&WinTrustData);
WinTrustData.dwStateAction = WTD_STATEACTION_CLOSE;
WinVerifyTrust(
NULL,
&WVTPolicyGUID,
&WinTrustData);
return lStatus == ERROR_SUCCESS;
}
In the above example using the WINTRUST_FILE_INFO works but the WINTRUST_BLOB_INFO does not.
The error that I get with a memory blob is always TRUST_E_PROVIDER_UNKNOWN.
I assume that the problem might be the WIN_TRUST_SUBJTYPE_RAW_FILE subject type but I don't know which one I should use for a msi file.
I am wondering if the sign check is possible at all with memory blobs of msi files.
The WIN_TRUST_SUBJTYPE_RAW_FILE is not the suitable subject GUID. You could The function CryptSIPRetrieveSubjectGuid retrieves a GUID based on the header information in a specified file.

Clearing the stm32f4-discovery flash programatically

I'm having a problem clearing the stm32f429 discovery board flash after creating a window using stemwin library. If I use the code below, flash will be cleared correctly:
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Sector = FLASH_SECTOR_22;
EraseInitStruct.NbSectors = 1;
HAL_FLASH_Unlock();
uint32_t sectorError = 0;
if(HAL_FLASHEx_Erase(&EraseInitStruct,&sectorError)!=HAL_OK)
{
return HAL_FLASH_GetError();
}
HAL_FLASH_Lock();
CreateWindow();
But if I bring the CreateWindow() function to top of the code, flash will not be cleared. Here is CreateWindow() function:
WM_HWIN CreateWindow(void)
{
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
hMultiPage = MULTIPAGE_CreateEx(0, -20, 320, 260, WM_GetClientWindow(hWin), WM_CF_SHOW, 0, 0);
MULTIPAGE_SetSkin(hMultiPage,MULTIPAGE_SKIN_FLEX);
hPage1 = GUI_CreateDialogBox(_aDialogCreate2, GUI_COUNTOF(_aDialogCreate2), _cbDialogPage1, WM_UNATTACHED, 0, 0);
MULTIPAGE_AddPage(hMultiPage, hPage1, "Settings");
hPage2 = GUI_CreateDialogBox(_aDialogCreate3, GUI_COUNTOF(_aDialogCreate3), _cbDialogPage2, WM_UNATTACHED, 0, 0);
MULTIPAGE_AddPage(hMultiPage, hPage2, "Run");
MULTIPAGE_SelectPage(hMultiPage,0);
return hWin;
}
These 2 things has nothing to do between.
There could be a problem, however, that you want to delete sector where data are located (maybe images or similar) for your GUI.
Technically, there is no other option here.
Also, check which value "SectorError" variables has after function completes?

vp9 encoder returns a null packet

i using this code to encode video stream using vp8 and i decided to give vp9 a try so i changed every thing with starts with vp_* from 8 to 9.
but the vp9 encoder always return a null packet although the encoder doesn't return any error.
here is the code i'am using for configuring.
vpx_codec_err_t error = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &enc_cfg, 0);
if(error != VPX_CODEC_OK)
return error;
enc_cfg.g_timebase.den = fps;
enc_cfg.rc_undershoot_pct = 95;
enc_cfg.rc_target_bitrate = bitrate;
enc_cfg.g_error_resilient = 1;
enc_cfg.kf_max_dist = 999999;
enc_cfg.rc_buf_initial_sz = 4000;
enc_cfg.rc_buf_sz = 6000;
enc_cfg.rc_buf_optimal_sz = 5000;
enc_cfg.rc_end_usage = VPX_CBR;
enc_cfg.g_h = height;
enc_cfg.g_w = width;
enc_cfg.rc_min_quantizer = 4;
enc_cfg.rc_max_quantizer = 56;
enc_cfg.g_threads = 4;
enc_cfg.g_pass = VPX_RC_ONE_PASS;
error = vpx_codec_enc_init(&codec, vpx_codec_vp9_cx(), &enc_cfg, 0);
if(error != VPX_CODEC_OK)
return error;
vpx_img_alloc(&vpx_image,VPX_IMG_FMT_I420 , width, height, 1);
configured = true;
return VPX_CODEC_OK;
and the code for the encoding
libyuv::RAWToI420(frame, vpx_image.d_w * 3, vpx_image.planes[VPX_PLANE_Y],vpx_image.stride[VPX_PLANE_Y],
vpx_image.planes[VPX_PLANE_U], vpx_image.stride[VPX_PLANE_U], vpx_image.planes[VPX_PLANE_V],
vpx_image.stride[VPX_PLANE_V], vpx_image.d_w, vpx_image.d_h);
const vpx_codec_cx_pkt_t *pkt;
vpx_codec_err_t error = vpx_codec_encode(&codec, &vpx_image, 0, 1, 0, VPX_DL_GOOD_QUALITY);
if(error != VPX_CODEC_OK)
return vector<byte>();
vpx_codec_iter_t iter = NULL;
if((pkt = vpx_codec_get_cx_data(&codec, &iter)))//always return null ?
{
if(pkt->kind == VPX_CODEC_CX_FRAME_PKT)
{
int length = pkt->data.frame.sz;
byte* buf = (byte*) pkt->data.frame.buf;
vector<byte> data(buf, buf + length);
return data;
}
return vector<byte>();
}
return vector<byte>();
the code is fully working if i'am using vp8 instead of 9, any help is welcomed
Just came across this post because I faced the same problem. Just for other to know: I solved it with setting
enc_cfg.g_lag_in_frames = 0;
This basically disallows the encoder to consume up to default 25 frames until it produces any output.

Migration of JCoFunction in sapjco 3.x

I'm migrating from JCO2.x to 3.x. I have rewritten almost the whole code, but with this I cannot move.
Original 2.x code:
JCO.ParameterList input = new JCO.ParameterList();
input.addInfo("APP_AREA", JCO.TYPE_STRING, 0, 0, 0, JCO.IMPORT_PARAMETER, null);
input.addInfo("XML", JCO.TYPE_STRING, 0, 0, 0, JCO.IMPORT_PARAMETER, null);
JCO.Function function = new JCO.Function(
BAPI_NAMESPACE + "ZZZ",
input, // input
new JCO.ParameterList(), // output
new JCO.ParameterList() // tables
);
My proposed code:
JCoParameterList input = new JCoParameterList();
input.addInfo("APP_AREA", JCO.TYPE_STRING, 0, 0, 0, JCO.IMPORT_PARAMETER, null);
input.addInfo("XML", JCO.TYPE_STRING, 0, 0, 0, JCO.IMPORT_PARAMETER, null);
JCoFunction function = new JCoFunction(
BAPI_NAMESPACE + "ZZZ",
input, // input
new JCoParameterList(), // output
new JCoParameterList() // tables
);
Thing is that JCoFunction cannot be instantiated in this form in 3.x. Should I create function template? Thank you for any hints.
.... a little late response...
You have to get the JcoFunction from your JcoDestination.
e.g.
JCoDestination destination = JCoDestinationManager
.getDestination(destinationName);
JCoRepository repository = destination.getRepository();
JCoFunctionTemplate template = repository.getFunctionTemplate(functionName);
JCoFunction function = template.getFunction();
JCoParameterList input = function_.getImportParameterList();
//set data on input
//execute the function
function.execute(destination);
//access the output
JCoParameterList output = function_.getExportParameterList();
JCoParameterList table = function_.getTableParameterList();

AudioConverterNew returned -50

I have a little issue regarding the use of the AudioQueue services.
I have followed the guide that is available on Apple's webiste, but when I got to start and run the Audio Queue, I get the message telling me that "AudioConverterNew returned -50".
Now, I know that the -50 error code means that there is a bad parameter. However, what I don't know is which parameter is the bad one (thank you so much Apple...) !
So, here's my code.
Here are the parameters of my class, named cPlayerCocoa
AudioQueueRef mQueue;
AudioQueueBufferRef mBuffers[NUMBER_BUFFERS]; // NUMBER_BUFFERS = 3
uint32 mBufferByteSize;
AudioStreamBasicDescription mDataFormat;
Here's the first function :
static void
BuildBuffer( void* iAQData, AudioQueueRef iAQ, AudioQueueBufferRef iBuffer )
{
cPlayerCocoa* player = (cPlayerCocoa*) iAQData;
player->HandleOutputBuffer( iAQ, iBuffer );
}
It creates a cPlayerCocoa from the structure containing the AudioQueue and calls the HandleOutputBuffer function, which allocates the audio buffers :
void
cPlayerCocoa::HandleOutputBuffer( AudioQueueRef iAQ, AudioQueueBufferRef iBuffer )
{
if( mContinue )
{
xassert( iBuffer->mAudioDataByteSize == 32768 );
int startSample = mPlaySampleCurrent;
int result = 0;
int samplecount = 32768 / ( mSoundData->BytesPerSample() ); // BytesPerSample, in my case, returns 4
tErrorCode error = mSoundData->ReadData( (int16*)(iBuffer->mAudioData), samplecount, &result, startSample );
AudioQueueEnqueueBuffer( mQueue, iBuffer, 0, 0 ); // I'm using CBR data (PCM), hence the 0 passed into the AudioQueueEnqueueBuffer.
if( result != samplecount )
mContinue = false;
startSample += result;
}
else
{
AudioQueueStop( mQueue, false );
}
}
In this next function, the AudioQueue is created then started.
I begin to initialise the parameters of the Data format. Then I create the AudioQueue, and I allocate the 3 buffers.
When the buffers are allocated, I start the AudioQueue and then I run the loop.
void
cPlayerCocoa::ThreadEntry()
{
int samplecount = 32768 / ( mSoundData->BytesPerSample() );
mDataFormat.mSampleRate = mSoundData->SamplingRate(); // Returns 44100
mDataFormat.mFormatID = kAudioFormatLinearPCM;
mDataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
mDataFormat.mBytesPerPacket = 32768;
mDataFormat.mFramesPerPacket = samplecount;
mDataFormat.mBytesPerFrame = mSoundData->BytesPerSample(); // BytesPerSample returns 4.
mDataFormat.mChannelsPerFrame = 2;
mDataFormat.mBitsPerChannel = uint32(mSoundData->BitsPerChannel());
mDataFormat.mReserved = 0;
AudioQueueNewOutput( &mDataFormat, BuildBuffer, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue );
for( int i = 0; i < NUMBER_BUFFERS; ++i )
{
AudioQueueAllocateBuffer( mQueue, mBufferByteSize, &mBuffers[i] );
HandleOutputBuffer( mQueue, mBuffers[i] );
}
AudioQueueStart( mQueue, NULL ); // I want the queue to start playing immediately, so I pass NULL
do {
CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.25, false );
} while ( !NeedStopASAP() );
AudioQueueDispose( mQueue, true );
}
The call to AudioQueueStart returns -50 (bad parameter) and I can't figure what's wrong...
I would really appreciate some help, thanks in advance :-)
I think your ASBD is suspect. PCM formats have predictable values for mBytesPerPacket, mBytesPerFrame, and mFramesPerPacket. For normal 16-bit interleaved signed 44.1 stereo audio the ASBD would look like
AudioStreamBasicDescription asbd = {
.mFormatID = kAudioFormatLinearPCM,
.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked,
.mSampleRate = 44100,
.mChannelsPerFrame = 2,
.mBitsPerChannel = 16,
.mBytesPerPacket = 4,
.mFramesPerPacket = 1,
.mBytesPerFrame = 4,
.mReserved = 0
};
AudioConverterNew returns -50 when one of the ASBDs is unsupported. There is no PCM format where mBytesPerPacket should be 32768, which is why you're getting the error.