Jump to content

ATI AC 97 Sounds (SB400) effort


Andras Kenez
 Share

696 posts in this topic

Recommended Posts

Hey, I fixed the DMA hardware pointer not advancing!!! I actually heard a sound produced from my speakers!!!! :D :D Attached is my code; if you want to change your code to fit rather than trying to read and comprehend mine :), look in the activateAudioConfiguration() function, in the for loop where the DMA ring buffer is initialized. The change is that the BDVector's next pointers must be written as PHYSICAL addresses, rather than the VIRTUAL addresses that we were using. There are still some bugs to fix, but I have seen the hardware pointer increment, so let's get hunting!

AppleAC97AudioATIIXP.cpp.txt

AppleAC97AudioATIIXP.h.txt

Link to comment
Share on other sites

Exciting news!! I have no coding ability at all but I've been following this thread (another stuck with SB400) as much as possible and just wanted to say thanks to Dopefish, Edflyer, Scousi and everyone else who has or is helping out. Thanks!!!!

 

Sounds like you guys (horrible pun intended) are making a ton of progress and putting in a ton of work and I know there are a whole bunch of people who really appreciate it. Rock on!

Link to comment
Share on other sites

Great work dopefish, i'll check that spot in my code later today and maybe I'll take a crack at understanding your code. It is funny, but I was talking to someone about how we were passing the address, its great that you found that.

 

You said you had sound, but you said there were still some bugs. Could you elaborate on that?

Link to comment
Share on other sites

I tried that on my laptop and it works almost perfectly for 5-6minutes (exept sound is 1-2 seconds late and only headset is working so built in speakers not working(i have had same problem whit linux)) and then sound starts loopping and then i must boot osx and then it works again ~5minutes..

 

Very good work! almost done!?

Link to comment
Share on other sites

Using my code, I've compiled a version that appears to be minimally functional - "minimally" defined as, it plays something resembling correct sound eventually. I suspect some of the remaining problems are in the getDMAHardwarePointer() function (I don't know what it's actually supposed to return), as well as the DMA engine never stopping. I'm attaching the complete archive in the .zip file; the compiled kext is found in build/Development and is named AppleAC97Audio.kext.

 

Using my code, I've compiled a version that appears to be minimally functional - "minimally" defined as, it plays something resembling correct sound eventually. I suspect some of the remaining problems are in the getDMAHardwarePointer() function (I don't know what it's actually supposed to return), as well as the DMA engine never stopping. I'm attaching the complete archive in the .zip file; the compiled kext is found in build/Development and is named AppleAC97Audio.kext.

ATIAppleAC97Audio.zip

Link to comment
Share on other sites

Mac OS X kernel drivers are unlike any other mainstream OS drivers on the market. As such, it's usually easier for us to start with something we're familiar with. I've been using and hacking Linux for probably ten years now, so I perfer to start with Linux kernel drivers, figure out how they work, and apply that functionality to the Mac OS driver model. Thank you for the information, though. :P

Link to comment
Share on other sites

is it possible that the playing for a while and then looping is caused by the buffer not being flushed so it leaves some data in there and then fills up and then starts looping?

 

sounds like we've got a memory leak or something like that.

-ed

Link to comment
Share on other sites

what's the condition necessary for the stopDMAEngine to be called?

 

It probably has something to do with the getDMAPointer that we are now incrementing, but maybe not incrememting the right way.

 

Yeha, so I'll be home from work in about 2 hours, then I'll be able to really dive into the code 100%

Link to comment
Share on other sites

the DMAPointer is supposed to return an IOByteCount.

 

From the other AC97 codes (intel, via) it seems they return how many bytes are left in the stream. It is entirely possible we are returning the wrong number and that's why it loops out on us.

Link to comment
Share on other sites

total bytes left = total bytes - bytes sent

 

that may be more useful than it would originally seem

 

you access the total length of the stream, see how many we've sent, and then subtract that out to get the bytes left and send that number...

 

 

or i could be entirely wrong. (standard oops i messed up, sorry kthnx disclaimer)

Link to comment
Share on other sites

@dopefish

the reason i thought (past tense) there was a buffering issue was the fact that it'd take a few seconds to load something then it would stutter but that was using your old code before you uploaded your project. now it takes a while to play and like 10 minutes with the Kext loaded it speeds up or atleast thats what i think its doing. also i think it is the way we increment the pointer because i looked at the other code from amd and intel and i noticed that after stopped DMA there was IOSleep() and for me it stopped the looping, but now after awhile the audio gets choppy and the latency is still up there and here is what i wrote

if (!(dma->flags & ATI_ENGINE_RUNNING))
{
	IOLog("%s::%s: Redundant DMA stop\n", getName(), __FUNCTION__);
	return;
}

dma->run_dma(regs, false);
dma->flush_dma(regs);
regs->update(ATI_REG_IER, ATI_REG_IER_SET_BUS_BUSY, 0);
IOSleep(50);
dma->interruptReady = false;
dma->flags &= ~ATI_ENGINE_RUNNING;

Link to comment
Share on other sites

i think i figured out here is the source code peice i changed

IOByteCount CLASS::getDMAEngineHardwarePointer(IOAC97DMAEngineID engine)
{
UInt32 curptr;
UInt32 timeout = 1000;
CHECK_DMA_ENGINE_ID(engine, 0);
ATIIXPDMADesc *dma = dma_channels[engine];
UInt32 tmp;
IOPhysicalAddress buf_addr = dma->sampleMemory->getPhysicalSegment(0, &tmp);
IOByteCount position;
/*while (timeout--)
{
	curptr = regs->read(dma->currentPointerOffset);
	DebugLog("%s::%s: DMA hardware pointer value 0x%lx\n", getName(), __FUNCTION__, curptr);
	if (curptr < buf_addr)
		continue;
	curptr -= buf_addr;
	DebugLog("%s::%s: Hardware pointer > sample buffer addr, offset 0x%lx\n", getName(), __FUNCTION__, curptr);
	if (curptr >= dma->sampleMemory->getCapacity())
	{
		DebugLog("%s::%s: Current buffer size 0x%lx\n", dma->sampleMemory->getCapacity());
		continue;
	}
	DebugLog("%s::%s: Hardware pointer < buffer size, returning to user\n", getName(), __FUNCTION__);
	return (IOByteCount)curptr;
} */
position = regs->read(ATI_REG_SPDF_DMA_DT_SIZE + (engine * 4));
IOLog("%s::%s: Timeout getting DMA hardware pointer\n", getName(), __FUNCTION__);
IOLog("Current codec mask: 0x%x\n", codecsNotReady);
return (position - dma->currentPointerOffset);
}

 

*never mind causes kernel panic :) *

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...