void TForm1::StartRecording() { run=1; WAVEFORMATEX *wf; if (recbuf) { // free old recording BASS_StreamFree(chan); chan=0; free(recbuf); recbuf=NULL; // close output device before recording incase of half-duplex device BASS_Free(); } // allocate initial buffer and make space for WAVE header recbuf=(char *)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=CHANS; wf->wBitsPerSample=16; wf->nSamplesPerSec=FREQ; wf->nBlockAlign=wf->nChannels*wf->wBitsPerSample/8; wf->nAvgBytesPerSec=wf->nSamplesPerSec*wf->nBlockAlign; // start recording rchan=BASS_RecordStart(FREQ,CHANS,0,RecordingCallback,0); if (!rchan) { //Error("Couldn't start recording"); free(recbuf); recbuf=0; return; } //MESS(10,WM_SETTEXT,0,"Stop"); }
/** * @brief Starts the record and set default confuration for audio file. If start record is failure free RECBUF is comming. */ void Widget::startRecording() { WAVEFORMATEX *wf; if (recbuf) { // free old recording; BASS_StreamFree(chan); chan=0; free(recbuf); recbuf=NULL; //ui->pushButton_2->setEnabled(false); ui->pushButton_3->setEnabled(false); // close output device before recording incase of half-duplex device; BASS_Free(); } // allocate initial buffer and make space for WAVE header; recbuf=(char*)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 32-bit stereo; if (!(rchan=BASS_RecordStart(44100,2,0,&RecordingCallback,0))) { QDEBUG(BASS_ErrorGetCode()); Error("Couldn't start recording"); free(recbuf); recbuf=0; return; } ui->pushButton->setEnabled(false); }
void StartRecording() { WAVEFORMATEX wf; if (chan) { // free old recording BASS_StreamFree(chan); chan=0; EnableWindow(DLGITEM(11),FALSE); // close output device before recording incase of half-duplex device BASS_Free(); } // open the output file if (!(rfp=_wfopen(L"bass.wav",L"wb"))) { Error(L"Can't create the file"); return; } // write the WAVE header fwrite("RIFF\0\0\0\0WAVEfmt \20\0\0\0",1,20,rfp); wf.wFormatTag=WAVE_FORMAT_PCM; wf.nChannels=1; wf.wBitsPerSample=16; wf.nSamplesPerSec=44100; wf.nBlockAlign=wf.nChannels*wf.wBitsPerSample/8; wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign; fwrite(&wf,1,16,rfp); fwrite("data\0\0\0\0",1,8,rfp); // start recording @ 44100hz 16-bit mono if (!(rchan=BASS_RecordStart(44100,1,0,&RecordingCallback,0))) { Error(L"Couldn't start recording"); fclose(rfp); return; } MESS(10,WM_SETTEXT,0,L"Stop"); }
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"); }
static BOOL Initialize() { BASS_INFO bi; // initialize output, get latency if (!BASS_Init(-1,44100,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(44100,2,0,STREAMPROC_PUSH,0); // start recording with 10ms period if (!BASS_RecordInit(-1) || !(rchan=BASS_RecordStart(44100,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 } } } { // prebuffer at least "minbuf" amount of data before starting playback DWORD prebuf=BASS_ChannelSeconds2Bytes(chan,bi.minbuf/1000.f); while (BASS_ChannelGetData(chan,NULL,BASS_DATA_AVAILABLE)<prebuf) Sleep(1); } BASS_ChannelPlay(chan,FALSE); return TRUE; }
// window procedure long FAR PASCAL SpectrumWindowProc(HWND h, UINT m, WPARAM w, LPARAM l) { switch (m) { case WM_PAINT: if (GetUpdateRect(h,0,0)) { PAINTSTRUCT p; HDC dc; if (!(dc=BeginPaint(h,&p))) return 0; BitBlt(dc,0,0,SPECWIDTH,SPECHEIGHT,specdc,0,0,SRCCOPY); EndPaint(h,&p); } return 0; case WM_LBUTTONUP: specmode=(specmode+1)%4; // swap spectrum mode memset(specbuf,0,SPECWIDTH*SPECHEIGHT); // clear display return 0; case WM_CREATE: win=h; // initialize BASS recording (default device) if (!BASS_RecordInit(-1)) { Error("Can't initialize device"); return -1; } // start recording (44100hz mono 16-bit) if (!(chan=BASS_RecordStart(44100,1,0,&DuffRecording,0))) { Error("Can't start recording"); return -1; } { // create bitmap to draw spectrum in (8 bit for easy updating) BYTE data[2000]={0}; BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data; RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh)); int a; bh->biSize=sizeof(*bh); bh->biWidth=SPECWIDTH; bh->biHeight=SPECHEIGHT; // upside down (line 0=bottom) bh->biPlanes=1; bh->biBitCount=8; bh->biClrUsed=bh->biClrImportant=256; // setup palette for (a=1;a<128;a++) { pal[a].rgbGreen=256-2*a; pal[a].rgbRed=2*a; } for (a=0;a<32;a++) { pal[128+a].rgbBlue=8*a; pal[128+32+a].rgbBlue=255; pal[128+32+a].rgbRed=8*a; pal[128+64+a].rgbRed=255; pal[128+64+a].rgbBlue=8*(31-a); pal[128+64+a].rgbGreen=8*a; pal[128+96+a].rgbRed=255; pal[128+96+a].rgbGreen=255; pal[128+96+a].rgbBlue=8*a; } // create the bitmap specbmp=CreateDIBSection(0,(BITMAPINFO*)bh,DIB_RGB_COLORS,(void**)&specbuf,NULL,0); specdc=CreateCompatibleDC(0); SelectObject(specdc,specbmp); } // setup update timer (40hz) timer=timeSetEvent(25,25,(LPTIMECALLBACK)&UpdateSpectrum,0,TIME_PERIODIC); break; case WM_DESTROY: if (timer) timeKillEvent(timer); BASS_RecordFree(); if (specdc) DeleteDC(specdc); if (specbmp) DeleteObject(specbmp); PostQuitMessage(0); break; } return DefWindowProc(h, m, w, l); }
INT_PTR 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,"%d",reclen-44); 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(); } break; case 16: if (HIWORD(w)==CBN_SELCHANGE) { // device selection changed int i=MESS(16,CB_GETCURSEL,0,0); // get the selection // initialize the selected device if (InitDevice(i)) { if (rchan) { // continue recording on the new device... HRECORD newrchan=BASS_RecordStart(FREQ,CHANS,0,RecordingCallback,0); if (!newrchan) Error("Couldn't start recording"); else rchan=newrchan; } } } 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(14,TBM_SETRANGE,FALSE,MAKELONG(0,100)); { // get list of recording devices int c,def; BASS_DEVICEINFO di; for (c=0;BASS_RecordGetDeviceInfo(c,&di);c++) { MESS(16,CB_ADDSTRING,0,di.name); if (di.flags&BASS_DEVICE_DEFAULT) { // got the default device MESS(16,CB_SETCURSEL,c,0); def=c; } } InitDevice(def); // initialize default recording device } SetTimer(h,0,200,0); // timer to update the position display return 1; case WM_DESTROY: // release all BASS stuff BASS_RecordFree(); BASS_Free(); break; } return 0; }
bool BassPlayer::startRecord(const wchar_t* file) { if (m_record_params) return error(L"Already recording. First stop and start new."); int device = getMicrophoneDevice(); if (device == -1) return error(L"Microphone not found."); if (!BASS_RecordInit(device)) return error_bass(L"Can't initialize microphone.", NULL); HANDLE hfile = CreateFile(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hfile == INVALID_HANDLE_VALUE) { std::wstring message(L"Can't open file to writing :"); message.append(file); return error(message.c_str()); } // write wav header WAVEFORMATEX wf; wf.wFormatTag = WAVE_FORMAT_PCM; wf.wBitsPerSample = 16; wf.nChannels = LOWORD(m_chans_record); wf.nSamplesPerSec = m_freq_record; wf.nBlockAlign = wf.nChannels*wf.wBitsPerSample/8; wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; wf.cbSize = 0; DWORD wf_size = sizeof(WAVEFORMATEX) - sizeof(WORD); DWORD headerSize = 20 + wf_size + 8; unsigned char* header = new unsigned char [headerSize]; memcpy(header, "RIFF\0\0\0\0WAVEfmt \20\0\0\0", 20); memcpy(header+20, &wf, wf_size); memcpy(header+20+wf_size, "data\0\0\0\0", 8); DWORD written = 0; if (!WriteFile(hfile, header, headerSize, &written, NULL) || written != headerSize) { CloseHandle(hfile); DeleteFile(file); std::wstring message(L"Can't start writing :"); message.append(file); return error(message.c_str()); } m_record_params = new RecordParams; m_record_params->hfile = hfile; m_record_params->recording = TRUE; m_record = BASS_RecordStart(m_freq_record, m_chans_record, 0, MyRecordProc, m_record_params); if (!m_record) { delete m_record_params; m_record_params = NULL; CloseHandle(hfile); DeleteFile(file); return error_bass(L"Can't start recording.", NULL); } // set a volume effect on the recording channel HFX volfx = BASS_ChannelSetFX(m_record, BASS_FX_BFX_VOLUME, 0); BASS_BFX_VOLUME param; param.lChannel = 0; // global volume control param.fVolume = volume_ToFloat(m_sensivity_record); // recording volume BASS_FXSetParameters(volfx, ¶m); // apply the level change return true; }
int main(int argc, char **argv) { std::cerr << "Start\n"; HANDLE hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "sc_shared"); if(hMapFile == NULL) { return -10; } Shared *shared; shared = (Shared*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*shared)); if(shared == NULL) { return -11; } std::string recDev = getopt(argc, argv, "--recDev="); //int sc_version = std::stoi(getopt(argc, argv, "--version=")); BASS_SetConfig(BASS_CONFIG_UNICODE, true); int recDevNo = -1; BASS_DEVICEINFO info; for(int i=0; BASS_RecordGetDeviceInfo(i, &info); i++) { if(recDev == std::to_string(hash_str(info.name))) { recDevNo = i; break; } } if(!BASS_RecordInit(recDevNo)) { int code = BASS_ErrorGetCode(); std::string text = "BASS error: " + std::to_string(code); if(code == 23) text += "\nProblem with device: \"" + recDev + "\"!"; std::cerr << text << "\n"; return -1; } int sampleRate = std::stoi(getopt(argc, argv, "--samplerate=")); int channels = std::stoi(getopt(argc, argv, "--channels=")); recStream = BASS_RecordStart(sampleRate, channels, 0, RecordProc, nullptr); #ifdef _WIN32 std::string lameBin = "lame.exe"; #else std::string lameBin = "lame"; #endif HENCODE encoder = BASS_Encode_Start(recStream, (lameBin + " -b " + getopt(argc, argv, "--bitrate=") + " -").c_str(), 0, NULL, 0); bool ok = BASS_Encode_CastInit(encoder, getopt(argc, argv, "--url=").c_str(), getopt(argc, argv, "--password="******"--bitrate=")), FALSE); if(!ok) { int code = BASS_ErrorGetCode(); std::string text = "BASS error: " + std::to_string(code); std::cerr << text << "\n"; return -2; } std::cerr << "OK\n"; while(!shared->end) { if(BASS_Encode_IsActive(encoder) != BASS_ACTIVE_PLAYING) { return -3; } BASS_CHANNELINFO info; if(BASS_ChannelGetInfo(recStream, &info)) { DWORD flags = info.chans == 1 ? BASS_LEVEL_MONO : BASS_LEVEL_STEREO; BASS_ChannelGetLevelEx(recStream, shared->levels, 0.035f, flags); } Sleep(35); } std::cerr << "End\n"; UnmapViewOfFile((LPCVOID)shared); CloseHandle(hMapFile); return 0; }