(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]