📄 rectest.c
字号:
/*
BASS recording example
Copyright (c) 2002-2008 Un4seen Developments Ltd.
*/
#include <windows.h>
#include <commctrl.h>
#include <stdlib.h>
#include <stdio.h>
#include "bass.h"
HWND win=NULL;
#define BUFSTEP 200000 // memory allocation unit
int input; // current input source
char *recbuf=NULL; // recording buffer
DWORD reclen; // recording length
HRECORD rchan=0; // recording channel
HSTREAM chan=0; // playback channel
// display error messages
void Error(const char *es)
{
char mes[200];
sprintf(mes,"%s\n(error code: %d)",es,BASS_ErrorGetCode());
MessageBox(win,mes,0,0);
}
// messaging macros
#define MESS(id,m,w,l) SendDlgItemMessage(win,id,m,(WPARAM)(w),(LPARAM)(l))
#define DLGITEM(id) GetDlgItem(win,id)
// buffer the recorded data
BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user)
{
// increase buffer size if needed
if ((reclen%BUFSTEP)+length>=BUFSTEP) {
recbuf=realloc(recbuf,((reclen+length)/BUFSTEP+1)*BUFSTEP);
if (!recbuf) {
rchan=0;
Error("Out of memory!");
MESS(10,WM_SETTEXT,0,"Record");
return FALSE; // stop recording
}
}
// buffer the data
memcpy(recbuf+reclen,buffer,length);
reclen+=length;
return TRUE; // continue recording
}
void StartRecording()
{
WAVEFORMATEX *wf;
if (recbuf) { // free old recording
BASS_StreamFree(chan);
chan=0;
free(recbuf);
recbuf=NULL;
EnableWindow(DLGITEM(11),FALSE);
EnableWindow(DLGITEM(12),FALSE);
// close output device before recording incase of half-duplex device
BASS_Free();
}
// allocate initial buffer and make space for WAVE header
recbuf=malloc(BUFSTEP);
reclen=44;
// fill the WAVE header
memcpy(recbuf,"RIFF\0\0\0\0WAVEfmt \20\0\0\0",20);
memcpy(recbuf+36,"data\0\0\0\0",8);
wf=(WAVEFORMATEX*)(recbuf+20);
wf->wFormatTag=1;
wf->nChannels=2;
wf->wBitsPerSample=16;
wf->nSamplesPerSec=44100;
wf->nBlockAlign=wf->nChannels*wf->wBitsPerSample/8;
wf->nAvgBytesPerSec=wf->nSamplesPerSec*wf->nBlockAlign;
// start recording @ 44100hz 16-bit stereo
if (!(rchan=BASS_RecordStart(44100,2,0,&RecordingCallback,0))) {
Error("Couldn't start recording");
free(recbuf);
recbuf=0;
return;
}
MESS(10,WM_SETTEXT,0,"Stop");
}
void StopRecording()
{
BASS_ChannelStop(rchan);
rchan=0;
MESS(10,WM_SETTEXT,0,"Record");
// complete the WAVE header
*(DWORD*)(recbuf+4)=reclen-8;
*(DWORD*)(recbuf+40)=reclen-44;
// enable "save" button
EnableWindow(DLGITEM(12),TRUE);
// setup output device (using default device)
if (!BASS_Init(-1,44100,0,win,NULL)) {
Error("Can't initialize output device");
return;
}
// create a stream from the recording
if (chan=BASS_StreamCreateFile(TRUE,recbuf,0,reclen,0))
EnableWindow(DLGITEM(11),TRUE); // enable "play" button
else
BASS_Free();
}
// write the recorded data to disk
void WriteToDisk()
{
FILE *fp;
char file[MAX_PATH]="";
OPENFILENAME ofn={0};
ofn.lStructSize=sizeof(ofn);
ofn.hwndOwner=win;
ofn.nMaxFile=MAX_PATH;
ofn.lpstrFile=file;
ofn.Flags=OFN_HIDEREADONLY|OFN_EXPLORER;
ofn.lpstrFilter="WAV files\0*.wav\0All files\0*.*\0\0";
ofn.lpstrDefExt="wav";
if (!GetSaveFileName(&ofn)) return;
if (!(fp=fopen(file,"wb"))) {
Error("Can't create the file");
return;
}
fwrite(recbuf,reclen,1,fp);
fclose(fp);
}
void UpdateInputInfo()
{
char *type;
float level;
int it=BASS_RecordGetInput(input,&level); // get info on the input
MESS(14,TBM_SETPOS,TRUE,level*100); // set the level slider
switch (it&BASS_INPUT_TYPE_MASK) {
case BASS_INPUT_TYPE_DIGITAL:
type="digital";
break;
case BASS_INPUT_TYPE_LINE:
type="line-in";
break;
case BASS_INPUT_TYPE_MIC:
type="microphone";
break;
case BASS_INPUT_TYPE_SYNTH:
type="midi synth";
break;
case BASS_INPUT_TYPE_CD:
type="analog cd";
break;
case BASS_INPUT_TYPE_PHONE:
type="telephone";
break;
case BASS_INPUT_TYPE_SPEAKER:
type="pc speaker";
break;
case BASS_INPUT_TYPE_WAVE:
type="wave/pcm";
break;
case BASS_INPUT_TYPE_AUX:
type="aux";
break;
case BASS_INPUT_TYPE_ANALOG:
type="analog";
break;
default:
type="undefined";
}
MESS(15,WM_SETTEXT,0,type); // display the type
}
BOOL CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l)
{
switch (m) {
case WM_TIMER:
{ // update the recording/playback counter
char text[30]="";
if (rchan) // recording
sprintf(text,"%I64d",BASS_ChannelGetPosition(rchan,BASS_POS_BYTE));
else if (chan) {
if (BASS_ChannelIsActive(chan)) // playing
sprintf(text,"%I64d / %I64d",BASS_ChannelGetPosition(chan,BASS_POS_BYTE),BASS_ChannelGetLength(chan,BASS_POS_BYTE));
else
sprintf(text,"%I64d",BASS_ChannelGetLength(chan,BASS_POS_BYTE));
}
MESS(20,WM_SETTEXT,0,text);
}
break;
case WM_COMMAND:
switch (LOWORD(w)) {
case IDCANCEL:
DestroyWindow(h);
break;
case 10:
if (!rchan)
StartRecording();
else
StopRecording();
break;
case 11:
BASS_ChannelPlay(chan,TRUE); // play the recorded data
break;
case 12:
WriteToDisk();
break;
case 13:
if (HIWORD(w)==CBN_SELCHANGE) { // input selection changed
int i;
input=MESS(13,CB_GETCURSEL,0,0); // get the selection
// enable the selected input
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
UpdateInputInfo(); // update info
}
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;
// setup recording device (using default device)
if (!BASS_RecordInit(-1)) {
Error("Can't initialize recording device");
DestroyWindow(win);
} else { // get list of inputs
int c;
const char *i;
MESS(14,TBM_SETRANGE,FALSE,MAKELONG(0,100)); // initialize input level slider
for (c=0;i=BASS_RecordGetInputName(c);c++) {
MESS(13,CB_ADDSTRING,0,i);
if (!(BASS_RecordGetInput(c,NULL)&BASS_INPUT_OFF)) { // this 1 is currently "on"
input=c;
MESS(13,CB_SETCURSEL,input,0);
UpdateInputInfo(); // display info
}
}
SetTimer(h,0,200,0); // timer to update the position display
return 1;
}
break;
case WM_DESTROY:
// release all BASS stuff
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -