(sorry for the double, devin. forgot to send to the mailer).

hi,

i know you’re helping, so i apologise for correcting you, but this *is* a 
mailing list, and, just as i found it through google, some noob may want to 
leave the cave.

as such, i believe you’re suggesting^{1} i create a separate engine for each 
stream that’s clocked separately, not device, right?
        -i can’t make more than one device since it’s an IOPCIDevice.

before discussing why i don’t want to do this (not saying i refuse, just don’t 
want to at this point), i wanted to ask you something if all streams were on 
the same clock:
        -how could returning this single UInt32 value suffice for all of the 
streams? this is what i kind of struggle to wrap my head around. 
                -i get what you’re saying that, if all streams have the same 
clock, then their positions should be the same. 
                        - but in terms of code, how does the driver use a 
single value and spread it across all of those respective streams?
                                - is that what it does by default?


^{1} again, i’m sorry about this. i don’t _want_ to it, especially when i’m 
asking for help!

---
re: splitting the driver into more engines

in theory this sounds very nice but it would result in a lot of problems with 
code overlap and also i disagree that others should consider this as a remedy.

i’m not saying your suggestion wouldn’t work, but off the top-of-my-head i 
would have to create redundant Engine objects just to hold a single 
input/output stream.
        -remember, each engine needs to have an interrupthandler/ioworkloop. 
                -even if i create a pseudo-engine for SPDIF for its own clock, 
i think i may have problems since all of the IOWorkLoop stuff has to go through 
the “main object” that handles interrupts from all sources.

if you’re ever curious you can take a look at what i’m saying here: 
https://github.com/i3roly/CMI8788/blob/master/CMI8788/XonarAudioEngine.cpp#L2453
 
<https://github.com/i3roly/CMI8788/blob/master/CMI8788/XonarAudioEngine.cpp#L2453>
        -i believe you’d concur that any properly-designed audio driver must 
handle all of the interrupts in a single place—i.e. the interrupt handler.
                -since you’re likely (far) more experienced than i, it’s 
possible having a second ioworkloop/interruptfilter for the same device may not 
be as problematic as i’m thinking.
                
-why didn’t APPUL foresee this possibility? to me it seems impossible they did 
not. ALSA did. yeesh.

i don’t even think the new “AudioServer”/DEXT crap has added any true 
functionality to deal with this potential (massive) pitfall.
        - feel free to chime in matt (mora) and correct me

Thanks,
Gagan


