Emulator audio...how?

edited March 2013 in Emulators
Hi all.

I am in the process of writing a Spectrum emulator (c#) for my final year project at university. I've got it all working, apart from sound. It's easy enough to trap the ROM routines when (for instance) a BASIC program uses the BEEP command, but obviously this doesn't work in most games.

So I was wondering if anyone could give me an idea of how to approach this? I'm sure its much easier than it seems to me. My current system involves synchronising every frame, and from the loudspeaker OUT commands over that timeframe, trying to recreate the pitch and duration - I get sound to output, but inaccurately.

Anyway, thanks in advance for any suggestions.

Cheers

James
Post edited by johara on

Comments

  • edited March 2013
    You would want to not only average the sound output for a nicer audio, but also synchronise the frame rate with the audio. Typically, this involves the following:

    1) Take the average of the sound value (the last OUT to BEEP i.e) every 79 tstates (this is for a 44100 Hz audio, which samples 882 sound values over 50 frames. If you are using 22.1 KHz, adjust the value accordingly). Push this sound value to the sound buffer.

    2) Once 882 samples are taken, play the sound buffer. You will need a few sound buffers chained together (circularly) to keep things flowing smoothly.

    The synchronization is achieved by waiting for the current sound buffer to finish playing 882 samples before proceeding with the emulation.

    That's the theory anyway. Hope that makes sense!
  • edited March 2013
    You don't want to be trapping the ROM routines for the sound.

    The sound is produced every time the Spectrum sets bit 4 of 0xFE port. so you need to use that to fill your sound buffer.
    I wanna tell you a story 'bout a woman I know...
  • edited March 2013
    My guess (although I've not tried this yet myself) and leading on from Karingal, is that every time bit 4 changes, (ignore if it is already set to the value being assigned) you note the time (delta) since the last change and fill your buffer accordingly. Every 50th second or so (the length of the your sound buffers) you send off the buffer to the sound device.

    When no sound is playing, you will know that this is the case and so you can send a prefilled buffer of 0's (or 1's). I wouldn't suggest monitoring the state every few t-states as this could be heavy work and may not provide an accurate reproduction.
  • edited March 2013
    Thanks Arjun for your suggestion - this seems to have worked almost perfectly - certainly much better than my previous attempt, and with less code too.

    I'm still getting some clicks in the audio, but I'm hopeful some tweaking of the buffers can fix that.

    Cheers

    James
  • edited March 2013
    Glad to hear you got that sorted. Hope you are also normalising the values in the sound buffer. Floating values will generally be between -1 and 1 and byte values should be between 0 and 255. They may not help with the clicking issue but will at least make the sound less harsher.

    Good luck with your project! Remember to make your emulator available on WoS when you're done! :)
  • edited March 2013
    johara wrote: »
    any suggestions.

    http://www.worldofspectrum.org/forums/showthread.php?t=39647

    http://zxmak2.codeplex.com/


    "...Project written in C#. Currently it works on Windows platform and using Managed DirectX. .."
Sign In or Register to comment.