Author Topic: BASS_ChannelPlay() Stopped working  (Read 437 times)

andrewshi

  • Posts: 6
BASS_ChannelPlay() Stopped working
« on: 11 Jul '17 - 06:08 »
     Hi, I just wrote a small program that transfers sound captured from microphone directly to speaker. The program simply keep doing BASS_StreamPutData in a callback function. There are also two checkboxes that enables/disables BASS_ChannelPlay(channel, FALSE) and StreamPutData. However, when I pause the channel after the playback stream is stalled, I found the program no longer working anymore (the program doesn't play anything after BASS_ChannelPlay is called). I added some breakpoints to track down where the problem is and found out that BASS_StreamPutData execute as expected but BASS_ChannelGetData(chan, NULL, BASS_DATA_AVAILABLE) stays at 0. Can anyone help me on that? I really don't know what the problem is. Thanks in advance.

Ian @ un4seen

  • Administrator
  • Posts: 20401
Re: BASS_ChannelPlay() Stopped working
« Reply #1 on: 11 Jul '17 - 17:24 »
Is the BASS_ChannelPlay call reporting success in its return value? If not, please confirm what the error code is (using BASS_ErrorGetCode). If that's fine, also confirm that BASS_StreamPutData is still being called successfully when the problem happens.

andrewshi

  • Posts: 6
Re: BASS_ChannelPlay() Stopped working
« Reply #2 on: 11 Jul '17 - 21:24 »
BASS_ChannelPlay call report success.
Code: [Select]
if(!BASS_ChannelPlay(chan, FALSE))MessageBox(0, "Error Occurred", 0, MB_ICONERROR);Every single call I made with BASS audio library is like that, and no error is reported throughout.

andrewshi

  • Posts: 6
Re: BASS_ChannelPlay() Stopped working
« Reply #3 on: 11 Jul '17 - 21:26 »
Interestingly, when I call BASS_ChannelPlay(chan, TRUE), suddenly the channel is able to take new data. However this would discard the data that had already been pushed to the stream.

Ian @ un4seen

  • Administrator
  • Posts: 20401
Re: BASS_ChannelPlay() Stopped working
« Reply #4 on: 12 Jul '17 - 17:05 »
In the case of the BASS_StreamPutData call, are you checking for a -1 return value? That is what it will return upon failure. If that's fine too, can you please provide some test code to reproduce the problem with?

andrewshi

  • Posts: 6
Re: BASS_ChannelPlay() Stopped working
« Reply #5 on: 12 Jul '17 - 20:14 »
Yes I'm aware that the error code for BASS_StreamPutData is -1. Here is my full code (modified from the sample BASS provided) Should I provide .rc file as well?
You can reproduce the problem simply by toggling BASS_ChannelPlay on and off (just to pause it while at stall state). Then the channel's play back buffer should stop taking data from queued data no matter what. It will not work unless you call BASS_ChannelPlay(channel, TRUE) However this will discard all data that has previously been pushed to the stream.
Code: [Select]
/*
BASS full-duplex test
Copyright (c) 2002-2014 Un4seen Developments Ltd.
*/
#include <windows.h>
#include <iostream>
#include <commctrl.h>
#include <stdio.h>
#include <math.h>
#include "bass.h"
#pragma comment( lib, "comctl32.lib " )

HWND win = NULL;

#define MESS(id,m,w,l) SendDlgItemMessage(win,id,m,(WPARAM)(w),(LPARAM)(l))

HRECORD rchan; // recording channel
HSTREAM chan; // playback stream
HFX fx[4] = { 0 }; // FX handles
int input; // current input source

#define SAMPLERATE 44100

DWORD rate; // current output rate
DWORD prebuf; // prebuffering amount

bool counter = TRUE;
bool keeppushing = FALSE;
int pushedsize = 0;

void Error(const char *es)
{
char mes[200];
sprintf(mes, "%s\n(error code: %d)", es, BASS_ErrorGetCode());
MessageBox(win, mes, 0, 0);
}

BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user)
{
DWORD bl;
if (keeppushing) {
if(BASS_StreamPutData(chan, buffer, length)==-1) Error("Error While Pushing");
}
return TRUE;
}

