[Windows Store version] MP3 Playing audio distortion

Started by jasonWun, 21 Apr '18 - 02:49

jasonWun

Hi,

I'm developing a music player for UWP and using the bass.dll of windows store version. However, I notice that it distorts (not sure it is the correct word to describe this) the audio a little bit while it is playing mp3 file.  I found the problem exists on another UWP app which uses Bass to output audio as well. Therefore it must be something wrong inside the library.

In short, here is the mp3 file which has the most distinct distortion in my opinion: https://1drv.ms/u/s!AlC0PxjvqYdLufo-s-ZRSr9ZGWgF_Q . In the first 20 secs (no other music instrument included yet), whenever the artist is singing you will hear the distorted sound in the background and it sounds like someone is whistling behind the artist.

This is the code to reproduce the problem, note you should declare capability of "Music Library" in Package.appxmanifest in order to pick and play the music
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Un4seen.Bass;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml.Controls;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace App2
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Bass.BASS_Start();
            Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
            NewMethod();
        }

        private async Task NewMethod()
        {
            var file = await SelectPlaybackFile();
            await Task.Run(() =>
            {
                int _handle = Bass.BASS_StreamCreateFile(file.Path, 0,0,BASSFlag.BASS_STREAM_AUTOFREE);

                //var length = Bass.BASS_ChannelBytes2Seconds(_handle, Bass.BASS_ChannelGetLength(_handle));

                if (_handle != 0 && Bass.BASS_ChannelPlay(_handle, false))
                {
                    // playing
                }
                else
                {
                    Debug.WriteLine("Error={0}", Bass.BASS_ErrorGetCode());
                }
            });
        }

        private async Task<IStorageFile> SelectPlaybackFile()
        {
            var picker = new FileOpenPicker
            {
                ViewMode = PickerViewMode.List,
                SuggestedStartLocation = PickerLocationId.MusicLibrary
            };
            picker.FileTypeFilter.Add(".mp3");
            picker.FileTypeFilter.Add(".aac");
            picker.FileTypeFilter.Add(".wav");
            picker.FileTypeFilter.Add(".m4a");

            var file = await picker.PickSingleFileAsync();
            return file;
        }
    }
}

If you don't have UWP development environment installed, you can download "Bread Player" from Windows Store and replay the attached mp3 file. It uses Bass to output audio and it will reproduce the problem either.

UPDATE:
I found that there is a better way to illustrate the problem which is drawing the audio spectrum, and it works. Here is the video posted on Youtube.

CAUTION: Please lower your volume
https://www.youtube.com/watch?v=DLgq_XEoPXQ&feature=youtu.be

The first distortion happens around 14-18 secs represent audio roughly from 280Hz to 900Hz.
The second distortion happens around 18s to 20s represents audio roughly between 1200Hz to 1800Hz
And the later ones are so hard to identify form the spectrum so I just ignore them but I believe the video can help you better understand the problem

Ian @ un4seen

To help narrow down where the problem is, please confirm what architecture you are running the app on, ie. x86/x64/arm? Does switching to another one make any difference? Also, is the problem only happening with MP3 files, and not WAV versions of the same audio?

jasonWun

Hi Ian,

Sorry for excluding more details on my post.

Q: What architecture you are running the app on, ie. x86/x64/arm? Does switching to another one make any difference?
A: The problem exists on both x86 & x64. I don't have any Windows 10 device with Arm processor so I can' give you the answer.

Q: is the problem only happening with MP3 files, and not WAV versions of the same audio
A: Yes. The problem only happening with MP3 files. I have tested file including .mp3, .m4a, and .wav and only MP3 files encounter the problem

Ian @ un4seen

That's strange. The MP3 decoder should be identical in the x86/x64 Windows Store and Win32 versions. Do you have the problem with the Win32 version too, eg. when running one of the pre-compiled examples in the BASS package?

jasonWun

No. In fact the decoder runs perfectly fine on Win32 platform and it confuses me as well. I'm guessing something broken for Win Store version

I'll take a look at it on my part and see what make the distortion happens

Ian @ un4seen

OK. To confirm that the problem definitely is in the MP3 decoding, could you try writing the decoded data to a file and then load that in a sample editor to check it? You can do the file writing in a DSPPROC function, set on the MP3 stream via BASS_ChannelSetDSP. Make sure there are no other DSP/FX set on the stream, in case they are causing the problem. Please also upload the test file that you used in your Youtube video, to try here.

   ftp.un4seen.com/incoming/

jasonWun

Hi Ian,

I would like to provide the decoded file to you.  Unfortunately,  I have little experience of audio processing.  I follow the code on document of DSPPROC function. And so far I got something like this and I get stuck
private async Task NewMethod()
        {
            var file = await SelectPlaybackFile();
            await Task.Run(() =>
            {
                _handle = Bass.BASS_StreamCreateFile(file.Path, 0,0,BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_SAMPLE_FLOAT);
                var _myDSPProc = new DSPPROC(Dsp1);
                int dspHandle = Bass.BASS_ChannelSetDSP(_handle, _myDSPProc, IntPtr.Zero, 0);
                Bass.BASS_ChannelPlay(_handle, false);
            });
           
        }

        unsafe void Dsp1(int handle, int channel, IntPtr buffer, int length, IntPtr user)
        {
            for (var s = (short*)buffer; length != 0; length -= 4, s += 2)
            {
                //Don't know what to write
            }
        }

It would be appreciated for providing more detail extract out the decoded data

Ian @ un4seen

I'm not a .Net user myself, so I'm not sure what's the best way to write the file there, especially in UWP flavour. I was hoping you would know :) ... You basically want to write the entire buffer to a file, so probably no need for a "for" loop. For example, using the C "fwrite" function would look like this:

void CALLBACK Dsp1(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
FILE *file = (FILE*)user;
fwrite(buffer, 1, length, file);
}

I found this, but I'm not sure it really makes things any clearer (to me at least):

   https://docs.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files

If you do manage to write the file, it will be a raw (headerless) PCM file. You won't be able to open it in a general media player but you can in a sample editor, or you can upload it and I'll check it:

   ftp.un4seen.com/incoming/

Please also upload the test file that you used in your Youtube video.

jasonWun

Hi Ian,

I uploaded the file at the first place but I didn't see any hint about success so I stopped the process. I tried to upload it again but it said there is no overwrite permission.

Could you please take a look at it and see if there any zip file named "MP3DistortionTestFileFromJasonWun.zip" which takes like 4.90 MB (5,146,432 bytes).

If you don't see such or the number of its size does not match, could you please delete the current one on remote and i will upload it again.


Ian @ un4seen

There was a file with 0 byte size. That has now been removed, so please try again. Note uploaded files aren't publicly visible, so you won't be able to see the file on the server after it has been uploaded.

jasonWun

It should work this time. I uploaded a file named "MP3DistortionTestFile.zip" while there is also a "MP3DistortionTestFileFromJasonWun.zip" due to failed ftp connection.

Let me know if the PCM file is correct.

Ian @ un4seen

Thanks for the test MP3 file. I am able to reproduce the problem with that. I notice it doesn't happen when compiler optimizations are disabled, so I will try to find out what part of the MP3 decoder the compiler optimizations are having trouble with and then come back with a fix.

Ian @ un4seen

Good news. Simply installing the latest update for the compiler seems to have fixed the problem. A recompiled BASS.DLL is up in the first post of the Windows Store thread now, so please re-download and see if you still get the problem with that.

jasonWun

It worked. Appreciated for your work