Page 1 of 6

Re: DTS support progress?

Posted: Fri Mar 04, 2011 11:45 am
by smartsmurf
I am still working on it, but at the moment I am a little bit stuck.

DTS passthrough requires some parts within samdrv.ko which are not present at the moment. You need to know that exeDSP just sets audio codec (PCM, WMA, AC3, etc.) and then later just sends down the audio frames.

I tried the following:
1) extracted AIDA DTS ucode from C series TV.
2) wrote samdrvext.ko as hook/extension to samdrv.ko for loading the C series ucode
3) instead of sending PCM 2.0 i sent DTS frames to samdrv.ko
4) the ucode gets loaded, but due to different hardware/memory architecture it is not processing the frames
-> stuck here
5) normally I would have implemented the functions for SPDIF output in samdrvext.ko next, but right now there is reason

For item 4) there is two options:
4a) reverse engineer AIDA DTS ucode and compile for B series TV.
4b) move DTS decoding library (e.g. ffmpeg) to samdrvext.ko to get fed the DTS audio frames and send them via SPDIF out and PCM 2.0 to AIDA PCM engine.

I started with 4a), but without knowledge on that proprietary piece of hardware it is more or less trial and error in order to analyze which registers/memories perform which tasks. Also I would estimate one man year in doing this work. So this path is not leading to a fast solution.
At the moment I am experimenting with 4b).

Questions, suggestions and volunteers are welcome. :)

Re: DTS support progress?

Posted: Wed Mar 09, 2011 12:48 am
by sbav1
An idea (I'm not sure if it's a viable one): for bit-perfect spdif transfers, maybe we can insert/substitute audio samples in CALM/AIDA output (== SPDIF Tx input) ring buffer (???).
I.e.: AIDA set for PCM playback and running as usual (we will feed it with random/all-zeros samples from exeDSP in right quantities), with it's output buffer constantly/concurrently being overwritten with our own, arbitrary audio data.

Output buffer utilized by PCM spdif playback is located at 0x766d0000 (64kB total, two 32kB sub-buffers for left/right channel), 32bit/4bytes per sample, bytes 0-2 (from left to right) are most probably 24-bit low-endian samples, byte 3 is always 0x00. Overwriting output buffers shouldn't be a problem, I tested it with the simple program (below); biggest obstacle is: how to achieve a proper timings.

I believe Spdif Tx hardware is consuming samples from left/right sub-buffers in 1024-byte long chunks via DMA transfers;
DMA6 BASE register (0x30630300, mapped to 0xf8630300 in kernel address space) looks interesting for synchronization purposes (holding 0x766D0000, 0x766D0400, ..., 0x766D7C00 pointers, incremented in 0x400 steps while PCM audio is being played via spdif). I hope somewhere in samdrv.ko there is a function (for initiating/setting up Spdif Tx DMA transfers periodically, or perhaps an interrupt handler for Spdif Tx) we can use for write pointer synchronization..

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>

#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)

#define BLK_SIZE 4096UL