BOOL Initialize()
{
BASS_INFO bi;

BASS_SetConfig(BASS_CONFIG_VISTA_TRUEPOS, 0); // allows lower latency on Vista and newer

  // initialize default output device (and measure latency)
if (!BASS_Init(-1, SAMPLERATE, BASS_DEVICE_LATENCY, win, NULL)) {
Error("Can't initialize output");
return FALSE;
}

// create a stream to play the recording
chan = BASS_StreamCreate(SAMPLERATE, 2, 0, STREAMPROC_PUSH, 0);

  // start recording with 10ms period
if (!BASS_RecordInit(-1) || !(rchan = BASS_RecordStart(SAMPLERATE, 2, MAKELONG(0, 10), RecordingCallback, 0))) {
BASS_RecordFree();
BASS_Free();
Error("Can't initialize recording");
return FALSE;
}

{ // get list of inputs
int c;
const char *i;
for (c = 0; i = BASS_RecordGetInputName(c); c++) {
float level;
MESS(10, CB_ADDSTRING, 0, i);
if (!(BASS_RecordGetInput(c, &level)&BASS_INPUT_OFF)) { // this 1 is currently "on"
input = c;
MESS(10, CB_SETCURSEL, input, 0);
MESS(11, TBM_SETPOS, TRUE, level * 100); // set level slider
}
}
}

return TRUE;
}

INT_PTR CALLBACK dialogproc(HWND h, UINT m, WPARAM w, LPARAM l)
{
switch (m) {
case WM_TIMER:
{ //Ignore that, use for debug data display
char buf[20];
int text = BASS_ChannelIsActive(chan);
sprintf(buf, "%d", text);
MESS(15, WM_SETTEXT, 0, buf);
}
break;

case WM_COMMAND:
switch (LOWORD(w)) {
case IDCANCEL:
DestroyWindow(h);
break;
case 10:
if (HIWORD(w) == CBN_SELCHANGE) { // input selection changed
int i;
float level;
input = MESS(10, CB_GETCURSEL, 0, 0); // get the selection
for (i = 0; BASS_RecordSetInput(i, BASS_INPUT_OFF, -1); i++); // 1st disable all inputs, then...
BASS_RecordSetInput(input, BASS_INPUT_ON, -1); // enable the selected input
BASS_RecordGetInput(input, &level); // get the level
MESS(11, TBM_SETPOS, TRUE, level * 100);
}
break;
case 20: //Toggle BASS_StreamPutData()
if (keeppushing == FALSE) {
keeppushing = true;
}
else
{
keeppushing = false;
}
break;
case 22: // Toggle ChannelPlay
if (fx[2] == 0) {
if(!BASS_ChannelPlay(chan, FALSE))
MessageBox(0, "Error Occurred", 0, MB_ICONERROR);
fx[2] = 1;
}
else {
if (!BASS_ChannelPause(chan))
Error("Pause Error");
fx[2] = 0;
}
break;
}
break;


case WM_HSCROLL:
if (l) { // set input source level
float level = SendMessage((HWND)l, TBM_GETPOS, 0, 0) / 100.f;
if (!BASS_RecordSetInput(input, 0, level)) // failed to set input level
BASS_RecordSetInput(-1, 0, level); // try master level instead
}
break;

case WM_INITDIALOG:
win = h;
MESS(11, TBM_SETRANGE, FALSE, MAKELONG(0, 100)); // initialize input level slider
if (!Initialize()) {
DestroyWindow(win);
break;
}
SetTimer(h, 1, 250, NULL);
return 1;

case WM_DESTROY:
KillTimer(h, 1);
// release it all
BASS_RecordFree();
BASS_Free();
break;
}
return 0;
}

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// check the correct BASS was loaded
if (HIWORD(BASS_GetVersion()) != BASSVERSION) {
MessageBox(0, "An incorrect version of BASS.DLL was loaded", 0, MB_ICONERROR);
return 0;
}

{ // enable trackbar support (for the level control)
INITCOMMONCONTROLSEX cc = { sizeof(cc),ICC_BAR_CLASSES };
InitCommonControlsEx(&cc);
}

DialogBox(hInstance, (char*)1000, 0, &dialogproc);

return 0;
}
« Last Edit: 13 Jul '17 - 04:38 by andrewshi »

Ian @ un4seen

  • Administrator
  • Posts: 20401
Re: BASS_ChannelPlay() Stopped working
« Reply #6 on: 13 Jul '17 - 17:42 »
Thanks, I was able to reproduce the problem you described with your test code. Here's an update that should fix it:

   www.un4seen.com/stuff/bass.zip

Let me know if you still see the problem happen.

andrewshi

  • Posts: 6
Re: BASS_ChannelPlay() Stopped working
« Reply #7 on: 13 Jul '17 - 20:51 »
Thank you. The problem is solved using the updated library. Will the library file on BASS website be updated as well?

Ian @ un4seen

  • Administrator
  • Posts: 20401
Re: BASS_ChannelPlay() Stopped working
« Reply #8 on: 14 Jul '17 - 13:19 »
Good to hear that the update is working well for you. The fix will indeed be in the next release on the BASS page. You can use the update posted above in the meantime (it is a "release" build).

andrewshi

  • Posts: 6
Re: BASS_ChannelPlay() Stopped working
« Reply #9 on: 15 Jul '17 - 01:18 »
Thank you so much. I really appreciate your help and works you've done to make this community a better place.