// window procedure
LRESULT CALLBACK 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);
}
Exemple #2
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, &param); // apply the level change
    return true;
}
BOOL CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l)
{
	switch (m) {
		case WM_TIMER:
			{ // update the recording/playback counter
				wchar_t text[30]=L"";
				if (rchan) // recording
					wsprintf(text,L"%I64d",BASS_ChannelGetPosition(rchan,BASS_POS_BYTE));
				else if (chan) {
					if (BASS_ChannelIsActive(chan)) // playing
						wsprintf(text,L"%I64d / %I64d",BASS_ChannelGetPosition(chan,BASS_POS_BYTE),BASS_ChannelGetLength(chan,BASS_POS_BYTE));
					else
						wsprintf(text,L"%I64d",BASS_ChannelGetLength(chan,BASS_POS_BYTE));
				}
				MESS(20,WM_SETTEXT,0,text);
				{ // display free disk space
					ULARGE_INTEGER space;
					if (GetDiskFreeSpaceEx(NULL,&space,NULL,NULL)) {
						wsprintf(text,L"%I64d",space.QuadPart);
						MESS(21,WM_SETTEXT,0,text);
					}
				}
			}
			break;

		case WM_COMMAND:
			switch (LOWORD(w)) {
				case IDOK:
				case IDCANCEL:
					EndDialog(h,LOWORD(w));
					break;
				case 10:
					if (!rchan)
						StartRecording();
					else
						StopRecording();
					break;
				case 11:
					BASS_ChannelPlay(chan,TRUE); // play the recorded data
					break;
			}
			break;

		case WM_INITDIALOG:
			win=h;
			// setup recording device (using default device)
			if (!BASS_RecordInit(-1)) {
				Error(L"Can't initialize recording device");
				EndDialog(h,0);
				return 0;
			}
			{ // go full screen
				SHINITDLGINFO shidi;
				shidi.dwMask = SHIDIM_FLAGS;
				shidi.dwFlags = SHIDIF_DONEBUTTON|SHIDIF_SIZEDLGFULLSCREEN|SHIDIF_EMPTYMENU|SHIDIF_SIPDOWN;
				shidi.hDlg = h;
				SHInitDialog(&shidi);
			}
			SetTimer(h,1,200,0); // timer to update the position display
			return 1;

		case WM_DESTROY:
			// release all BASS stuff
			BASS_RecordFree();
			BASS_Free();
			break;
	}
	return 0;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}