Plugin Progress
So just a little update and there is good news and bad news.
The
good news is that I asked the libsidplayfp guys the question and while I didn't get the answer I was after they gave me a soultion nonetheless, so I am using MingW (via NetBeans) instead which appears to work just fine so far.
With that worked out after a week+ of solidly smacking my face against the wall, I knocked some bricks loose and have an
almost functional new plugin with all the tag loading, sub song handling, some basic settings and so forth.
The
bad news is the only thing left is, of course, the most important bit, actually getting the beeps and boops to XMPlay. Math is not my strong point, nor is audio or conversion thereof which at least to my brain makes this bit of a problem. I understand the concept I think but the execution is another story.
Current Problem
So! With all that in mind I'll slap the details of the problem here and maybe one of you clever chaps can tell me "Why Keltic you silly sausage, you just divide by the square root of pie!" and we can try this puppy out.
This is the XMPlay Process function that is used to get the audio samples from the plug in as follows.
// get some sample data, always floating-point
// count=number of floats to write (not bytes or samples)
// return number of floats written. if it's less than requested, playback is ended...
// so wait for more if there is more to come (use CheckCancel function to check if user wants to cancel)
DWORD WINAPI SIDex_Process(float *buffer, DWORD count) {}
To get the goods we need to use the following function from libsidplayfp.
// Run the emulation and produce samples to play if a buffer is given.
// Parameter: buffer pointer to the buffer to fill with samples.
// Parameter: count the size of the buffer measured in 16 bit samples or 0 if no output is needed (e.g. Hardsid)
// Returns: the number of produced samples. If less than requested and #isPlaying() is true an error occurred, use #error() to get a detailed message.
uint_least32_t Player::play(short *buffer, uint_least32_t count) {}
Thoughts So Far
So from start to finish with this whole thing I've had a very poor track record of thinking something is 10,000 more complicated than it actually is, or just plain over complicating things when I don't need to.
*cough*Sorry for the silly emails Ian *cough*Despite that I was thinking it would work something like the following.
DWORD WINAPI SIDex_Process(float *buffer, DWORD count){
// I figure count can just be used in the play command since it is the same thing right?
// I'll pop the result into a temporary buffer since XMPlay wants floats
// sidDone is just to pass back how many we actually got
short * sidBuffer;
int sidDone=0;
// Then we'll do the command to get some samples
sidDone = sidEngine.m_engine->play(sidBuffer, count);
// Next we'll do some fancy conversion of the sidBuffer from short to float and populate the buffer provided by XMPlay
// I either have no idea how to do this, or my conversion was fine and the above is not actually correct.
// I tested with memcpy(&buffer,&sidBuffer,std::min(sizeof(buffer),sizeof(sidBuffer))); just to get something through and it plays nonsense
// Despite playing nonsense it does play which suggests the sidDone number is correct and it returned the count as requested
// So my theory is if I can convert he short properly it will presumably work?
// Let XMPlay know how many we got if it needs to stop
return sidDone;
}
For reference though I have tried to figure it out by looking at foobars foo_sid, winamps in_sidplay2, hippoplayer sid plugin, the sid support in another xmplay plugin (zxtune) and the sidplayfp app. Over the development I have also looked at probably every single plug in for XMPlay that has source available, so quite the adventure. All of which has been very useful in the general building of the plug in but not for this bit in particularly.
Any thoughts are welcome.