Cosmo's Cosmic Adventure II: The Humanizer Thread

Anything related to Keen Modding.
Post Reply
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Cosmo's Cosmic Adventure II: The Humanizer Thread

Post by T-Squared »

Hey everyone! :D You probably remember my little topic I made in 2008 that had to do with the sound issues I was encountering while trying to put custom sound into Cosmo's Cosmic Adventure, including making digitized sound through the PC speaker.



After talking with levellass, I found out that the output speed of the sound engine cannot be modified without modifying the clock speed of the entire program. (The original plan was going to be changing the speed of sound output to increase the resolution of the sound that could be output) However, I also found out from levellass that the entire game loop is run through within one clock cycle (sound output, music output, animation, sprite movement), and that the sound loop is only accessed once through that entire loop.

I was thinking that the sound routine could be accessed multiple times within one cycle to increase the resolution of the sound engine and make it less blippy to accomodate properly digitzed sound.

levellass also clued me into changing the length of the tone output (based on one tone) to make it shorter; a different method, but probably accomplishing the same idea.

She also pointed me in the direction of a programmer here on the who can help me with this named Lemm. :D (If you're out there, Lemm, I'd like some help with this!)
lemm
Posts: 554
Joined: Sun Jul 05, 2009 12:32 pm

Post by lemm »

Hi T-squared,

What you want to do can be accomplished to some extent.

A little background:
The game speed can be manipulated without having to alter the system timer. The game logic is not run through within one 8253 system timer chip pulse. The system timer pulse is set to 560Hz, the rating of the IMF file. At each pulse, the interrupt 8 is called, which does the following:

1) It updates some tick counters (variables). I can find two that are important to you (call them ticksA and ticksB).
2) It plays the sound.
3) It plays the AdLib music.

TicksA is incremented during every call to interrupt 8. Then, int 8 checks if TicksA is a multiple of 4. If it is, it calls play_sound(), which increments TicksB.

Elsewhere, there is a timing loop that waits until ticksB is greater than 13. When ticksB >= 13, the loop is broken, ticksB is reset to 0, and then the game logic, drawing, etc begins. After all that is done, the game returns to the timing loop and waits for ticksB to get to 13 again. Remeber that int08 is called regardless of where the program is, so ticksA and B are always updated at a constant rate relative to real world time. Also note that the play_adlib() is called once per int08. (If there is no adlib detected, the clock frequency is set to 140Hz, but that is not a worry in dosbox).

To summarize:
TicksA: updated once every timer pulse
TicksB: updated once every 4th timer pulse.
Game Loop: run through once every (4 * 13) = 52'nd timer pulse.
play_sound(): called once every 4th timer pulse.
play_adlib(): called once every timer pulse.

Now on to patching:
You can alter the frequency at which play_sound() is called, play_adlib() is called, and the timing loop is broken by patching some values. ("Speed" is relative to real time)

Example:
play_sound() at 2x speed
play_adlib() at 1x speed
play game (break timing loop) at 1x speed

To do this, we change the TicksA multiple-of-4 check I mentioned earlier to a multiple-of-2 check. This results in play_sound being called 2x as fast, and TicksB (and therefore the game) being updated 2x as fast. To slow the game down by four times, we scale the <= 13 comparison accordingly, to <=26. As expected, sounds are played in half the time.

Code: Select all

#Use a hex editor. These values are relative to the start of the exe file.  if you have a patcher, i think you subtract $1600 from what I've given.
patch $1158A to $1A  #game loop (ticksB check)
patch $12218 to $01W #play sound (ticksA check)

Other offsets you can patch (defaults shown):

Code: Select all

$12293 $230W #the speed of the clock , default 560Hz
$1254D $05   #this has something to do with drawing to the screen
             #if TicksB > 5 (or whatever value you patch), then TicksB = 0
             #I noticed that when I set the game speed faster, I saw flickering of masked images
             #You might need to change this is you want > 1x game speed

If you need anything else, let me know =).
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

Code: Select all

#Use a hex editor. These values are relative to the start of the exe file.  if you have a patcher, i think you subtract $1600 from what I've given.
patch $1158A to $1A  #game loop (ticksB check)
patch $12218 to $01W #play sound (ticksA check)

Other offsets you can patch (defaults shown):

Code: Select all

$12293 $230W #the speed of the clock , default 560Hz
$1254D $05   #this has something to do with drawing to the screen
             #if TicksB > 5 (or whatever value you patch), then TicksB = 0
             #I noticed that when I set the game speed faster, I saw flickering of masked images
             #You might need to change this is you want > 1x game speed
