List of Music Players that Use Our DAC (10j changes things)

Search This thread

shadowxaero

Senior Member
Apr 19, 2008
375
125
As of 10j Black Player and Pulsar down sample.

Short answer...In my testing only the Stock LG Music Player, will output Hi-Fi audio without down-sampling.
WE HAVE THREE OPTIONS....so far.

I used an internal Sound Blaster Z to record audio from the phone (Can only record up to 96kHz). Adobe Audition is my DAW of choice.

Music Players Tested
LG Stock Music Player - 96kHz playback (I am sure it will do higher, I just can't record higher than 96kHz.)
Black Player - 96kHz 10i
Pulsar - 96kHz 10i

PowerAMP - 48kHz
GoneMAD - 48kHz
Rocket Player - 48kHz
Onkyo Player - 48kHz
Neutron - 48kHz

Player Pro - 44.1kHz (48kHz with dsp pack)
JetAudio - 44.1kHz
Play Music - 44.1kHz
Shuttle+ - 44.1kHz
Foobar - 44.1kHz

Youtube - *Shrugs* something even lower lol.

NFCzO9q.png

eYSQFVE.png

HeciciS.png


Note using v4a will downsample the audio to 48kHz regardless of whatever player you use.
 
Last edited:

jamebarron88

Senior Member
Short answer...In my testing only the Stock LG Music Player, will output Hi-Fi audio without down-sampling.
I used an internal Sound Blaster Z to record audio from the phone (Can only record up to 96kHz). Adobe Audition is my DAW of choice.

Music Players Tested
LG Stock Music Player - 96kHz playback (I am sure it will do higher, I just can't record higher than 96kHz.)

PowerAMP - 48kHz
GoneMAD - 48kHz
Rocket Player - 48kHz

Player Pro - 44.1kHz
JetAudio - 44.1kHz
Play Music - 44.1kHz
Shuttle+ - 44.1kHz
Foobar - 44.1kHz

Youtube - *Shrugs* something even lower lol.




So unfair! The stock music player was not included on Sprint variant.
 

WishRyder

Senior Member
Feb 2, 2008
165
62
Waukee, IA
Music Players Tested
LG Stock Music Player - 96kHz playback (I am sure it will do higher, I just can't record higher than 96kHz.)
Black Player - 96kHz
Pulsar - 96kHz

Thanks for the recommendations! I've been a longtime user of PowerAmp, to the point where I haven't even bothered looking into alternatives, but I've been slowly falling out of love with it. I'm not crazy about the stock LG player and am glad to know there are some high quality apps out there that will play high quality files. Unfortunately, now I'm faced with the problem of trying to decide between Black Player and Pulsar! :crying:
 

DamnCampers

Senior Member
Jul 29, 2010
60
13
You might want to check jetAudio. I just changed to the v20 from a note 4 and its still doing good. I have the plus version and just by toggling the dac and listening i can hear a difference in quality.
 

fenrir_ac

Senior Member
Jun 21, 2014
144
61
What about zplayer? I thought someone mentioned it on other thread but not sure if it's supported.
 

shadowxaero

Senior Member
Apr 19, 2008
375
125
You might want to check jetAudio. I just changed to the v20 from a note 4 and its still doing good. I have the plus version and just by toggling the dac and listening i can hear a difference in quality.

I checked JetAudio and it does downsample. (And it honestly sounds like it does haha). What kind of headphones are you using?

What about zplayer? I thought someone mentioned it on other thread but not sure if it's supported.

I will check zPlayer and n7 player today.
 
  • Like
Reactions: fenrir_ac

DamnCampers

Senior Member
Jul 29, 2010
60
13
I checked JetAudio and it does downsample. (And it honestly sounds like it does haha). What kind of headphones are you using?

Right now I've got a couple pairs that I change around as I need to. My primary ones that I use are a pair of Jays One+, but I have been thinking about trying out my pair of Astro A40s to see if the dac is strong enough for push the headphones without the hardware dac for the headphone.
 

shadowxaero

Senior Member
Apr 19, 2008
375
125
Right now I've got a couple pairs that I change around as I need to. My primary ones that I use are a pair of Jays One+, but I have been thinking about trying out my pair of Astro A40s to see if the dac is strong enough for push the headphones without the hardware dac for the headphone.

I use a pair of a40s when I stream gameplay and I want to say their impedance is around 50 ohms if not a bit less so the v20 will drive them no problem. The a40s soundstage leave much to be desired. The headset is great for gaming for things like picking up footsteps behind you and what not. And they are good at simulating the direction a sound is coming from, but this "surround" effect it produces makes music, especially high sample rate music sound, reverby. So just be cautions about that.

The earbuds will sound better when you toggle the DAC because earbuds by nature have a narrow band to them. So toggling to DAC may give the impression of a wider sound which makes it sound better but that doesn't necessarily mean the audio player isn't downsampling the music.

I personally need my q701s to really hear the difference between 44.1/48kHz sampled music and 96kHz. I can't really distinguish above 96kHz lol.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 21
    As of 10j Black Player and Pulsar down sample.

    Short answer...In my testing only the Stock LG Music Player, will output Hi-Fi audio without down-sampling.
    WE HAVE THREE OPTIONS....so far.

    I used an internal Sound Blaster Z to record audio from the phone (Can only record up to 96kHz). Adobe Audition is my DAW of choice.

    Music Players Tested
    LG Stock Music Player - 96kHz playback (I am sure it will do higher, I just can't record higher than 96kHz.)
    Black Player - 96kHz 10i
    Pulsar - 96kHz 10i

    PowerAMP - 48kHz
    GoneMAD - 48kHz
    Rocket Player - 48kHz
    Onkyo Player - 48kHz
    Neutron - 48kHz

    Player Pro - 44.1kHz (48kHz with dsp pack)
    JetAudio - 44.1kHz
    Play Music - 44.1kHz
    Shuttle+ - 44.1kHz
    Foobar - 44.1kHz

    Youtube - *Shrugs* something even lower lol.

    NFCzO9q.png

    eYSQFVE.png

    HeciciS.png


    Note using v4a will downsample the audio to 48kHz regardless of whatever player you use.
    12
    Sorry if this is the wrong thread to post this in, but I hope it will be helpful to app developers trying to use the V20's DAC.

    After some investigation, it looks like the regular Android "MediaPlayer" API works perfectly on the V20: If you feed it any file, it outputs directly to the hardware (bypassing the Android mixer) at the correct sample rate.

    I tested using the following code, and running "dumpsys media.audio_flinger" while it was playing:
    Code:
    String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +"/test1.mp3";
    MediaPlayer mp = new MediaPlayer();
    mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
    File f = new File(filePath);
    FileInputStream fIS = new FileInputStream(f);
    mp.setDataSource(fIS.getFD());
    fIS.close();
    mp.prepare();
    mp.start();
    For instance, here's a "dumpsys media.audio_flinger" while playing a 320kbps, 16-bit, 44.1khz MP3 (MP3 supports hardware decoding, so it's just writing the MP3 data directly to the audio driver which then sends the decoded data to the DAC):
    Code:
    Output thread 0xedea7000 type 4 (OFFLOAD):
      Thread name: AudioOut_AD5
      I/O handle: 2773
      TID: 4006
      Standby: no
      [b]Sample rate: 44100 Hz[/b]
      HAL frame count: 32768
      HAL format: 0x1000000 (mp3)
      HAL buffer size: 32768 bytes
      Channel count: 2
      Channel mask: 0x00000003 (front-left, front-right)
      Processing format: 0x1000000 (mp3)
      Processing frame size: 1 bytes
      Pending config events: none
      Output device: 0x4 (WIRED_HEADSET)
      Input device: 0 (NONE)
      Audio source: 0 (default)
      Normal frame count: 32768
      Last write occurred (msecs): 606
      Total writes: 11
      Delayed writes: 0
      Blocked in write: no
      Suspend count: 0
      Sink buffer : 0xeec59000
      Mixer buffer: 0xeed2d000
      Effect buffer: 0xf00af000
      Fast track availMask=0xfe
      Standby delay ns=1000000000
      AudioStreamOut: 0xf0088c08 flags 0x31 (DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING)
      Stream volumes in dB: 0:-10, 1:-28, 2:-28, 3:-28, 4:-28, 5:-28, 6:0, 7:-28, 8:-27, 9:-96, 10:0, 11:-28, 12:0, 13:0
      Normal mixer raw underrun counters: partial=0 empty=0
      1 Tracks of which 1 are active
        Name Active Client Type      Fmt Chn mask Session fCount S F [b]SRate[/b]  L dB  R dB    Server Main buf  Aux Buf Flags UndFrmCnt
        none    yes   3977    3 01000000 00000003    5921  65536 A 3 [b]44100[/b]     0     0  00040000 0xeec59000 0x0 0x000         0
      0 Effect Chains

    And a 24-bit, 96khz FLAC (it's decoding in software, and outputing 24/96 PCM directly, again bypassing the mixer):
    Code:
    Output thread 0xee84a000 type 1 (DIRECT):
      Thread name: AudioOut_ADD
      I/O handle: 2781
      TID: 5001
      Standby: no
      [b]Sample rate: 96000 Hz[/b]
      HAL frame count: 3840
      [b]HAL format: 0x6 (pcm24)[/b]
      HAL buffer size: 23040 bytes
      Channel count: 2
      Channel mask: 0x00000003 (front-left, front-right)
      [b]Processing format: 0x6 (pcm24)[/b]
      Processing frame size: 6 bytes
      Pending config events: none
      Output device: 0x4 (WIRED_HEADSET)
      Input device: 0 (NONE)
      Audio source: 0 (default)
      Normal frame count: 3840
      Last write occurred (msecs): 22
      Total writes: 44
      Delayed writes: 0
      Blocked in write: yes
      Suspend count: 0
      Sink buffer : 0xede8c000
      Mixer buffer: 0xee924000
      Effect buffer: 0xee988000
      Fast track availMask=0xfe
      Standby delay ns=1000000000
      AudioStreamOut: 0xf0088a48 flags 0x2001 (DIRECT|0x2000)
      Stream volumes in dB: 0:-10, 1:-28, 2:-28, 3:-28, 4:-28, 5:-28, 6:0, 7:-28, 8:-27, 9:-96, 10:0, 11:-28, 12:0, 13:0
      Normal mixer raw underrun counters: partial=0 empty=0
      1 Tracks of which 1 are active
        Name Active Client Type      Fmt Chn mask Session fCount S F [b]SRate[/b]  L dB  R dB    Server Main buf  Aux Buf Flags UndFrmCnt
        none    yes   4953    3 00000006 00000003    5929  49920 A 3 [b]96000[/b]     0     0  0002A300 0xede8c000 0x0 0x000         0
      0 Effect Chains

    So, that's the good news: Players that just use the android MediaPlayer to decode and play audio will likely work fine with the V20's DAC. I took a look at LG's default music player (which is confirmed working) in a Java decompiler, and it's not doing anything other than that (other than adding its built-in equalizer, effects, etc).

    The bad news is that it seems MediaPlayer is the ONLY accessible API which works properly. Everything else (AudioTrack and OpenSL) will resample everything to 48khz/16-bit and pass it through the Android mixer - even CD-quality audio which is 44.1khz! So, while it's good that MediaPlayer works OK, there's no way to use it to output raw data and handle decoding separately. This limits apps using it to the built-in Android effects and precludes things like better equalizers.

    Looking at the actual firmware code, it's likely that the reason MediaPlayer works is because it uses the low-level AudioTrack C++ libraries, which can accept ALL output PCM formats (including 24-bit integer), and LG's drivers correctly detect the hi-res 24-bit formats and route them appropriately. Android's public APIs for AudioTrack and OpenSL can only accept 16-bit integer PCM or 32-bit floating point - and the 32-bit floating point apparently doesn't trigger the right route, and puts everything through the mixer resampled to 48khz.

    While this AudioTrack C++ interface isn't publicly documented or accessible, it is possible to use it via dlopen(). After about a week of experimenting to find the right parameters to pass, I got it working! It can directly output 24-bit stereo PCM data in any of the supported sampling rates up to 192khz, in the same way MediaPlayer does. I suspect Poweramp's "hi-res" output driver uses a similar method, and works with regular Snapdragon phones, so hopefully it would just take some small tweaks to get the V20 working.

    Here's some example JNI code. It won't work as-is, and has some pseudocode. Any app using it needs a target API version <= 22, as Google purposely broke the dlopen() method in later versions, as they don't want apps doing this (I don't blame them, but there seems to be no other way to use the V20 DAC; hopefully an official version will be provided at some point). It also needs "audio.h" from the Android framework.
    Code:
    #include "audio.h"
    
    /* How data is transferred to AudioTrack
         */
    enum transfer_type {
        TRANSFER_DEFAULT,   // not specified explicitly; determine from the other parameters
        TRANSFER_CALLBACK,  // callback EVENT_MORE_DATA
        TRANSFER_OBTAIN,    // call obtainBuffer() and releaseBuffer()
        TRANSFER_SYNC,      // synchronous write()
        TRANSFER_SHARED,    // shared memory
    };
    
    struct AudioTrack
    {
        char padding[0x400];
        int32_t guard;
    };
    
    typedef void (*AT_constructor1)(AudioTrack*);
    typedef void (*AT_destructor)(AudioTrack*);
    typedef void (*AT_set)(AudioTrack*,
                           audio_stream_type_t streamType,
                           uint32_t sampleRate,
                           audio_format_t format,
                           audio_channel_mask_t channelMask,
                           size_t frameCount, //   = 0,
                           audio_output_flags_t flags, // = AUDIO_OUTPUT_FLAG_NONE,
                           callback_t cbf, //      = NULL,
                           void* user, //          = NULL,
                           int32_t notificationFrames, // = 0,
                           void* UNUSED,
                           //const android::sp<IMemory>& sharedBuffer, // = 0,
                           bool threadCanCallJava, // = false,
                           audio_session_t sessionId, //  = AUDIO_SESSION_ALLOCATE,
                           transfer_type transferType, // = TRANSFER_DEFAULT,
                           const audio_offload_info_t *offloadInfo, // = NULL,
                           uid_t uid, // = -1,
                           pid_t pid, // = -1,
                           const audio_attributes_t* pAttributes, // = NULL,
                           bool doNotReconnect, // = false,
                           float maxRequiredSpeed); // = 1.0f);
    typedef int32_t (*AT_write)(AudioTrack*,
                                const void*,
                                int32_t,
                                bool);
    typedef int32_t (*AT_start)(AudioTrack*);
    typedef int32_t (*AT_stop)(AudioTrack*);
    typedef int32_t (*AT_pause)(AudioTrack*);
    typedef int32_t (*AT_flush)(AudioTrack*);
    
    typedef int (*RB_incStrong)(void*, const void*);
    typedef int (*RB_decStrong)(void*, const void*);
    
    
    extern "C"
    jstring
    Java_com_example_nativehiresoutputtest_MainActivity_audioTrackOut(
            JNIEnv *env,
            jobject, /* this */ ) {
    
        // re-load all DLLs, including "libmedia", as global instead of local, so we can access them. Doesn't work on API 23+.
        void* hdr = dlopen(NULL, RTLD_GLOBAL | RTLD_NOW | RTLD_NOLOAD);
    
        // load c++ functions from loaded DLLs
        AT_constructor1 cnstFcn = reinterpret_cast<AT_constructor1>(dlsym(hdr, "_ZN7android10AudioTrackC2Ev"));
        AT_destructor dstrFcn = reinterpret_cast<AT_destructor>(dlsym(hdr, "_ZN7android10AudioTrackD0Ev"));
        AT_set setFcn = reinterpret_cast<AT_set>(
                dlsym(hdr,
                      "_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjj20audio_output_flags_tPFviPvS"
                      "4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tiiPK1"
                      "8audio_attributes_tbf"));
        AT_write writeFcn = reinterpret_cast<AT_write>(dlsym(hdr, "_ZN7android10AudioTrack5writeEPKvjb"));
        AT_start startFcn = reinterpret_cast<AT_start>(dlsym(hdr, "_ZN7android10AudioTrack5startEv"));
        AT_stop stopFcn = reinterpret_cast<AT_stop>(dlsym(hdr, "_ZN7android10AudioTrack4stopEv"));
        AT_pause pauseFcn = reinterpret_cast<AT_pause>(dlsym(hdr, "_ZN7android10AudioTrack5pauseEv"));
        AT_flush flushFcn = reinterpret_cast<AT_flush>(dlsym(hdr, "_ZN7android10AudioTrack5flushEv"));
        RB_incStrong rbisFcn = reinterpret_cast<RB_incStrong>(dlsym(hdr, "_ZNK7android7RefBase9incStrongEPKv"));
        RB_decStrong rbdsFcn = reinterpret_cast<RB_decStrong>(dlsym(hdr, "_ZNK7android7RefBase9decStrongEPKv"));
    
        AudioTrack* at = reinterpret_cast<AudioTrack*>(calloc(sizeof(AudioTrack), 1));
        at->guard = 0xbaadbaad;
        cnstFcn(at);
        if (at->guard != 0xbaadbaad)
            return env->NewStringUTF("ERROR: constructor overwrote data!");
    
        // mark the AudioTrack (RefBase) strong pointer as referenced.
        rbisFcn(at, at);
    
        audio_attributes_t* attributes = reinterpret_cast<audio_attributes_t*>(calloc(sizeof(audio_attributes_t), 1));
        attributes->content_type = AUDIO_CONTENT_TYPE_MUSIC;
        attributes->source = AUDIO_SOURCE_DEFAULT;
        attributes->usage = AUDIO_USAGE_MEDIA;
        attributes->flags = 0x0;
    
        void* nullSharedBufferPtr = 0;
    
        // set parameters for the AudioTrack.
        setFcn(at,
               AUDIO_STREAM_MUSIC,
               192000, //sampleRate,
               AUDIO_FORMAT_PCM_24_BIT_PACKED,
               AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT,
               0,
               AUDIO_OUTPUT_FLAG_NONE,
               NULL, //audio_callback,
               NULL, //userData,
               0,
               &nullSharedBufferPtr,
               true,
               AUDIO_SESSION_ALLOCATE,
               TRANSFER_DEFAULT,
               NULL,
               getuid(),
               getpid(),
               attributes,
               false,
               1.0f
        );
    
        free(attributes);
    
        // start the AudioTrack playing.
        startFcn(at);
    
        // Write PCM (24-bit stereo packed) data.  (PSEUDOCODE, assumes sampleData exists)
        while (sampleRemaining > 0)
        {
            // synchronous write.
            int bytesWritten = writeFcn(at, &sampleData[idx], sampleRemaining, true);
            if (bytesWritten < 0)   ERROR();
            sampleRemaining -= bytesWritten;
            idx += bytesWritten;
        }
    
        // stop the AudioTrack playing, and flush the remaining data.
        stopFcn(at);
        flushFcn(at);
    
        // mark the AudioTrack (RefBase) strong pointer as de-referenced.
        rbdsFcn(at, at);
        //dstrFcn(at);     // destructor seems to hang
        free(at);
    }

    If anyone is working on a media player app and wants to use the above code in any form, for any reason, please feel free. I definitely don't have time to write one myself (and I'm not really an Android developer) - the important thing is to get the DAC working properly!

    I've only tested on my phone (H990ds, update v10d), so I'm not sure if firmware/hardware differences would affect this.
    8
    I just started looking at the V20 DAC again recently.

    A few things I've discovered:
    - The audio output method in my original post does indeed work. Everything up to 192 khz PCM is supported by this method.
    - There is support in the kernel for DSD, using DoP. Contrary to what you may read on audiophile forums, DoP ("DSD over PCM") IS actually DSD, without resampling or conversion - just wrapped in PCM packets for ease of transmission to the DAC. LG's source code includes support for this
    - In theory, on a rooted phone, if you set the ALSA mixer "Es9018 Dop" to 1, and send 176.4 khz/24bit PCM data with the bottom 16 bits of each packet set to the DSD data (see above link), the DAC should accept this data and decode it verbatim as DSD. (NOTE - I have not tested this!!)
    - Unfortunately, there seems to be no way to send 352.8khz PCM or DSD128 (or higher resolutions) to the DAC; to be honest, I can't imagine anyone can hear the difference (and I'm an audiophile) but whatever...

    I have a copy locally of FFmpegMediaPlayer with the audio output changed to use the AudioTrack c++ calls. (By the way, if wseemann is reading this - thanks!! You saved me probably a year of work, even if I'd had the motivation to write an FFmpeg android port myself. I sent you a donation.) My code is not at all reusable (I actually have my own equalizer settings hardcoded into the signal path, and the audio/video sync commented out). I need to clean it up before uploading it.
    5
    Guys, there are a lot of players that use the DAC and not get resampled. These are the ones I know that work properly:

    Pulsar
    Phonograph
    Pi
    Retro

    There are probably many more. You can actually see for yourself if they work or not:

    Turn on USB debugging and open cmd (whatever the windows version is) in the adb folder and enter this while music is playing with the music player you want in hi-fi mode with headphones on:

    adb shell dumpsys media.audio_flinger

    If there is a DIRECT section in the result and shows the sample rate right and the bit depth right (pcm16 or pcm24) then it is using the DAC properly.
    4
    Hi guys, lasted Poweramp (790) seems support Hi-Res output and use quaddac.