int main(int argc, char **argv) {
    int fd;
    unsigned nonpp_out_addr=0x766d0000;
    unsigned mm_size=0x10000;

    [PES / ES In BASE ] 0x76680000 (SQB0 BASE)
    [PP Out BASE      ] 0x766c0000 (SQB1 BASE)
    [Non-PP Out BASE  ] 0x766d0000
    [PCM In 1 BASE    ] 0x76680000
    [PCM In 2 BASE    ] 0x76690000
    [AD MIX BASE      ] 0x766e0000
    [ES Out BASE      ] 0x766b8000

    /* [SPDIF TX 0 DMA Register Value (DMA 6)]
    [BASE       (0xf8630300)] 0x766d0000
    [TRCNT      (0xf8630304)] 0x00000800
    [CTCNT      (0xf8630308)] 0x00000660
    [CADDR      (0xf863030c)] 0x766d7ce0
    [CFG        (0xf8630310)] 0x310c8000
    [COM        (0xf8630314)] 0x00000000
    [INTCFG     (0xf8630318)] 0x00001000
    [STATUS     (0xf863031c)] 0x00000001
    [WRSIZE     (0xf8630320)] 0x00000000
    [WRADDR     (0xf8630324)] 0x00000000
    [OBUF       (0xf8630328)] 0x00000000

    * 0x3063_0300 ~ 0x3063_0328 : 41. AIO DMA6
    * 0x3063_0680 ~ 0x3063_06B0 : 41. AIO SPDIF Tx

    unsigned target=nonpp_out_addr;
    if (mm_size % BLK_SIZE) { fprintf(stderr, "\nSize value (%d) outside block boundary !!!\n", mm_size); exit(1); }
    if (target % BLK_SIZE) { fprintf(stderr, "\nInvalid address (%p) !!!\n", target); exit(1); }

    if ((fd=open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
    void *mm_base=mmap(0, mm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target);
    if (mm_base == (void *) -1) FATAL;
    printf("Memory %p mapped at address %p.\n", target, mm_base);
    printf("Size: %d bytes / %d kB / %d block[s].\n", mm_size, (mm_size/1024), (mm_size/BLK_SIZE));

    int blen=mm_size/2;
    unsigned char *b1addr=mm_base;
    unsigned char *b2addr=mm_base+blen;

    while (1) {
       memset(b1addr, 0, blen); // LEFT CHANNEL 32kB buf
       memset(b2addr, 0, blen); // RIGHT CHANNEL 32kB buf
       printf("="); fflush(stdout);
       usleep(50000); // 50ms sleep (?) ~enough to overwrite output buffers in real-time for 44.1kHz playback

    if (munmap(mm_base, mm_size) == -1) FATAL;
    return 0;

Re: DTS support progress?

Posted: Fri Mar 11, 2011 2:08 am
by sbav1
AWW, it works :). DMA reg sync method is a little bit ugly, though ;(
Proof-of-concept app for DTS passthrough: ... 0.tgz.html

audio.spdif: an IEC 61937 encoded DTS audio sample, generated with:

Code: Select all

ffmpeg -i ATofTS-002.mkv -vn -sn -acodec copy audio.dts
ffmpeg -i audio.dts -acodec copy -f spdif audio.spdif
- initialize playback of [any] media file with 2-channel 48kHz audio in Samsung media player (typical *.avi file with stereo 48kHz MP3 audio track should be fine for that purpose),
- run atest1 from command line.

Tested with my old Yamaha RX-V350 receiver. YMMV; a couple of bits in spdif tx channel status registers should be [most likely] flipped for a better receiver compatibillty (RX-V350 general behavior: if it looks like iec61943 stream, it is
an iec61943 stream == "I'll better happily ignore improper CS bits, for a better good").

Re: DTS support progress?

Posted: Sat Mar 12, 2011 1:17 pm
by majonezz
Great news! I want to test it with LE40B679 and Yamaha HTR-5930, but i'm getting following error:

Code: Select all

# /mtd_wiselink/SamyGo/DTS_Test/atest1
Memory 0x766d0000 mapped at address 0x4013f000.
Size: 65536 bytes / 64 kB / 16 block[s].
Registers 0x30000000 mapped at address 0x4014f000.
Size: 11276288 bytes / 11012 kB / 2753 block[s].
ERROR: fopen() failed !!!
ERROR: read failed.
File with sample content is in the same directory as exe is. What i'm doing wrong?

Re: DTS support progress?

Posted: Sat Mar 12, 2011 1:22 pm
by erdem_ua
Wooho. :)
I do not declared bounty for pass-thru before, but now decided to give $100 for this hack. (After checking if it's works on B650)
Doesn't it worth to it? :D

I add your acc as a project member. You welcome :D
Please put that file into download area directly.

Thanks sbav1.