// scan the peaks void __cdecl ScanPeaks(void *p) { DWORD decoder=(DWORD)p; DWORD pos=0; float spp=BASS_ChannelBytes2Seconds(decoder,bpp); // seconds per pixel while (!killscan) { float peak[2]; if (spp>1) { // more than 1 second per pixel, break it down... float todo=spp; peak[1]=peak[0]=0; do { float level[2],step=(todo<1?todo:1); BASS_ChannelGetLevelEx(decoder,level,step,BASS_LEVEL_STEREO); // scan peaks if (peak[0]<level[0]) peak[0]=level[0]; if (peak[1]<level[1]) peak[1]=level[1]; todo-=step; } while (todo>0); } else BASS_ChannelGetLevelEx(decoder,peak,spp,BASS_LEVEL_STEREO); // scan peaks { DWORD a; for (a=0;a<peak[0]*(HEIGHT/2);a++) wavebuf[(HEIGHT/2-1-a)*WIDTH+pos]=1+a; // draw left peak for (a=0;a<peak[1]*(HEIGHT/2);a++) wavebuf[(HEIGHT/2+1+a)*WIDTH+pos]=1+a; // draw right peak } pos++; if (pos>=WIDTH) break; // reached end of display if (!BASS_ChannelIsActive(decoder)) break; // reached end of channel } if (!killscan) { DWORD size; BASS_ChannelSetPosition(decoder,(QWORD)-1,BASS_POS_BYTE|BASS_POS_SCAN); // build seek table (scan to end) size=BASS_ChannelGetAttributeEx(decoder,BASS_ATTRIB_SCANINFO,0,0); // get seek table size if (size) { // got it void *info=malloc(size); // allocate a buffer BASS_ChannelGetAttributeEx(decoder,BASS_ATTRIB_SCANINFO,info,size); // get the seek table BASS_ChannelSetAttributeEx(chan,BASS_ATTRIB_SCANINFO,info,size); // apply it to the playback channel free(info); } } BASS_StreamFree(decoder); // free the decoder scanthread=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; }