>> On Dec 21, 2022, at 7:15 PM, Devin Roth <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> I would create a device for each stream that is clocked separately. 
>> On Dec 21, 2022, 5:03 PM -0800, Gagan Sidhu via Coreaudio-api 
>> <[email protected] <mailto:[email protected]>>, 
>> wrote:
>>> hi,
>>> 
>>> thank you for your quick and insightful response. this is the most 
>>> sophisticated question i’ve been asked in terms of interfacing code with 
>>> hardware (it’s “my first driver’).
>>> 
>>> i am not certain this sound card (Xonar HDAV1.3 Deluxe) has a single clock 
>>> because it has multiple DMA engines.
>>> 
>>> from what i can gather, it may be a single clock for a few of the engines 
>>> (an SPI clock) but each engine may be (is) using different periods.
>>> 
>>> but for sure there is a separate “sampling clock" for the SPDIF.
>>> 
>>> can we attach images on a mailing list? probably not, right?
>>> 
>>> at the end of this message, i’ve included relevant portions from the 
>>> specification.
>>>     - i believe the term ‘codec’ is equivalent to streams. i have a maximum 
>>> of 6 IOAudioStream objects, which corresponds to the codecs 0-5. 
>>>             -not all cards have six engines. it’s a family of cards that 
>>> use a different combination of these six.
>>> 
>>> man there has to be a way to do this. 
>>> 
>>> SPI (Serial Port Interface) Bus Control Registers
>>> 
>>> PCI 98: SPI Control Register Address Offset: 98h
>>> Default Value: 00h
>>> 
>>> Bit
>>> 
>>> Attribute
>>> 
>>> Description
>>> 
>>> 7
>>> 
>>> R/W
>>> 
>>> SPI CEN control
>>> 0: codec latch control data at SPI clock low (default) 1: codec latch 
>>> control data at SPI clock high
>>> 
>>> 6:4
>>> 
>>> R/W
>>> 
>>> Codec select
>>> 000: codec 0 (XSPI_CEN0) 001: codec 1 (XSPI_CEN1) 010: codec 2 (XSPI_CEN2) 
>>> 011: codec 3 (XSPI_CEN3)
>>> 
>>> 100: codec 4 (XSPI_CEN4) 101: codec 5 (XSPI_CEN5) others: no use
>>> 
>>> 3:2
>>> 
>>> R/W
>>> 
>>> SPI clock period 00: 160 ns 01: 320 ns 10: 640 ns
>>> 
>>> 11: 1280 ns (1.28 micro-second)
>>> 
>>> 1
>>> 
>>> R/W
>>> 
>>> The data length of read/write, 0: 2 bytes (D6-D7), 1: 3 bytes (D6-D8)
>>> 
>>> 0
>>> 
>>> R/W
>>> 
>>> Write 1 to trigger read/write operation, After read/write operation 
>>> completes, the bit will be cleared to 0 automatically.
>>> 
>>> 
>>> and
>>> 
>>> PCI 70: SPDIF Function Control Register Address Offset: 70-73h
>>> Default Value: 02000000h
>>> 
>>> High Performance PCI Audio Controller CMI8788/CMI8787 Register 
>>> Specification V.0.1
>>> 
>>> Bit
>>> 
>>> Attribute
>>> 
>>> Description
>>> 
>>> 31:27
>>> 
>>> Reserved.
>>> 
>>> 26:24
>>> 
>>> R/W
>>> 
>>> SPDIF/OUT Sampling Rate (all support)
>>> 
>>> SPDOSR[2:0]
>>> 
>>> 000 : 001 : 010 : 011 : 100 : 101 : 110 : 111 :
>>> 
>>> 32 Khz 44.1 Khz 48 Khz 64 Khz 88.2 Khz 96 Khz 176.4 Khz 192 Khz
>>> 
>>> 23:17
>>> 
>>> Reserved.
>>> 
>>> 16
>>> 
>>> R/W
>>> 
>>> SPDIF/IN Sampling clock
>>> 
>>> 1: >96khz 0: <=96khz
>>> 
>>> 15
>>> 
>>> R/W/C
>>> 
>>> RATE_INT, SPDIN smp rate change interrupt. Write 1 to clear
>>> 
>>> 14
>>> 
>>> R/W/C
>>> 
>>> LOCK_INT, Interrupt of SPDIN data is locked or not. Write 1 to clear
>>> 
>>> 13
>>> 
>>> R/W/C
>>> 
>>> SENSE_INT, Interrupt of SPDIN data is sensed or not. Write 1 to clear.
>>> 
>>> 12
>>> 
>>> Read only
>>> 
>>> LOCK_STUS, indicate SPDIN data is locked or not
>>> 
>>> 11
>>> 
>>> Read only
>>> 
>>> SENSE_STUS, indicate there is transition in SPDIN
>>> 
>>> 10
>>> 
>>> R/W
>>> 
>>> LOCK_PAR, LOCK_INTR trigger level 0: low to high, 1: high to low
>>> 
>>> 9
>>> 
>>> R/W
>>> 
>>> SENSE_PAR, SENSE_INTR trigger level 0: low to high; 1: high to low
>>> 
>>> 7-8
>>> 
>>> Reserved
>>> 
>>> 6
>>> 
>>> R/W
>>> 
>>> SPDVALID, SPDIF/IN valid bit detect enabled.
>>> 
>>> 5
>>> 
>>> R/W
>>> 
>>> RATE_MASK, 1: RATE_INT is un-masked
>>> 
>>> 4
>>> 
>>> R/W
>>> 
>>> LOCK_MASK, 1: LOCK_INT is un-masked
>>> 
>>> 3
>>> 
>>> R/W
>>> 
>>> SENSE_MASK, 1: SENSE_INT is un-masked
>>> 
>>> 2
>>> 
>>> R/W
>>> 
>>> SPDFLOOPI, internal SPDIF/IN loopback to SPDIF/OUT
>>> 
>>> 1
>>> 
>>> R/W
>>> 
>>> ENSPDOUT, enable SPDIF/OUT to I/O Interface
>>> 
>>> 0
>>> 
>>> -
>>> 
>>> <page23image4076672.png>
>>> Reserved
>>> 
>>> 
>>> btw i do think the panic was caused by having an empty 
>>> getCurrentSampleFrame since, 0x08 is the address (on the device) where the 
>>> driver writes the IOBufferMemoryDescriptor’s physical address:
>>>> 
>>>> Anonymous UUID:       9DD1C300-68BB-0152-2C74-E8415A6CC86C
>>>> 
>>>> Wed Dec 21 16:06:45 2022
>>>> 
>>>> *** Panic Report ***
>>>> panic(cpu 0 caller 0xffffff801bcdab9d): Kernel trap at 0xffffff801c2200c5, 
>>>> type 14=page fault, registers:
>>>> CR0: 0x000000008001003b, CR2: 0x0000000000000008, CR3: 0x000000002253f000, 
>>>> CR4: 0x00000000000226e0
>>>> RAX: 0x0000000000000000, RBX: 0xffffff818d9b22e0, RCX: 0x0000000024000000, 
>>>> RDX: 0xffffff8110f18900
>>>> RSP: 0xffffff8e20a1bce0, RBP: 0xffffff8e20a1bd30, RSI: 0xffffff818d9b22e0, 
>>>> RDI: 0x0000000000000000
>>>> R8:  0xffffff81927a10c0, R9:  0x0000000000000000, R10: 0x0000000000000002, 
>>>> R11: 0x0000000000000000
>>>> R12: 0xffffff81c8245140, R13: 0xffffff81c8245140, R14: 0x0000000000000001, 
>>>> R15: 0xffffff8110f18900
>>>> RFL: 0x0000000000010206, RIP: 0xffffff801c2200c5, CS:  0x0000000000000008, 
>>>> SS:  0x0000000000000010
>>>> Fault CR2: 0x0000000000000008, Error code: 0x0000000000000000, Fault CPU: 
>>>> 0x0, PL: 0, VF: 1
>>>> 
>>>> Backtrace (CPU 0), Frame : Return Address
>>>> 0xffffff8e20a1b7b0 : 0xffffff801bbad5cd 
>>>> 0xffffff8e20a1b800 : 0xffffff801bce9245 
>>>> 0xffffff8e20a1b840 : 0xffffff801bcda97a 
>>>> 0xffffff8e20a1b8b0 : 0xffffff801bb5a9d0 
>>>> 0xffffff8e20a1b8d0 : 0xffffff801bbacfe7 
>>>> 0xffffff8e20a1b9f0 : 0xffffff801bbace33 
>>>> 0xffffff8e20a1ba60 : 0xffffff801bcdab9d 
>>>> 0xffffff8e20a1bbd0 : 0xffffff801bb5a9d0 
>>>> 0xffffff8e20a1bbf0 : 0xffffff801c2200c5 
>>>> 0xffffff8e20a1bd30 : 0xffffff801c2267f7 
>>>> 0xffffff8e20a1bd80 : 0xffffff7f9d0a43d3 
>>>> 0xffffff8e20a1bdb0 : 0xffffff7fa1b5b658 
>>>> 0xffffff8e20a1bdd0 : 0xffffff7fa1b5b321 
>>>> 0xffffff8e20a1be00 : 0xffffff7f9d0a2fd2 
>>>> 0xffffff8e20a1be40 : 0xffffff801c22df6b 
>>>> 0xffffff8e20a1be80 : 0xffffff801c22dc25 
>>>> 0xffffff8e20a1bf00 : 0xffffff801c22d1e7 
>>>> 0xffffff8e20a1bf50 : 0xffffff801c22ecd6 
>>>> 0xffffff8e20a1bfa0 : 0xffffff801bb5a0ce 
>>>>       Kernel Extensions in backtrace:
>>>>          
>>>> com.apple.iokit.IOAudioFamily(206.5)[F5DBFDB4-22C9-32C1-BB72-3372EAAB1FCB]@0xffffff7f9d09f000->0xffffff7f9d0ddfff
>>>>             dependency: 
>>>> com.apple.vecLib.kext(1.2.0)[3B4888B9-CBFC-39DE-A8A2-1C6377702BC3]@0xffffff7f9cfcf000
>>>>          
>>>> com.CMedia.CMI8788.PCIAudioDriver(1337.0)[911B90EB-E9A8-32ED-BE28-B51438A69824]@0xffffff7fa1b58000->0xffffff7fa1c09fff
>>>>             dependency: 
>>>> com.apple.iokit.IOPCIFamily(2.9)[CE5E5806-48AB-39C0-8C1F-B57921B37D71]@0xffffff7f9c492000
>>>>             dependency: 
>>>> com.apple.iokit.IOAudioFamily(206.5)[F5DBFDB4-22C9-32C1-BB72-3372EAAB1FCB]@0xffffff7f9d09f000
>>>>             dependency: 
>>>> com.apple.kec.pthread(1)[6C7628FE-2621-3C19-B248-D4DA0D722123]@0xffffff7f9cb26000
>>>> 
>>>> BSD process name corresponding to current thread: kernel_task
>>>> Boot args: agdpmod=pikera enable-gva-support shikigva=80 unfairgva=1 
>>>> mbasd=1 -no_compat_check no32exec=0 debug=0x8 serverperfmode=1 ncl=262144
>>>> 
>>> 
>>> 
>>>> On Dec 21, 2022, at 5:20 PM, Devin Roth <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> I assume all your streams use the same clock. In that case it will be the 
>>>> same for all of them. I’m pretty sure that clocks run at the device level 
>>>> rather than the stream level. 
>>>> 
>>>> Devin
>>>> On Dec 21, 2022, 3:56 PM -0800, Gagan Sidhu via Coreaudio-api 
>>>> <[email protected] <mailto:[email protected]>>, 
>>>> wrote:
>>>>> hello all,
>>>>> 
>>>>> so the driver completes inithardware, the streams are ready to go, but 
>>>>> it’s panicking and there’s no printf to show where.
>>>>> 
>>>>> 1. is it possible/likely it’s crashing because i have an empty 
>>>>> getCurrentSampleFrame method?
>>>>> -probably?
>>>>> 
>>>>> 2. the engine is asking me to return a single UInt32 value. what if i 
>>>>> have multiple streams, though?
>>>>> -we would want to update the position of each active stream, would we not?
>>>>> -this would require one UInt32 per stream.
>>>>> 
>>>>> this is done in the ALSA driver as follows:
>>>>> 
>>>>>> static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream 
>>>>>> *substream)
>>>>>> {
>>>>>> struct oxygen *chip = snd_pcm_substream_chip(substream);
>>>>>> struct snd_pcm_runtime *runtime = substream->runtime;
>>>>>> unsigned int channel = oxygen_substream_channel(substream);
>>>>>> u32 curr_addr;
>>>>>> 
>>>>>> /* no spinlock, this read should be atomic */
>>>>>> curr_addr = oxygen_read32(chip, channel_base_registers[channel]);
>>>>>> return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr);
>>>>>> }
>>>>>> 
>>>>> 
>>>>> it seems ALSA passes the stream to the function and then it can be 
>>>>> updated easily.
>>>>> 
>>>>> in the APPUL case, it does not seem like we know what stream we’re being 
>>>>> asked to update. there are no parameters being passed.
>>>>> 
>>>>> in short: how can we update the position of multiple streams using the 
>>>>> existing getCurrentSampleFrame prototype?
>>>>> 
>>>>> so close to getting this bad boy going (i think)!!
>>>>> 
>>>>> Thanks,
>>>>> Gagan
>>>>> 
>>>>> _______________________________________________
>>>>> Do not post admin requests to the list. They will be ignored.
>>>>> Coreaudio-api mailing list ([email protected] 
>>>>> <mailto:[email protected]>)
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>> https://lists.apple.com/mailman/options/coreaudio-api/devinroth%40existential.audio
>>>>>  
>>>>> <https://lists.apple.com/mailman/options/coreaudio-api/devinroth%40existential.audio>
>>>>> 
>>>>> This email sent to [email protected] 
>>>>> <mailto:[email protected]>
>>> 
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Coreaudio-api mailing list ([email protected] 
>>> <mailto:[email protected]>)
>>> Help/Unsubscribe/Update your Subscription:
>>> https://lists.apple.com/mailman/options/coreaudio-api/devinroth%40existential.audio
>>>  
>>> <https://lists.apple.com/mailman/options/coreaudio-api/devinroth%40existential.audio>
>>> 
>>> This email sent to [email protected] 
>>> <mailto:[email protected]>
> 

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to