Retrieve HostCallbackInfo from AudioKit to Sync IAA and AKSequencer - audiounit

I'm struggled trying to sync AKSequencer with IAA.
Need to get HostCallbackInfo from the AudioUnit. In Core Audio and ObjC, would be something like this:
UInt32 dataSize = sizeof(HostCallbackInfo);
callBackInfo = (HostCallbackInfo*) malloc(dataSize);
OSStatus result = AudioUnitGetProperty(audioController.audioUnit, kAudioUnitProperty_HostCallbacks, kAudioUnitScope_Global, 0, callBackInfo, &dataSize);
Now, with AudioKit and AKSequencer in Swift, how can I get this HostCallbackInfo data ?

Related

How to make POST request to a web server with C++ and Core Foundation APIs for macOS?

I'm trying to follow this example to let me make a POST request to a web server and receive its response in pure C++ using Core Foundation functions. I'll copy and paste it here:
void PostRequest()
{
// Create the POST request payload.
CFStringRef payloadString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("{\"test-data-key\" : \"test-data-value\"}"));
CFDataRef payloadData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, payloadString, kCFStringEncodingUTF8, 0);
CFRelease(payloadString);
//create request
CFURLRef theURL = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("https://httpbin.org/post"), NULL); //https://httpbin.org/post returns post data
CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("POST"), theURL, kCFHTTPVersion1_1);
CFHTTPMessageSetBody(request, payloadData);
//add some headers
CFStringRef hostString = CFURLCopyHostName(theURL);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("HOST"), hostString);
CFRelease(hostString);
CFRelease(theURL);
if (payloadData)
{
CFStringRef lengthString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), CFDataGetLength(payloadData));
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Length"), lengthString);
CFRelease(lengthString);
}
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), CFSTR("charset=utf-8"));
//create read stream for response
CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
CFRelease(request);
//set up on separate runloop (with own thread) to avoid blocking the UI
CFReadStreamScheduleWithRunLoop(requestStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFOptionFlags optionFlags = (kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered);
CFStreamClientContext clientContext = {0, (void *)payloadData, RetainSocketStreamHandle, ReleaseSocketStreamHandle, NULL};
CFReadStreamSetClient(requestStream, optionFlags, ReadStreamCallBack, &clientContext);
//start request
CFReadStreamOpen(requestStream);
if (payloadData)
{
CFRelease(payloadData);
}
}
And the callback:
void LogData(CFDataRef responseData)
{
CFIndex dataLength = CFDataGetLength(responseData);
UInt8 *bytes = (UInt8 *)malloc(dataLength);
CFDataGetBytes(responseData, CFRangeMake(0, CFDataGetLength(responseData)), bytes);
CFStringRef responseString = CFStringCreateWithBytes(kCFAllocatorDefault, bytes, dataLength, kCFStringEncodingUTF8, TRUE);
CFShow(responseString);
CFRelease(responseString);
free(bytes);
}
static void ReadStreamCallBack(CFReadStreamRef readStream, CFStreamEventType type, void *clientCallBackInfo)
{
CFDataRef passedInData = (CFDataRef)(clientCallBackInfo);
CFShow(CFSTR("Passed In Data:"));
LogData(passedInData);
//append data as we receive it
CFMutableDataRef responseBytes = CFDataCreateMutable(kCFAllocatorDefault, 0);
CFIndex numberOfBytesRead = 0;
do
{
UInt8 buf[1024];
numberOfBytesRead = CFReadStreamRead(readStream, buf, sizeof(buf));
if (numberOfBytesRead > 0)
{
CFDataAppendBytes(responseBytes, buf, numberOfBytesRead);
}
} while (numberOfBytesRead > 0);
//once all data is appended, package it all together - create a response from the response headers, and add the data received.
//note: just having the data received is not enough, you need to finish the response by retrieving the response headers here...
CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader);
if (responseBytes)
{
if (response)
{
CFHTTPMessageSetBody(response, responseBytes);
}
CFRelease(responseBytes);
}
//close and cleanup
CFReadStreamClose(readStream);
CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFRelease(readStream);
//just keep the response body and release requests
CFDataRef responseBodyData = CFHTTPMessageCopyBody(response);
if (response)
{
CFRelease(response);
}
//get the response as a string
if (responseBodyData)
{
CFShow(CFSTR("\nResponse Data:"));
LogData(responseBodyData);
CFRelease(responseBodyData);
}
}
I understood how it works, and started implementing it ..... only to get this error:
'CFReadStreamCreateForHTTPRequest' is deprecated: first deprecated in
macOS 10.11 - Use NSURLSession API for http requests
There's absolutely zero examples how to use NSURLSession for C++, or how to bypass that idiotic "is deprecated" error.
Any help on how am I supposed to code this in C++ now?
PS. I don't want to use any third-party libraries. This is a simple task that was available with simple API calls (as I showed above.)
PS2. Sorry I am not an Apple developer, and I'm not used to features being deprecated on the whim.
There are 3 options.
Ignore the warning.
Use ObjC runtme.
Use libcurl
The first one is the easiest and the second one is the hardest solutions for your skills. The third option is easy and the most advanced solution - if you extend you software with new features, CFNetwork will lack of functionality.

