This is a sample program I downloaded from un4seen.com, bass audio library sample. However, when I try to build it no window is shown although it successfully generates the executable file and runs. I tried to add few breakpoints and figured that the program ends immediatly after it called Dialogbox() and didn't do callback. Can anyone tell me what the problem is?
#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 chunk; // recording chunk size
int input; // current input source
int latency = 0; // current latency
#define SAMPLERATE 44100
#define ADJUSTRATE // adjust the output rate (in case input and output devices are going at slightly different speeds)
DWORD rate; // current output rate
DWORD prebuf; // prebuffering amount
#ifdef ADJUSTRATE
DWORD targbuf; // target buffer level
DWORD prevbuf; // previous buffer level/threshold
#endif
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;
BASS_StreamPutData(chan, buffer, length); // feed recorded data to output stream
bl = BASS_ChannelGetData(chan, NULL, BASS_DATA_AVAILABLE); // get output buffer level
if (prebuf) { // prebuffering
if (bl >= prebuf + length) { // gone 1 block past the prebuffering target
#ifdef ADJUSTRATE
targbuf = bl; // target the current level
prevbuf = 0;
#endif
prebuf = 0; // finished prebuffering
BASS_ChannelPlay(chan, FALSE); // start the output
}
}
else { // playing
#ifdef ADJUSTRATE
if (bl<targbuf) { // buffer level is below target, slow down...
rate--;
BASS_ChannelSetAttribute(chan, BASS_ATTRIB_FREQ, rate);
prevbuf = 0;
}
else if (bl>targbuf && bl >= prevbuf) { // buffer level is high and not falling, speed up...
rate++;
BASS_ChannelSetAttribute(chan, BASS_ATTRIB_FREQ, rate);
prevbuf = bl;
}
#endif
}
return TRUE; // continue recording
}
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;
}
BASS_GetInfo(&bi);
if (bi.dsver<8) { // no DX8, so disable effect buttons
EnableWindow(GetDlgItem(win, 20), FALSE);
EnableWindow(GetDlgItem(win, 21), FALSE);
EnableWindow(GetDlgItem(win, 22), FALSE);
EnableWindow(GetDlgItem(win, 23), FALSE);
}
// create a stream to play the recording
chan = BASS_StreamCreate(SAMPLERATE, 2, 0, STREAMPROC_PUSH, 0);
rate = SAMPLERATE;
prebuf = BASS_ChannelSeconds2Bytes(chan, bi.minbuf / 1000.f); // prebuffer at least "minbuf" worth of data
// 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:
{ // display current latency (input+output buffer level)
char buf[20];
latency = (latency * 3 + BASS_ChannelGetData(chan, NULL, BASS_DATA_AVAILABLE)
+ BASS_ChannelGetData(rchan, NULL, BASS_DATA_AVAILABLE)) / 4;
sprintf(buf, "%d", (int)(BASS_ChannelBytes2Seconds(chan, latency) * 1000));
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 chorus
if (fx[0]) {
BASS_ChannelRemoveFX(chan, fx[0]);
fx[0] = 0;
}
else
fx[0] = BASS_ChannelSetFX(chan, BASS_FX_DX8_CHORUS, 0);
break;
case 21: // toggle gargle
if (fx[1]) {
BASS_ChannelRemoveFX(chan, fx[1]);
fx[1] = 0;
}
else
fx[1] = BASS_ChannelSetFX(chan, BASS_FX_DX8_GARGLE, 0);
break;
case 22: // toggle reverb
if (fx[2]) {
BASS_ChannelRemoveFX(chan, fx[2]);
fx[2] = 0;
}
else
fx[2] = BASS_ChannelSetFX(chan, BASS_FX_DX8_REVERB, 0);
break;
case 23: // toggle flanger
if (fx[3]) {
BASS_ChannelRemoveFX(chan, fx[3]);
fx[3] = 0;
}
else
fx[3] = BASS_ChannelSetFX(chan, BASS_FX_DX8_FLANGER, 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
MessageBox(win,
"Do not set the input to 'WAVE' / 'What you hear' (etc...) with\n"
"the level set high, as that is likely to result in nasty feedback.\n",
"Feedback warning", MB_ICONWARNING);
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;
}
This line:
DialogBox(hInstance, (char*)1000, 0, &dialogproc);
is likely failing because the resource (1000) is missing.
The second parameter is resource ID - but to a resource that isn't linked in. That is, your linked in .res (compiled from .rc file) should a have a dialog template defined with an ID of 1000. The dialog template defines the layout of the dialog, buttons, controls and positions of each. Are you sure you aren't missing a .rc
file that came with that sample .cpp
file? If you have that rc file, add it to your Visual Studio project.
What's odd is that resource IDs (and command IDs of dialog controls) are rarely hardcoded numbers in code. You typically have a resource.h
file that that defines #define IDD_DIALOG1 1000
or something similar. It's included by both the resource.rc
file as well as the C/C++ code.
Update - I suspect you are trying to compile the basstest
project that comes with the download of bass24.zip. But you only compiled the .c file, and not the corresponding basstest.rc file.