Hi all,
I wrote a sound player via basswasapi.dll(version 2.4.3.1). The feature I want to achieve is that each channel of the audio file's sound can be output independently, like ASIO mode.When using the wasapi exclusive mode,the following occurs:
- Audio output is correct when the number of audio channels matches the number of sound card output channels.
- Audio output is incorrect when the number of channels of audio is greater than the number of output channels of the sound card.
- When the number of audio channels is less than the number of sound card output channels, the audio output may be correct or incorrect.
And then I made some attempts.For the first time I modified the sample rate parameter of the initialisation function and tested it.
Here is a part of my code:
DWORD CALLBACK WasapiProc(void* buffer,DWORD length,void* user)
{
int len =0;
len=BASS_ChannelGetData(g_chan,buffer,length);
float* ptr=(float*)buffer;
float val = BASS_WASAPI_GetVolume(BASS_WASAPI_CURVE_WINDOWS);
for(size_t i=0,i<length/4;i++)
{
ptr[i] *= val;
}
if(len<0)
{
if(!BASS_WASAPI_GetData(NULL,BASS_DATA_AVAILABLE)
return 0;
}
return len;
}
void PlayMusic()
{
if(BASS_WASAPI_IsStarted())
{
BASS_WASAPI_Stop(FALSE);
}
if(!BASS_WASAPI_Start())
{
int err=BASS_ErrorGetCode();
}
}
void OpenMusic()
{
BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD,0);
BASS_Init(0,48000,0,0,NULL);
if(!BASS_WASAPI_Init(-1,44100,16,BASS_WASAPI_AUTOFORMAT | BASS_WASAPI_WASAPI_EXCLUSIVE,0.01,0.0,WasapiProc,NULL))
{
int err=BASS_ErrorGetCode();
}
if(BASS_WASAPI_Start())
{
TRACE(“start audio! \n”);
}
DWORD chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE);
}
void main()
{
OpenMusic();
PlayMusic();
}
In this code, I used a sound card with 4 output channels for testing, and the test results are as follows:
- The format of the audio:8 channels, 48000Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3 4 output channel no sound.
- The format of the audio:6 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3 4 output channel no sound.
- The format of the audio:2 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds correct,3 4 output channel no sound.
With the above results,
1.it can be seen that the audio output is correct only when the number of audio channels is less than the number of sound card output channels and the audio sampling rate is consistent with the initialization sampling rate.
2. I also found that with 8-channel audio or 6-channel audio, only 2 channels of audio can be output, and each channel does not sound independent and has noise.
Thus,I guessed that the error was related to the initialization parameters, so I made adjustments to the OpenMusic function in the code.
Here is the updated code:
void OpenMusic()
{
BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD,0);
BASS_Init(0,48000,0,0,NULL);
//Create a stream first and then initialize it
DWORD chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE);
BASS_CHANNELINFO info;
BASS_ChannelGetInfo(chan,&info);
WORD wchan;
DWORD dwSamplePerSec;
switch(info.ctype)
{
case BASS_CTYPE_STREAM_WAV:
case BASS_CTYPE_STREAM_WAV_FLOAT:
case BASS_CTYPE_STREAM_WAV_PCM:
{
const WAVEFORMATEX* wf = (const WAVEFORMATEX*)BASS_ChannelGetTags(chan,BASS_TAG_WAVEFORMAT);
wchan = wf->nChannels;
dwSamplePerSec = wf->nSamplePerSec;
}
break;
default:
{
wchan = info.chans;
dwSamplePerSec = info.freq;
}
break;
}
//FreeWasapi before initialization
BASS_WASAPI_Free();
//Initialization
if(!BASS_WASAPI_Init(-1,dwSamplePerSec,wchan,BASS_WASAPI_AUTOFORMAT | BASS_WASAPI_WASAPI_EXCLUSIVE,0.01,0.0,WasapiProc,NULL))
{
int err=BASS_ErrorGetCode();
}
//Start
if(BASS_WASAPI_Start())
{
TRACE(“start audio play! \n”);
}
}
void main()
{
OpenMusic();
PlayMusic();
}
I tested the updated code using the same sound card. The test results are as follows:
- The format of the audio:8 channels, 48000Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=48000 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3 4 output channel no sound.
- The format of the audio:6 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3 4 output channel no sound.
- The format of the audio:2 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds correct,3 4 output channel no sound.
As you can see from the results, there is little correlation with the parameters of the initialisation function.
It is still not possible to achieve: if the number of channels in the audio file is 8, and the number of output channels of the sound card is 4, the four output channels of the sound card will output the first four channels of the audio file independently.
I suspect it is related to the model of the sound card. Then, I ran a third test using three different models of sound cards.The test results are as follows:
- M-Audio:8 outputs
- The format of the audio:8 channels, 48000Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=48000 wi.chans = 8,sound card:1-8 output channel sounds correct.
- The format of the audio:6 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3-8 output channel no sound.
- The format of the audio:2 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds correct,3-8 output channel no sound.
- Cube Pro:4 outputs
- The format of the audio:8 channels, 48000Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=48000 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3 4 output channel no sound.
- The format of the audio:6 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds incorrect,3 4 output channel no sound.
- The format of the audio:2 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds correct,3 4 output channel no sound.
- TASCAM:8 outputs
- The format of the audio:8 channels, 48000Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=48000 wi.chans = 8,sound card:1-8 output channel sounds correct.
- The format of the audio:6 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 4,sound card:1-4 output channel sounds incorrect,5-8 output channel no sound.
- The format of the audio:2 channels, 44100Hz. Result:BASS_WASAPI_GetInfo(&wi) wi.freq=44100 wi.chans = 2,sound card:1 2 output channel sounds correct,3-8 output channel no sound.
From this result, two conclusions can be drawn:
1. when the number of audio channels is the same as the number of output channels of the sound card, each channel of the audio independently outputs the right sound
2. When the audio is stereo, as long as the number of output channels of the sound card is greater than or equal to 2, the audio can be output correctly.
Despite many tests, I still can't get the relevant information to make the sound output correctly when the number of output channels of the sound card doesn't match the number of audio output channels.
I want to know if the logic of the code is correct?Did I miss some important functions that were not called, resulting in incorrect audio output?
Looking forward to your reply.
Best Regards!