Try to get blob data from Oracle by OCI routines but get error: ORA-01008: not all variables bound

I try to get blob data from Oracle by OCI routines.
I use the next code but the exceute statement gives ther error: ORA-01008: not all variables bound
What do I wrong? Can anybody help me?
Thanks,
Kees Braaksma
void get_blob_data()
{
// The query
// The results of this methode
// if errstring is empty, the blob data can be found in the 4th parameter.
// otherwise the error is given in errstring
CString csQuery;
csQuery.Format("BEGIN get_blob('%s','%ld',:ERRSTRING,:BLOB); END;", "20", 200);
//init
OCIHandleAlloc((dvoid *)m_OCIEnvironment , (dvoid **)(&m_OCIStatement),
(ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);
//Prepare statement voor query
OCIStmtPrepare(m_OCIStatement, m_OCIError, (text *)(csQuery),
(ub4)(strlen(csQuery)), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
// output variables
char *pszResult = (char*)malloc(256);
memset(pszResult, 0, sizeof(pszResult));
Blob *blob = new Blob();
m_pIndicator1 = malloc(sizeof(OCIInd));
m_pDefine1 = NULL;
OCIDefineByPos(m_OCIStatement, &m_pDefine1, m_OCIError, (ub4)1,
(dvoid*)*pszResult,
(sb4)256, SQLT_STR,
(dvoid*)m_pIndicator1,
(ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT);
m_pIndicator2 = malloc(sizeof(OCIInd));
m_pDefine2 = NULL;
OCIDescriptorAlloc(m_OCIEnvironment, &blob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
OCIDefineByPos(m_OCIStatement, &m_pDefine2,
m_OCIError, (ub4)2,
(dvoid*)blob,
(sb4)-1, SQLT_BLOB,
(dvoid*)m_pIndicator2,
(ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT));
iStatus = OCIStmtExecute(m_OCISrvCtx, m_OCIStatement, m_OCIError, (ub4)1, (ub4)0,
(OCISnapshot *)NULL, (OCISnapshot *)NULL,
(ub4)OCI_DEFAULT);
// results:
// iStatus = -1;
// Errorstring: ORA-01008: not all variables bound
}
You don't have any OCIBindByName() calls. OCIDefineByPos() is used when running SQL queries, which you aren't.
It's odd that you use a mixture of %s and bind variables in the PL/SQL call. I think you want to use bind variables for all parameters.
One handy hint is to see how ODPI-C uses OCI. For LOBs you can get either locators or data directly. The latter is a lot faster, but limited to 1G. It's arguably easiest to install Python and cx_Oracle, and run some samples e.g. ReturnLobsAsStrings.py. You can trace the OCI calls in dpiOci.c.
There are some sample OCI programs (sadly not so accessible - your DBA may be able to install them), look out for cdemolb.c and cdemolbs.c
Best Oracle-users,
Still have problems with getting a blob from Oracle. I use it so less.
Most of the time I copy some code and a new query is working fine.
I asked my collegue to change the function.
New the query is:
select ngm_transactie_pck.get_checkout_blob('20','200') from dual
the result of this function is a blob.
So i programmed:
static OCILobLocator *blob = NULL;
after OCIHandleAlloc() and OCIStmtPrepare() as in previous example i have:
OCIDescriptorAlloc(m_OCIEnvironment, &blob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
CIDefineByPos(m_OCIStatement, &m_pDefine2,
m_OCIError, (ub4)1,
(dvoid*)&blob,
(sb4)-1, OCI_DTYPE_LOB,
(dvoid*)m_pIndicator2,
(ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT));
The call to OciDefineByPos() gives crash/stackoverflow.
What do I wrong?
Greetz,
Kees

Core Audio specify which audio track to decode

I am able to successfully get the decoded PCM data of an audio file using Core Audio API. Below is the reduced code that shows how do I do that:
CFStringRef urlStr = CFStringCreateWithCString(kCFAllocatorDefault, "file.m4a", kCFStringEncodingUTF8);
CFURLRef urlRef = CFURLCreateWithFileSystemPath(NULL, urlStr, kCFURLPOSIXPathStyle, false);
ExtAudioFileOpenURL(urlRef, &m_audioFile);
bzero(&m_outputFormat, sizeof(AudioStreamBasicDescription));
m_outputFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
m_outputFormat.mSampleRate = m_inputFormat.mSampleRate;
m_outputFormat.mFormatID = kAudioFormatLinearPCM;
m_outputFormat.mChannelsPerFrame = m_inputFormat.mChannelsPerFrame;
m_outputFormat.mBytesPerFrame = sizeof(short) * m_outputFormat.mChannelsPerFrame;
m_outputFormat.mBitsPerChannel = sizeof(short) * 8;
m_outputFormat.mFramesPerPacket = 1;
m_outputFormat.mBytesPerPacket = m_outputFormat.mBytesPerFrame * m_outputFormat.mFramesPerPacket;
ExtAudioFileSetProperty(m_audioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(m_outputFormat), &m_outputFormat)
short* transformData = new short[sampleCount];
AudioBufferList fillBufList;
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels = channels;
fillBufList.mBuffers[0].mDataByteSize = m_sampleCount * sizeof(short);
fillBufList.mBuffers[0].mData = (void*)(&transformData[0]);
ExtAudioFileRead(m_audioFile, &m_frameCount, &fillBufList);
I am interested in how can I specify the audio track I want to decode (suppose that media file contains more than one)?
One method is to decode all tracks and then extract (copy) the desired track data (every other sample for interleaved stereo, etc.) into another buffer, array, or file. Compared to the decode time, the extra copy time is insignificant.

xmlReadMemory - unknown 'url' parameter

I have my xml as char buffer (that's fetched from server, I don't want to save it -> takes extra time and is completely obsolete):
char myword[] = "...xml..."
xmlSchemaParserCtxtPtr ctxt = xmlSchemaNewParserCtxt(xsdFilePath);
xmlDocPtr doc = ?;
Now I need to get doc. I'm trying to use following function:
doc = xmlReadMemory(myword, sizeof(myword), ?URL?, NULL, 0)
But the problem is with URL, what should I put in there..? Am I using this function right? Maybe there is another way to get xmlDocPtr?
BTW: I need xmlDocPtr to perform:
ret = xmlSchemaValidateDoc(ctxt, doc);
Simply pass a NULL pointer:
doc = xmlReadMemory(myword, sizeof(myword), NULL, NULL, 0);

Using RegQueryValueEx and HKEY_PERFORMANCE_COUNTER to Get "Disk Bytes/sec%

I've looked for examples and documentation, but I still can't figure this out...
How do you use RegQueryValueEx (not the PdhXxx functions) to query for something like Disk Bytes/sec?
I've tried the following:
DWORD type;
static union { TCHAR Data[32 * 1024]; PERF_DATA_BLOCK Perf; } perf;//Stack buffer
DWORD cbData = sizeof(perf);
LSTATUS s = RegQueryValueEx(HKEY_PERFORMANCE_DATA,
_T("PhysicalDisk"), NULL, &type, (LPBYTE)&perf, &cbData);
PPERF_OBJECT_TYPE pObjType =
(PPERF_OBJECT_TYPE)((BYTE*)&perf + perf.Perf.HeaderLength);
but it just returns a header with no data. :(
You can't query for the data by name like that. Instead, you need to query by index. MSDN can help you with some code to find out the appropriate index to query. Unfortunately, you need to make the determination of which index at run-time.
For example, the following SHOULD retrieve the performance data for the processor.
LSTATUS s = RegQueryValueEx(HKEY_PERFORMANCE_DATA, _T("238"), NULL,
&type, (LPBYTE)&perf, &cbData);