Do have some code from classic Amiga times which, while written in C, do use "audio.device". I do not know much about it, but as far as I remember, there were users saying that anything which use audio.device don't work for them (maybe it platform dependent?)
Also, those who use it on os4, do you have any issues with, like, crashes on exit when you're about to close device, etc. ?
And as last question, is there some easy way to rewrite usage of audio.device to something which will works fine everywhere, but without total rewrite to AHI or so: the code ? Or maybe there are already some "modern" audio.device which is not part of the OS ?
Or, if taken into account that it all was system friendly enough just replaced the audio.device on ahi.device in hope not many changes need it?
Sadly, 68K software is often avoiding api’s even when the software should be system friendly.
I expect, properly nothing wrong with audio.device, but instead code using DFF006 or CIAA/CIAB for timing, you can try running NallePuh or Ciaagent, to see if helps.
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
It still didn't crash and works. But this line is set only one time in the code, in all other places this “custom” didn't used, and everywhere is usual:
Etc. So i think that maybe pure replacing audio.device on ahi.device and their MP and IO may make it works without changes (or with very little ones).
Interesting, when we run code over audio.device, this "INTF_AUD0" probably just skipped ?
EDIT: seems not that easy: audio.device is operated with BeginIO() while ahi.device is with SendIO()/DoIO(). But that alone not the problem, problem is the difference in the request, for example how to replace those:
It depends on the use of the audio.device. Most programs, especially module players and games, simply open audio.device to allocate the audio in a friendly manner but then bang the hardware. This was common practise.
This also caused confusion when an OS4 audio.device appeared in the early days. People used audio.device apps but didn't hear a sound. This is because the OS4 audio.device provided the API but didn't emulate Paula. People assumed the existence of the audio.device meant audio software would work. No, the audio.device and Amiga audio are two different things.
There are two variants of audio.device. The Classic version and the AmigaOne version. The Classic version be a straight up OS4 port of the original. The AmigaOne version is a shim that is a wrapper for ahi.device. It works fine for playing audio since it just redirects CMD_WRITE calls to AHI. So can't be fixed in that regard, since it already works, as it's the programs that aren't using it to play audio.
The AmigaOne version also has a bug I found out this year. The ADCMD_LOCK is faulty. It just replies back straight away. This could affect software as it is a bug that violates known API. Though it shouldn't affect playback. Given they ported audio.device to AHI I don't understand how they messed this up. The code was right there, what did they do with it?
So, aside from the hard patching method you employed in the past, the only way at present for this to work is to use NallePUH.
@Hypex In my case, audio.device used properly with CMD_WRITE, and while I do hear all the sounds, it crashes for me on exit. So i just tried to understand why so..
Have a clue how to rewrite this code from audios.device to ahi.device usage ?
In my case, audio.device used properly with CMD_WRITE, and while I do hear all the sounds, it crashes for me on exit. So i just tried to understand why so..
I wonder if it's because of ADCMD_LOCK? Maybe not. Do you have any equivalent C code that can replicate the crash?
Quote:
Have a clue how to rewrite this code from audios.device to ahi.device usage ?
Sure. It's similar in a way as it uses a duplicated IORequest for each channel but can use Unit to specify channel. So unit 2 would map to channel 1 which should be right. Unless you had an Amiga which was opposite to the other side of the world.
To do it for channels an IORequest needs duplicating for each extra channel after opening AHI. Then the period needs converting to frequency. After that it's setting volume and matching pan.
Set the clock:
if (GfxBase->DisplayFlags & PAL) clock=3546895L; /* PAL clock */
else clock=3579545L; /* NTSC clock */
Just do not want to rewrite everything in this… Especially i have hard times to rewrite this part of code to AHI:
It maps unit to channel. Except for when mapping all channels that I don't get. Seems total channels, such as 4, is code for playing on all channels.
Wiki has more info. Except doesn't say how to play a sound. Only has a CMD_READ recording example. Doesn't fully explain how to play sound. Leaves it to example to fill in gaps. Also the closing code is strange. It uses AbortIO() without checking then does a WaitPort() and GetMsg(). Looks kludgy. Then example code uses normal WaitIO().
I have no practical experience with audio.device, but based on reading the documentation I can see that ioa_Length takes a value in WORDS, while ahir_Std.io_Length takes a value in BYTES. So when transferring the code to AHI, you need to multiply the original code's ioa_Length by 2 to get the length for ahir_Std.io_Length.
Set the clock: if (GfxBase->DisplayFlags & PAL) clock=3546895L; /* PAL clock */ else clock=3579545L; /* NTSC clock */
Wait, we about amigaos4, right ? I mean, WTF PAL/NTSC ?:) We can just write 44100, or any other. Or you mean to just reproduce exactly freq as it was on audio.device's code ? But anyway, PAL or NTSC giving the same 44100, so probably no needs for this code.
Yes I had forgot about that. As well as period and volume it's the same as the direct hardware. I always thought it was too close and should have used sample length and frequency in the API.
@kas1e
Quote:
Wait, we about amigaos4, right ? I mean, WTF PAL/NTSC ?:) We can just write 44100, or any other. Or you mean to just reproduce exactly freq as it was on audio.device's code ? But anyway, PAL or NTSC giving the same 44100, so probably no needs for this code.
Yes, that should still work, it should be set in OS. It's needed for period conversion if you have a Paula period. But for direct frequency you don't need to convert it.
@All So rewrote from the audio.device to ahi.device, and while sound works, i do crash always on exit when call first time WaitIO call after AbortIO. The same as it was with the original code.
Now, what is interesting : if i replace in the code CreateMsgPort() on AllocSysObject() and CreateIORequest() on AllocSysObjectTags() i have no more crashes!
Is it pointing us to something ? Like forgotten wait() for something with original CreateIORequest() and CreateMsgPort() or forgotten signal send maybe ? IT surely shouldn't crash even with original-deprecated functions, and replacing them on allocsysobject() ones somehow auto-fix something..
It just looks like the original os3 code has some bug there which were just forgiving on OS3, but on OS4 not, and when i replace functions it just “auto fixes” buggy code.
That's why I thought it was kludgy. It doesn't fully use device functions which is only the case for special cases like some audio.device functions and timer.device interrupts.
The proper way is to check and then wait on the IO. Of course IO has to be sent. If an IORequest was opened on a device and then never used then an IO check can hang.
@hypex Wait, you quote ahi.device variant (my one), but i ask about why their audio.device variant crashes : they don't have waitio, but instead waitport() ÷ getmsg() and was ok for os3. Yeah, os3 was forgiving for bugs, but which one ? I mean checkio can be added before abortio in their audio.device way, but is waitport and getmsg can be used after ?
if (c->sound_in_progress) {
AbortIO ((struct IORequest *)c->audio_io);
}
BeginIO ((struct IORequest *)c->audio_io);
c->sound_in_progress = TRUE;
}
StopSound (added checkio() as well, didn't help):
void StopSND( int handle )
{
if (!audio_is_open) {
return;
}
if (channel_info[handle].sound_in_progress) {
if (!CheckIO((struct IORequest *)channel_info[handle].audio_io)) AbortIO((struct IORequest *)channel_info[handle].audio_io);
WaitPort (channel_info[handle].audio_mp);
GetMsg (channel_info[handle].audio_mp);
channel_info[handle].sound_in_progress = FALSE;
}
}
So it crashes on WaitPort as far as i can tell.
I of course can replace it all on ahi.device already, but i just need to know what wrong with this code that it was ok for os3, but didn't for os4 ?
Edited by kas1e on 2022/12/16 16:31:38 Edited by kas1e on 2022/12/16 16:32:04 Edited by kas1e on 2022/12/16 16:32:48 Edited by kas1e on 2022/12/16 17:05:23
Wait, you quote ahi.device variant (my one), but i ask about why their audio.device variant crashes : they don't have waitio, but instead waitport() ÷ getmsg() and was ok for os3.
Oh, I thought that was your audio.device code that matches your last code, in my last post about Abort()()?
Quote:
Yeah, os3 was forgiving for bugs, but which one ? I mean checkio can be added before abortio in their audio.device way, but is waitport and getmsg can be used after ?
It maybe because of the audio.device design using WaitPort and GetMsg and might need to be done in the unconventional way.
Quote:
There is original code:
Init:
That code is old, it looks original. It predates OS2.
It aborts but doesn't clear the request. So if sound is playing it aborts but doesn't pull the old request then adds another request. Looks like it's asking for trouble.