I really appreciate this, I really do. :D I edited your values a little bit that shouldn't affect gameplay. (only the main menu, sound, and everything having to do with text was affected.)

I divided the TicksA value to $00, and doubled the TicksB value to $34 (hex calc provided by the internet XD), essentially making the sound engine go as fast as the clock, and slowing the game loop down to a normal speed. (relative to real-time) :D
levellass
Posts: 3001
Joined: Wed Oct 11, 2006 12:03 pm
Location: Ngaruawahia New Zealand

Post by levellass »

I am curious, can this be accomplished in Keen? It would make for more detailed sounds I should think.
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

With some help from Lemm, I was able to come up with this: The first one is the original (my voice) It's still muddled, but it's a lot better than it originally was. With any luck, the clarity will be close to this, if not as much: http://upload.wikimedia.org/wikipedia/e ... ron%29.ogg
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

Can the play_sound routine be called twice in the same loop? I'm still getting muddled digitized audio. (it's very close, but still can't be understandable by my method.)
lemm
Posts: 554
Joined: Sun Jul 05, 2009 12:32 pm

Post by lemm »

It could be, although I don't think that would have the effect you want. I'm pretty sure what would happen is that the sound data sent in the first call would get immediately over written by the second call, so you would just be hearing every second "chunk" of sound data.

To get an even space between the each call, I think you will have to change the timer frequency by patching at $12293 and call play_sound once during every interrupt 8. For now, keep $12218 patched to $0 as you have done, turn the music off and ignore the game speed, and just keep multiplying the timer frequency by two (560Hz, 1120Hz, 2240Hz, etc) until the sound is to your liking. I'll make a patch so that play_adlib is called 1/2, or 1/4 as much depending on what you have chosen.

By the way, do you have a patcher program for Cosmo that I can use?

levellass: Yes that could be done.
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

lemm wrote: For now, keep $12218 patched to $0 as you have done, turn the music off and ignore the game speed, and just keep multiplying the timer frequency by two (560Hz, 1120Hz, 2240Hz, etc) until the sound is to your liking. I'll make a patch so that play_adlib is called 1/2, or 1/4 as much depending on what you have chosen.
Oooh, I never thought about patching the timer frequency! :D (I don't mess with certain things in the program unless I know it won't adversely affect it.)
lemm wrote: By the way, do you have a patcher program for Cosmo that I can use?
No, sorry. I'm not a big programmer (I've only been able to partially create a basic ping-pong game in Applesoft BASIC on my Apple IIe, and even then, it's not completely finished. XD) CCA just isn't one of those programs that's popular enough to have a patcher...

I understand the logic of commands in the program when they're put into plain English, but making something from scratch is not my forte.

I'm most likely going to need your help correctly patching the story pages for the game as well. (After I write all of it out and condense my story parts down to a format that fits into the pages.)
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

Hey everybody, I'm still working on the digitized sound problem. I think I may have found the answer by mixing all the methods that I've been using up to this point together.

My first method was a doozy because I was doing a rather poor job of manually translating a single pulse of a 1-bit sound by ear into an SND file.

The second method [straight translation of 1-bit wav sound into SND data using KEENWAVE] didn't work (which also would have affected the first method) because the rate at which the sound is output is far too slow for any words let alone digitized sound to be heard coherently, all that's created is a series of blips that server no purpose.

The third method I tried didn't work either and had the same effect as before. (I used a sound "table" to match the pulses in the sound and input the data in KEENWAVE's sound bitmap by hand.)

I almost gave up until I realized that the timing of the blips could be sped up and could merge together to form a digital voice. (The same way the speaker sounds work on the Apple II.)

The fourth method was the same as the second [1-bit translation straight to SND]. It didn't work, but I realized that the sounds needed to be stretched out in order for Keenwave to read the samples correctly, then the sped-up game engine could shrink them back down to their original length. So I first took the sound and literally slowed it down; didn't work. But then I manually went to each pulse of the sound and had the computer repeat it several times. (took a long time to repeat each pulse, even though it's technically a small snippet of sound.)

It became a lot clearer than before, but still muddled. Fortunately, now I've realized that I could probably measure each repeated pulse by ear using the sound "table", and then input the data into the bitmap manually, thus clearing up any muddiness and incongruities in the sound.

(I'd have to draw a picture to show what I'm trying to do here. XD)

Anyways, I'll post an example of my discovery if it works.
Last edited by T-Squared on Sun Jul 11, 2010 5:05 pm, edited 1 time in total.
levellass
Posts: 3001
Joined: Wed Oct 11, 2006 12:03 pm
Location: Ngaruawahia New Zealand

Post by levellass »

I've got a new Keenwave in the works, it can use pitch, frequency or both to translate wave files into sound; I'm also hoping to make it so that you can stretch or squeeze a sound in Keenwave and listen to it before saving it as a format. (You can already alter the pitch up and down.) What I'm hoping for is far better wav->snd conversion. I will be interested in your method, it may be possible to automate it. (I'd appreciate any speech waves you have too, so I can test on things other than PC wavs.)
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

