Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Karlos on January 17, 2003, 04:51:16 PM
-
Hi all!
I wonder if someone can help me out here. I'm rewriting the SoundDevice class of my system toolkit to use AHI.
The basic idea is that I open the AHI device level interface based on the user's prefered unit. This is to allow my code to coexist with other AHI device users that may be running concurrently. I then mix the sound with my own code into the buffers and submit the mixed data to unit. I use the double buffering as described in the AHI docs.
It's working fine except for an annoying click each time the the secondary buffer switches back to the primary (but oddly not the other way around).
I've checked all the obvious potential glitches in the mixing routine and even used a pure sinewave that exactly fills the buffer. The click is still there.
Note the code below is a C++ method, so forgive any unfamiliar syntax. Also please excuse the indentation - it seems that tabs or spaces just vanish when I preview, so I put blank lines to help a little
sint32 SoundDevice::run() // overriden from Thread class
{
  if (!openHardware())
  {
   return -1;
  }
  sint32 packetsMixed=0;
  while (!shutDown())
  {
    // This loop will end when someone calls the Thread inherited stop() method
    // soundIO is a union of the io pointer types used
    // to avoid excessive casting
    // set up a cross linked double buffer
    soundIO[0].std->io_Command = CMD_WRITE;
    soundIO[0].std->io_Message.mn_Node.ln_Pr= 0;
    soundIO[0].std->io_Length = bufferSize*sizeof(sint16);
    soundIO[0].std->io_Data = out;
    soundIO[0].ahi->ahir_Type = AHIST_S16S;
    soundIO[0].ahi->ahir_Frequency = freq;
    soundIO[0].ahi->ahir_Link = soundIO[1].ahi;
    soundIO[0].ahi->ahir_Volume = masterVol;
    soundIO[0].ahi->ahir_Position = masterPan;
    soundIO[1].std->io_Command = CMD_WRITE;
    soundIO[1].std->io_Message.mn_Node.ln_Pr= 0;
    soundIO[1].std->io_Length = bufferSize*sizeof(sint16);
    soundIO[1].std->io_Data = out + bufferSize;
    soundIO[1].ahi->ahir_Type = AHIST_S16S;
    soundIO[1].ahi->ahir_Frequency = freq;
    soundIO[1].ahi->ahir_Link = soundIO[0].ahi;
    soundIO[1].ahi->ahir_Volume = masterVol;
    soundIO[1].ahi->ahir_Position = masterPan;
    // kick off the primary play buffer & mix secondary
    ::SendIO(soundIO[0].io);
    mixSecondary();
    ++packetsMixed;
    // submit secondary request
    ::SendIO(soundIO[1].io);
    // wait for primary to complete
    ::WaitIO(soundIO[0].io);
    // kick off secondary play buffer & mix primary
    mixPrimary();
    ++packetsMixed;
    // wait for secondary to complete
    ::WaitIO(soundIO[1].io);
  }
  closeHardware();
  return packetsMixed;
}
Well, it's got me foxed and I bet it's something simple too.
-
*bump*
Well, it worked for another thread... ;-)
-
Here is an odd suggestion.
What if you make 3 buffers.
If only the click comes when you switch form 2 to 1, then, do this while playing buffer 3.
But then again, maybe the click will just come when buffer 3 changes..
-
to post code with indentation, convert all the indentations to . I keep a copy in a text editor so that if i notice a mistake, i can change it and paste it back in (clicking edit turns all the 's back to spaces).
-
I recently port (http://www.iki.fi/sintonen/uade/)ed uade (http://ee.tut.fi/~heikki/uade.html) for MorphOS.
I use AHI for audio output there, with double buffering.
Download uade-0.80-pre3-antiwar.tar.bz2 (http://ee.tut.fi/~heikki/uade/pre/uade-0.80-pre3-antiwar.tar.bz2), unarchive it and take a look at src/sd-sound-ahi.c and src/sd-sound-ahi.h.
Maybe this will help.
-
@Tickly,
Cheers :-) That fragment looks a lot better now!
-
@Piru,
Thanks, will do...
-
yssing wrote:
Here is an odd suggestion.
What if you make 3 buffers.
If only the click comes when you switch form 2 to 1, then, do this while playing buffer 3.
But then again, maybe the click will just come when buffer 3 changes..
Hi,
I did actually try this, and using a single, looping buffer too. Basically it gives the click when it gets back to the first one. I even inspected the buffer contents afterwards and could't find a rouge value causing a click. Interestingly, it doesn't happen when the buffer contents are silent, so I assume a zero word is being pumped out somewhere when it gets back to the first buffer. Strange...