• Welcome to ASR. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

FiiO PEQ – Equalizer APO Converter

How easy where my instructions to follow?

  • The instructions looked too complicated so I didn't even try

    Votes: 0 0.0%
  • I tried but gave up

    Votes: 0 0.0%
  • I got it working, but it wasn't easy

    Votes: 0 0.0%
  • The instructions where perfect

    Votes: 0 0.0%
  • The instructions where unnecessarily detailed

    Votes: 0 0.0%
  • I got it working, I didn't even need the instructions

    Votes: 2 100.0%

  • Total voters
    2

IsaacOscar

Senior Member
Forum Donor
Joined
Jan 11, 2026
Messages
343
Likes
173
I have attached a javascript converter between FiiO's (Undocumented) XML format for PEQ filters, and Equalizer APO's txt format. Which is very useful if you want to try Amir's PEQ settings on a FiiO device, or for making a custom EQ using the very helpful squig.link web app.

Note: I've only got a 10-band FiiO Tiny A and Melody to test this on; and others have tested it on the KA15; but it should hopefully work with other FiiO devices.

Features​

  • Converting from FiiO to Equalizer APO is very simple, and supports all FiiO PEQ features supported by my Tiny A.
  • Converting from Equalizer APO to FiiO only supports the following features:
    • YOU MUST change set device_model variable at the top of the script file (the generated xml file will then only work with the selected device; however you can manually modify the specified model at the top of an xml file to a different device).
    • Preamps (as above, this is adjusted based on the max_global_gain variable)
      BiQuad Filters (Peaking, low/high/band/all-pass, low/high-shelf),
      • Supported, via conversion to FiiO supported filters:
        • bandwidth (BW) values instead of Q. (This uses the value of the sample_rate variable at the top of the file)
        • slope values (only used in shelf filters)
        • corner-frequency shelf filters (LS/HS): these are converted to centre-frequency ones (LSC/HSC)
      • Similarly to the above, this multiplies Q values by √2, unless you make shelf_q_fix return false.
      • (Some devices don't support the low/high/all/band-pass filters, in which case you will get an error).
      • NOT SUPPORTED:
        • Notch (NO) filters
        • Filters with custom coefficients (IIR)
    • Comments
      • if the first line of the Equalizer APO file starts with a "# " the rest of the line is used as the name of the FiiO filter
      • any subsequent "# " lines are used as the description.
      • If the above are absent, the script will try to generate them based on the input and output file names.

WARNING: If you are using high-shelf (HS/HSC) filters, your FiiO device may output crazy loud & distorted stuff, even at low volume or preamp values!

The Melody and QX13 should be safe though. I do not know how to detect or fix this bug.
(currently, this bug is known to occur on the Tiny A, Tiny B, and Jeizi)

Instructions​

  1. To obtain a FiiO XML file: go to fiiocontrol.fiio.com (even if you are on a mobile), go to the personal tab on the left, click the ... on the profile you want, and then click export:
    1769732166210.png
    1. Exporting is not supported on the mobile app, but you can use the download/upload buttons to sync with the data on the website:
    2. Screenshot_20260308-044058.png
      Screenshot_20260308-044105.png
    3. WARNING: pressing "upload" will delete anything on the website that is not on your mobile app; and pressing "download" will undelete anything you've locally deleted.
  2. Run this script on the commandline node convert.js.txt --<model> <input filename> <output filename>(the filenames default to stdin/stdout).
    1. Where <model> is the (case-insensitive) model name of your device (you can use -'s instead of spaces, and you don't need to include the brand name, e.g. FIIO or SNOWSKY).
    2. If you are converting from a FiiO XML to Equalizer APO, the --&lt;model&gt; part is unnecessary and simply ignored (as the FiiO xml file contains this information)
    3. Instead of providing --<model>, you can modify the device_model variable at the top of the convert.js.txt file.
  3. Or use this version in an online interpreter
    1. If you are converting from Equalizer APO to FiiO, remember to modify the device_model variable at the top of the script
    2. On the top right, click the Input/Output tab.
    3. Make sure the Interactive Mode checkbox is unchecked
    4. Paste your input file in the big white Stdin Inputs text box below (it will auto-detect whether this is a FiiO XML file or an Equalizer APO file)
    5. Press the big orange Execute button at the top-right
    6. Copy the results from the big black box at the bottom right, and save it a file (the filename you use should end in .xml if you are generating a FiiO file)
      1769732789112.png
  4. If you are converting to a FIio XML file: go to fiiocontrol.fiio.com (even if you are on a mobile device), click the Import button at the top right, click Upload File, select your .xml file, then click Confirm.
    1769733306149.png

    The loaded profile will be at the bottom of the list, and might not have any name or description, but you can easily fix this:
    1769733456585.png

  5. If you are converting to Equalizer APO, paste the contents of the file into C:\Program Files\EqualizerAPO\config\config.txt
(The input file is detected as being a FiiO XML file if starts with a <?, otherwise it is assumed to be an Equalizer APO file. The output file format is the opposite of the input format.)

Supported Devices​

The following list of devices were extracted from the fiiocontrol.fiio.com source code (namely, the index-DcKjLhLc.js script file included by it):
If your device is not listed above, and you can still successfully import/export XML profiles on fiiocontrol.fiio.com, let me know so I can add support for it! (The script will give you instructions on how to manually add support for a device if it doesn't recognise the value of the device_model variable).

Please let me know if you have any question or feature requests. I'd especially like to know if it doesn't work correctly with a specific device.​

 
Last edited:
Wow great start! It's obviously missing most features from mine (in particular, for LSC and HSC filters, the Q value will be wrong as it needs to be divided by √2)

It would be nice to put the various variables I've got at the top of my script into text boxes.

And if/when you implement conversion to Fiio XML files, you should also add text boxes for the name and description fields (my script just tries to generate these based on the filenames you pass it via command line)
 
Last edited:
Wow great start! It's obviously missing most features from mine (in particular, for LSC and HSC filters, the Q value will be wrong as it needs to be divided by √2)

It would be nice to put the various variables I've got at the top of my script into text boxes.

And if/when you implement conversion to Fiio XML files, you should also add text boxes for the name and description fields (my script just tries to generate these based on the filenames you pass it via command line)
aight. addedmost of it. check it again
 
aight. addedmost of it. check it again
Awesome!
Some things I noticed after a quick test:
  • You don't have an upload file button for EqualizerAPO
  • The shelf Q checkbox should also be an option on the to Fiio XML version
  • There is no text box for the no_gain parameter
  • You are not correctly converting preamp and masterGain values (you should use masterGain = floor(preamp + no_gain)
  • You should give an error (or disable the buttons?) if you don't give a device model, as the generated XML file won't work.
Also I'm going to update my script tomorrow
based on more device-dependent stuff I've discovered, see the spoiler for details (in particular, I think you should have a drop down box that lets you select a Fiio device name, and have it pre fil the various text boxes based on this information).
Code:
Unless otherwise stated, the following information was obtained from fiiocontrol.fiio.com/index-DcKjLhLc.js
These are the valid values of device-model (but you should allow a custom one as well just in case):
    FIIO Air Link
    FIIO BR15 R2R
    FIIO BT11
    FIIO BTR13
    FIIO BTR17
    FIIO DM15 R2R
    FIIO FG3
    FIIO FP3
    FIIO FX17
    FIIO K13 R2R
    FIIO K15
    FIIO K17
    FIIO K19
    FIIO KA15
    FIIO KA17
    FIIO LS-TC2
    FIIO OAK NANO
    FIIO QX13
    JadeAudio JA11
    JadeAudio JIEZI
    RETRO NANO
    SNOWSKY Melody
    SNOWSKY TINY A
    SNOWSKY TINY B

TODO: lookup each of the above and determine how many bands they have
    (most have 10, the K17 and K19 have 31)

Dvice version is always 0.0.1

Some devices only support some filter types:
     only Peak, Low/High shelf:  JA11, BTR17, FP3, LS TC2, OAK NANO, K17, K19
      does not support band pass: BR15 R2R
      does not support all pass:  FIIO FG3
    
the valid values for master gain are usually from -24 to 12, except:
    the following have a mimum of -12: JA11, JIEZI, TINY A, TINY B, KA17, RETRO NANO, BTR13, KA15, BTR17, QX13, LS TC2
    (obtained from testing) for the Tiny A, and probably Tiny B, the maximum is actually 5, values from 6–12 behave like 5)

The range of valid Q values is usually between 0.25 and 8, exept:
   the K17 and K19  have a range between 0.4 and 128


also theres a bug I need to fix (it's not correctly ignoring EqualizerAPO filters that are "OFF" instead of "ON").
 
Last edited:
aight. addedmost of it. check it again
Ok, I've read your source code now:
  • I see you are trying to calculate the appropriate preamp that avoids clipping, however your calculation is incorrect as it doesn't take into account filters overlapping (e.g. if you have +1 dB high-shelf filter, and then a +1 dB peak filter after that, your maximum gain could actually be +2 dB). I don't know how to calculate this correctly, but I know squig.link seems to be doing it.
  • You really should give an error if the EqualizerAPO file has more bands than the device supports, as fiiocontrol.fiio.com itself often doesn't give erors but just behaves weirdly when given bad data
  • You're still missing some features of course (no checks that the filter parameters are within Fiio's supported range, no conversion of BW, slope, and LS/HS filters)
 
Last edited:
Another feature that might be useful (that I haven't implemented), is allowing you to convert a Fiio XML from one device to another (r.g. this would modify the masterGain accordingly, and round values). This is equivalent to converting to EqualizerAPO and back again, but it would preserve the StyleName and description fields.
 
aight. addedmost of it. check it again
Ok I've updated my script now, all the logic around variables has changed.
For making the web UI: just give users a drop-down box with all the values of my known_devices variable, and you shouldn't need to provicde textboxes for the device_version or bands variables.
Also if you could provide a link to this thread on your website (so we can get feadback) that would be great.
 
Thanks for this folks. My BTR13 arrived today and I successfully converted the PEQ for my Moondrop LAN II POP from the text format I use for Topping Tune (same as eAPO) into the XML for Fiio - I used the website.
 
Back
Top Bottom