levellass wrote:(I'd appreciate any speech waves you have too, so I can test on things other than PC wavs.)
You need 1-bit speech recordings? Cause I think you can make your own 1-bit recording using a program by Ken Silverman (yes, THAT Ken Silverman) in DOSBox.

http://www.advsys.net/ken/utils.htm

You can find the program under the name "MP3PC" at the address above.

All you have to do is convert your sound file into an MP3, then record the program's playback of the sound file in DOSBox using the "Stereo Mix" feature on your sound card.

For right now take this advice with a grain of salt, cause I myself haven't tested it yet.

I use my Apple II cause it's got the most basic Digital to Analog Converter on it.

But if you want 1-bit recordings that I've made, I'll gladly send them to you.
User avatar
Malvineous
Posts: 113
Joined: Sat Mar 13, 2004 12:54 am
Location: Brisbane, Australia
Contact:

Post by Malvineous »

Ken Silverman's program worked very well when I tried it years ago, but IIRC it toggles the PC speaker very, very quickly.

Is there some reason why you really need to play digitised audio out of the PC speaker? Since Lemm has recently written a TSR to play music in Keen 1-3, it should be relatively simple to use the same principle to make the game call your own code when it wants to play a sound. You could then either play it out the PC speaker yourself, or use the sound card. Either way you'd get far better results!
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

Malvineous wrote: Since Lemm has recently written a TSR to play music in Keen 1-3, it should be relatively simple to use the same principle to make the game call your own code when it wants to play a sound.
*JAWDROP*

WOW! 8D Is there anything this Lemm guy can't do? XD

I had that idea when I started this project in 2007 also. But my idea was going to be in essence "hanging a speaker outside the DOS Box" I wanted the user to be able to run the program in both DOSBox and pure DOS (if they have it) without losing the ability to create digitized sound. In my idea, A program in Windows was going to detect certain speaker sounds being played in DOSBox, and then play its own corresponding sound effect. Like I said before, the digitized sound would only be able to play in Windows. But now I see that I can keep everything neat and tidy and "Keep the speaker inside the DOS Box" by using that TSR.

What language is the TSR programmed in? I'd really like to see this TSR to try it out on Keen and Cosmo!
User avatar
Malvineous
Posts: 113
Joined: Sat Mar 13, 2004 12:54 am
Location: Brisbane, Australia
Contact:

Post by Malvineous »

As far as I'm aware the TSR hasn't yet been released, it's part of an upcoming mod. I'm not sure how it works, but as I had often wondered about doing the same thing myself I would've implemented it by hooking an interrupt, then patching the sound playing code to call my interrupt when a sound should play. That would allow as much code as I liked to run (since only the one or two byte interrupt call needs to be patched into the game code) so the rest of the code could be written in a nice language like C (as opposed to assembly.)

Using a method like this you could just as easily play sound out of a SoundBlaster card, which would give you true digitised sound effects in both DOSBox and native DOS. (Well I say "just as easily", in fact writing code to play digitised sound out of a SoundBlaster card can be horribly complex, but again as you don't have to patch in any of this code you're free to use a sound library where somebody else has done all the hard work for you!)
User avatar
T-Squared
Posts: 143
Joined: Mon Dec 01, 2008 6:11 pm
Location: San Antonio, Texas
Contact:

Post by T-Squared »

I just had an idea for when the TSR is edited into an SB Voice/Sound player. In Cosmo, the text for the hint globes(/kiosks in my Mod) could be read out by a recorded voice. How could this be done? Well, each chunk of hint text is written at a certain hex address, right? In the TSR, the program could have a special subroutine set to play a certain voice accompaniment when the starting hex address of a certain message chunk is read.

It's the same principle as how I want to give Cosmo his voice, but this subroutine reads from the executable instead of looking in the STN and VOL data files.
Post Reply