Example #1
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
}
Example #2
0
/**
 * @brief No incoming parameters. Get data from RCHAN. Creating the stream file. If BASS_StreamCreateFile is failure colled BASS_Free().
 * @param No params
 */
void Widget::stopRecording()
{
    if (BASS_ChannelGetData(rchan, this->fft, BASS_DATA_FFT1024 | BASS_DATA_FFT_COMPLEX) == -1) {
        QDEBUG("Cannot get recbuf from rchan");
        QDEBUG(BASS_ErrorGetCode());
    }

    BASS_ChannelStop(rchan);
    rchan=0;
    ui->pushButton->setText(tr("Record"));
    // complete the WAVE header
    *(DWORD*)(recbuf+4)=reclen-8;
    *(DWORD*)(recbuf+40)=reclen-44;
    // enable "save" button
    ui->pushButton_3->setEnabled(true);
    // setup output device (using default device)
    if (!BASS_Init(-1,44100,0,NULL,NULL)) {
        QDEBUG(BASS_ErrorGetCode());
        QDEBUG("Can't initialize output device");
        return;
    }
    // create a stream from the recording
    if (chan=BASS_StreamCreateFile(TRUE,recbuf,0,reclen,BASS_SAMPLE_FLOAT)) {
        //ui->pushButton_2->setEnabled(true); // enable "play" button
    }
    else
        BASS_Free();
    ui->pushButton->setEnabled(true);
}
void Player::push(void *data, uint32_t size) {
    int buffered = BASS_ChannelGetData(_output, NULL, BASS_DATA_AVAILABLE);
    Log::msg("In buffer: %d - New: %d", buffered, size);
    
	if(BASS_StreamPutData(_output, data, size) == (DWORD)-1)
		Log::error("Bass Error: putting stream data failed: %s", GetBassStrError());
}
Example #4
0
bool BassPlayer::calcSpectrum(QList<QVector<float> > & result) {
    float fft[1024 * channels_count];
    BASS_ChannelGetData(chan, fft, BASS_DATA_FFT2048 | BASS_DATA_FFT_INDIVIDUAL | BASS_DATA_FFT_REMOVEDC);

    QVector<float> peaks;
    int b0 = 0, x, z, peakNum;

    for (x = 0; x < channels_count; x++)
        result.append(QVector<float>());

    for (x = 0; x < calcSpectrumBandsGroupCount(); x++) {
        peaks.fill(0, channels_count);

        int b1 = spectrumComplexPoints[x];

        for (; b0 < b1; b0++) {
            peakNum = b0 % channels_count;
            if (peaks[peakNum] < fft[b0])
                peaks[peakNum] = fft[b0];
        }

        for (z = 0; z < channels_count; z++)
            result[z].append(sqrt(peaks[z]));
    }

    return true;
}
Example #5
0
bool PlaybackWidget::getFFT(void *buffer)
{
    if(state == PLAYING
       && BASS_ChannelGetData(curchan, buffer, BASS_DATA_FFT8192) >= 0)
        return true;
    return false;
}
Example #6
0
float* CBassAudio::GetFFTData ( int iLength )
{
    if ( m_pSound )
    {
        long lFlags = BASS_DATA_FFT256;
        if ( iLength == 256 )
            lFlags = BASS_DATA_FFT256;
        else if ( iLength == 512 )
            lFlags = BASS_DATA_FFT512;
        else if ( iLength == 1024 )
            lFlags = BASS_DATA_FFT1024;
        else if ( iLength == 2048 )
            lFlags = BASS_DATA_FFT2048;
        else if ( iLength == 4096 )
            lFlags = BASS_DATA_FFT4096;
        else if ( iLength == 8192 )
            lFlags = BASS_DATA_FFT8192;
        else if ( iLength == 16384 )
            lFlags = BASS_DATA_FFT16384;
        else 
            return NULL;

        float* pData = new float[ iLength ];
        if ( BASS_ChannelGetData ( m_pSound, pData, lFlags ) != -1 )
            return pData;
        else
        {
            delete [] pData;
            return NULL;
        }
    }
    return NULL;
}
Example #7
0
void render::updateSounds() {
	float buffer[1024 * 4];
	BASS_ChannelGetData(sound_chan, buffer, -2147483645);
	
	num = 0.0f;
	for (int i = 0; i <= 15; i++)
		num += buffer[i];
	num *= (13.0f/15.0f);
}
Example #8
0
/* check that buffer has sufficient decoded data */
void CheckBuffer(BUFSTUFF *b, DWORD pos)
{
	if (pos>b->writepos) {
		int o=min(b->readposl,b->readposr);
		b->writepos-=o;
		memmove(b->buf,b->buf+o*2,b->writepos*4); // shift over used data
		b->readposl-=o;
		b->readposr-=o;
		pos-=o;
		// read upto requested position
		b->writepos+=BASS_ChannelGetData(b->dstr,b->buf+b->writepos*2,(pos-b->writepos)*4)/4;
	}
}
Example #9
0
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;
}
Example #10
0
unsigned int BassDecoder::fetch(Signal& left, Signal& right){
  if (_music)
  {
    DWORD readed=0;
    #if defined(LIBTOOLS_WINDOWS) && !defined(BASS_H)
    if (!BASS_ChannelGetData || ! BASS_ErrorGetCode) {
      std::cerr << "Error missing BASS_ChannelGetData or BASS_ErrorGetCode functions" << std::endl;
      return 0;
    }
    #endif
    
    
    readed=BASS_ChannelGetData((DWORD)_music, (void*)_samplesForSignals, _bytesFrame);

    if(readed==-1 && BASS_ErrorGetCode() == BASS_ERROR_ENDED) {
      left.reset();
      right.reset();
      _ended=true;
      return 0;
    }

    if (readed < _bytesFrame)
    {
      for (unsigned int i=readed; i< _bytesFrame ;i++)
        ((char*)_samplesForSignals)[i]=0;
    }
    const unsigned int signal_size=Signal::size;
    if (_infos.chans>=2)
    {
      unsigned int k=0;
		  for (unsigned int i=0; i < signal_size;)
		  {
			  left.samples[i]=_samplesForSignals[k++];
			  right.samples[i++]=_samplesForSignals[k++];
        k+=_infos.chans-2;
		  }
    }
    else if (_infos.chans==1) //mono
    {
      unsigned int k=0;
		  for (unsigned int i=0; i < signal_size;)
		  {
			  left.samples[i]=_samplesForSignals[k];
			  right.samples[i++]=_samplesForSignals[k++];
		  }
    }
    return readed/sizeof(sample);
  }
  return 0;
}
Example #11
0
HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size)
{
	DWORD _size, length, samples;
	HSAMPLE hs;
	HSTREAM hstrm;
	BASS_CHANNELINFO info;
	void *buffer, *data;

	if(hBass)
	{
		if(bSilent) return 1;

		if(size) { data=(void *)filename; _size=size; }
		else
		{
			data=Resource_Load(filename, &_size);
			if(!data) return NULL;
		}
	
		hs=BASS_SampleLoad(TRUE, data, 0, _size, 4, BASS_SAMPLE_OVER_VOL);
		if(!hs) {
			hstrm=BASS_StreamCreateFile(TRUE, data, 0, _size, BASS_STREAM_DECODE);
			if(hstrm) {
				length=(DWORD)BASS_ChannelGetLength(hstrm);
				BASS_ChannelGetInfo(hstrm, &info);
				samples=length;
				if(info.chans < 2) samples>>=1;
				if((info.flags & BASS_SAMPLE_8BITS) == 0) samples>>=1;
				buffer=BASS_SampleCreate(samples, info.freq, 2, 4, info.flags | BASS_SAMPLE_OVER_VOL);
				if(!buffer)
				{
					BASS_StreamFree(hstrm);
					_PostError("Can't create sound effect: Not enough memory");
				}
				else
				{
					BASS_ChannelGetData(hstrm, buffer, length);
					hs=BASS_SampleCreateDone();
					BASS_StreamFree(hstrm);
					if(!hs)	_PostError("Can't create sound effect");
				}
			}
		}

		if(!size) Resource_Free(data);
		return hs;
	}
Example #12
0
bool BassPlayer::calcSpectrum(QVector<float> & result) {
    int b0 = 0;
    float fft[1024];
    BASS_ChannelGetData(chan, fft, BASS_DATA_FFT2048);

    for (int x = 0; x < sbands_count; x++) {
        float peak = 0;
        int b1 = spectrumPoints[x];
        for (; b0 < b1; b0++)
            if (peak < fft[1 + b0])
                peak = fft[1 + b0];

        result.append(sqrt(peak));
    }

    return true;
}
Example #13
0
// Load an audio file in .wav format
bool LoadAudioFile(LPCSTR szFileName)
{
  // Load the data from the specified file
  HSTREAM file_stream = BASS_StreamCreateFile(FALSE,szFileName,0,0,BASS_STREAM_DECODE);

  // Get the length and header info from the loaded file
  stream_length=BASS_StreamGetLength(file_stream); 
  BASS_ChannelGetInfo(file_stream, &info);

  // Get the audio samples from the loaded file
  data = new char[(unsigned int)stream_length];
  BASS_ChannelGetData(file_stream, data, (unsigned int)stream_length);
    
  // Set playing to begin at the beginning of the loaded data
  pos = 0;

  return false;
}
//---------------------------------------------------------------------------
// 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=(char *)realloc((char *)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;

	int res=BASS_ChannelGetData(rchan,buf,BASS_DATA_FFT16384|BASS_DATA_FLOAT); // get the sample data (floating-point to avoid 8 & 16 bit processing)

	return TRUE; // continue recording
}
Example #15
0
//
// Util use in BeginLoadingMedia
//
HSTREAM CBassAudio::ConvertFileToMono(const SString& strPath)
{
    HSTREAM decoder = BASS_StreamCreateFile ( false, strPath, 0, 0, BASS_STREAM_DECODE | BASS_SAMPLE_MONO ); // open file for decoding
    if ( !decoder )
        return 0; // failed
    DWORD length = static_cast <DWORD> ( BASS_ChannelGetLength ( decoder, BASS_POS_BYTE ) ); // get the length
    void *data = malloc ( length ); // allocate buffer for decoded data
    BASS_CHANNELINFO ci;
    BASS_ChannelGetInfo ( decoder, &ci ); // get sample format
    if ( ci.chans > 1 ) // not mono, downmix...
    {
        HSTREAM mixer = BASS_Mixer_StreamCreate ( ci.freq, 1, BASS_STREAM_DECODE | BASS_MIXER_END ); // create mono mixer
        BASS_Mixer_StreamAddChannel ( mixer, decoder, BASS_MIXER_DOWNMIX | BASS_MIXER_NORAMPIN | BASS_STREAM_AUTOFREE ); // plug-in the decoder (auto-free with the mixer)
        decoder = mixer; // decode from the mixer
    }
    length = BASS_ChannelGetData ( decoder, data, length ); // decode data
    BASS_StreamFree ( decoder ); // free the decoder/mixer
    HSTREAM stream = BASS_StreamCreate ( ci.freq, 1, BASS_STREAM_AUTOFREE, STREAMPROC_PUSH, NULL ); // create stream
    BASS_StreamPutData ( stream, data, length ); // set the stream data
    free ( data ); // free the buffer
    return stream;
}
Example #16
0
float* CBassAudio::GetWaveData ( int iLength )
{
    if ( m_pSound )
    {
        long lFlags = 0;
        if ( iLength == 128 || iLength == 256 || iLength == 512 || iLength == 1024 || iLength == 2048 || iLength == 4096 || iLength == 8192 || iLength == 16384 )
        {
            lFlags = 4*iLength|BASS_DATA_FLOAT;
        }
        else 
            return NULL;

        float* pData = new float [ iLength ];
        if ( BASS_ChannelGetData ( m_pSound, pData, lFlags ) != -1 )
            return pData;
        else
        {
            delete [] pData;
            return NULL;
        }
    }
    return NULL;
}
Example #17
0
void cSnd::Vpr()
{
	//  get data
	if (view.eVis==viPrint && surf && PlR)
	{
		EnterCriticalSection(&cs);
		BASS_ChannelGetData(bPlay ? chPl : chRec, fftB, fts[view.fftSize] );

		for (int x=0; x < view.xSize+1; x++)
		{
			float f = fftB[x+1];  if (f<0.000001f) f=0.000001f;
			float y = -log10(f) * view.fftMul /255.f -0.1f;  //par

			y = mia(0.f,1.0f, y);
			C[xpn][x] = 1.f-y;
		}
		// _ write pos
		xpr++;  if (xpn < PrLin)  xpn++;
		if (xpr >= view.xSize)  xpr = 0;
		
		LeaveCriticalSection(&cs);
	}else
	if (!bPaused)  {  xpr = 0;  xpn = 0;  }
}
Example #18
0
void Vis::paintEvent(QPaintEvent *event){
    if(!this->isVisible()){
        return;
    }
    BASS_ChannelGetData(this->chan, fft, BASS_DATA_FFT8192); //получение даных БФП
    if(this->ctype == 1){
        if(this->Draw){
            QPainter paint(this);
            this->Draw(paint, fft);
        }
        else{
            qDebug() << "error: cold not resolve Draw...";
        }
    }
    else if(this->ctype == 2){
        if(this->Upd){
            this->Upd(fft);
        }
        else{
            err << "could't resolve Update()";
        }
    }
    memset(fft, 0, sizeof(this->fft));
}
Example #19
0
// update the spectrum display - the interesting bit :)
gboolean UpdateSpectrum(gpointer data)
{
	int x,y,y1;
	RGB *specbuf=(RGB*)gdk_pixbuf_get_pixels(specpb);

	if (specmode==3) { // waveform
		int c;
		float *buf;
		BASS_CHANNELINFO ci;
		memset(specbuf,0,SPECWIDTH*SPECHEIGHT*sizeof(*specbuf));
		BASS_ChannelGetInfo(chan,&ci); // get number of channels
		buf=alloca(ci.chans*SPECWIDTH*sizeof(float)); // allocate buffer for data
		BASS_ChannelGetData(chan,buf,(ci.chans*SPECWIDTH*sizeof(float))|BASS_DATA_FLOAT); // get the sample data (floating-point to avoid 8 & 16 bit processing)
		for (c=0;c<ci.chans;c++) {
			for (x=0;x<SPECWIDTH;x++) {
				int v=(1-buf[x*ci.chans+c])*SPECHEIGHT/2; // invert and scale to fit display
				if (v<0) v=0;
				else if (v>=SPECHEIGHT) v=SPECHEIGHT-1;
				if (!x) y=v;
				do { // draw line from previous sample...
					if (y<v) y++;
					else if (y>v) y--;
					specbuf[y*SPECWIDTH+x]=palette[c&1?127:1]; // left=green, right=red (could add more colours to palette for more chans)
				} while (y!=v);
			}
		}
	} else {
		float fft[1024];
		BASS_ChannelGetData(chan,fft,BASS_DATA_FFT2048); // get the FFT data

		if (!specmode) { // "normal" FFT
			memset(specbuf,0,SPECWIDTH*SPECHEIGHT*sizeof(*specbuf));
			for (x=0;x<SPECWIDTH/2;x++) {
#if 1
				y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
#else
				y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
#endif
				if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
				if (x && (y1=(y+y1)/2)) // interpolate from previous to make the display smoother
					while (--y1>=0) specbuf[(SPECHEIGHT-1-y1)*SPECWIDTH+x*2-1]=palette[y1+1];
				y1=y;
				while (--y>=0) specbuf[(SPECHEIGHT-1-y)*SPECWIDTH+x*2]=palette[y+1]; // draw level
			}
		} else if (specmode==1) { // logarithmic, acumulate & average bins
			int b0=0;
			memset(specbuf,0,SPECWIDTH*SPECHEIGHT*sizeof(*specbuf));
#define BANDS 28
			for (x=0;x<BANDS;x++) {
				float peak=0;
				int b1=pow(2,x*10.0/(BANDS-1));
				if (b1>1023) b1=1023;
				if (b1<=b0) b1=b0+1; // make sure it uses at least 1 FFT bin
				for (;b0<b1;b0++)
					if (peak<fft[1+b0]) peak=fft[1+b0];
				y=sqrt(peak)*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
				if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
				while (--y>=0)
					for (y1=0;y1<SPECWIDTH/BANDS-2;y1++)
						specbuf[(SPECHEIGHT-1-y)*SPECWIDTH+x*(SPECWIDTH/BANDS)+y1]=palette[y+1]; // draw bar
			}
		} else { // "3D"
			for (x=0;x<SPECHEIGHT;x++) {
				y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
				if (y>127) y=127; // cap it
				specbuf[(SPECHEIGHT-1-x)*SPECWIDTH+specpos]=palette[128+y]; // plot it
			}
			// move marker onto next position
			specpos=(specpos+1)%SPECWIDTH;
			for (x=0;x<SPECHEIGHT;x++) specbuf[x*SPECWIDTH+specpos]=palette[255];
		}
	}

	gtk_image_set_from_pixbuf(GTK_IMAGE(speci),specpb); // update the display

	return TRUE;
}
Example #20
0
// update the spectrum display - the interesting bit :)
void CALLBACK UpdateSpectrum(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	static DWORD quietcount=0;
	HDC dc;
	int x,y,y1;

	if (specmode==3) { // waveform
		short buf[SPECWIDTH];
		memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
		BASS_ChannelGetData(chan,buf,sizeof(buf)); // get the sample data
		for (x=0;x<SPECWIDTH;x++) {
			int v=(32767-buf[x])*SPECHEIGHT/65536; // invert and scale to fit display
			if (!x) y=v;
			do { // draw line from previous sample...
				if (y<v) y++;
				else if (y>v) y--;
				specbuf[y*SPECWIDTH+x]=abs(y-SPECHEIGHT/2)*2+1;
			} while (y!=v);
		}
	} else {
		float fft[1024];
		BASS_ChannelGetData(chan,fft,BASS_DATA_FFT2048); // get the FFT data

		if (!specmode) { // "normal" FFT
			memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
			for (x=0;x<SPECWIDTH/2;x++) {
#if 1
				y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
#else
				y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
#endif
				if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
				if (x && (y1=(y+y1)/2)) // interpolate from previous to make the display smoother
					while (--y1>=0) specbuf[y1*SPECWIDTH+x*2-1]=y1+1;
				y1=y;
				while (--y>=0) specbuf[y*SPECWIDTH+x*2]=y+1; // draw level
			}
		} else if (specmode==1) { // logarithmic, acumulate & average bins
			int b0=0;
			memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
#define BANDS 28
			for (x=0;x<BANDS;x++) {
				float peak=0;
				int b1=pow(2,x*10.0/(BANDS-1));
				if (b1>1023) b1=1023;
				if (b1<=b0) b1=b0+1; // make sure it uses at least 1 FFT bin
				for (;b0<b1;b0++)
					if (peak<fft[1+b0]) peak=fft[1+b0];
				y=sqrt(peak)*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
				if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
				while (--y>=0)
					memset(specbuf+y*SPECWIDTH+x*(SPECWIDTH/BANDS),y+1,0.9*(SPECWIDTH/BANDS)); // draw bar
			}
		} else { // "3D"
			for (x=0;x<SPECHEIGHT;x++) {
				y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
				if (y>127) y=127; // cap it
				specbuf[x*SPECWIDTH+specpos]=128+y; // plot it
			}
			// move marker onto next position
			specpos=(specpos+1)%SPECWIDTH;
			for (x=0;x<SPECHEIGHT;x++) specbuf[x*SPECWIDTH+specpos]=255;
		}
	}

	// update the display
	dc=GetDC(win);
	BitBlt(dc,0,0,SPECWIDTH,SPECHEIGHT,specdc,0,0,SRCCOPY);
	if (LOWORD(BASS_ChannelGetLevel(chan))<500) { // check if it's quiet
		quietcount++;
		if (quietcount>40 && (quietcount&16)) { // it's been quiet for over a second
			RECT r={0,0,SPECWIDTH,SPECHEIGHT};
			SetTextColor(dc,0xffffff);
			SetBkMode(dc,TRANSPARENT);
			DrawText(dc,"make some noise!",-1,&r,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
		}
	} else
		quietcount=0; // not quiet
	ReleaseDC(win,dc);
}
Example #21
0
void net_radio_getFftData1024Floats(float* data) {
    BASS_ChannelGetData(chan, data, BASS_DATA_FFT2048);
}
Example #22
0
int decodeFunc(void* inData)
{
    int a, b, r, g, i;
    //short waveData[8 * 1024];
    unsigned int* fftPtr;
    unsigned int* fftOutput;
    float fftData[1024];
    //double timeInSec = 0.0;
    const float maxIntensity = 500 * 2;
    const int COLOR_STEPS = 255;
    const int PALETTE_SIZE = 3 * COLOR_STEPS;
    const int spectrumLength = 1024;
    ThreadFuncData* threadData = (ThreadFuncData*)inData;
    unsigned int colors[255 * 3];
    int imageHeight = 128;
    HSTREAM chan = threadData->stream;
	MusicData* data = threadData->data;
    float percentDone = 1.0f;
    float step = 0.0f;

    mtx_lock(&s_mutex);

    const int SAMPLING_FREQUENCY = 100; //warning: in TimelineImage this samplingfrequency is assumed to be 100
    const double SAMPLING_RESOLUTION = 1.0 / SAMPLING_FREQUENCY;

    QWORD sampleLength = BASS_ChannelSeconds2Bytes(chan, SAMPLING_RESOLUTION);
    int numSamples = (int)((double)BASS_ChannelGetLength(chan, BASS_POS_BYTE) / (double)sampleLength);

    //printf("Num samples %d\n", (int)sampleLength);
    //printf("Num samples %d\n", numSamples);

    BASS_ChannelPlay(chan, 0);

    int j_table[128];
    int pj_table[128];
    int nj_table[128];

    // TODO: Size optimize?

    data->sampleCount = numSamples;

    fftPtr = fftOutput = (unsigned int*)malloc(128 * 4 * (numSamples + 1));

    //const int spectrumLength = 1024;
    //const int imageHeight = 256;

    //var spectrumImage = new Bitmap((int)numSamples, imageHeight);
    //var volumeImage = new Bitmap((int)numSamples, imageHeight);

    //s_editorData.waveViewSize = 128;
	//s_editorData.trackViewInfo.windowSizeX -= s_editorData.waveViewSize;

    //timeInSec =(DWORD)BASS_ChannelBytes2Seconds(chan, len);
    //printf(" %u:%02u\n", (int)timeInSec / 60, (int)timeInSec % 60);

    for (i = 0; i < PALETTE_SIZE; ++i)
    {
        a = 255;
        if (i < PALETTE_SIZE * 0.666f)
            a = (int)(i * 255 / (PALETTE_SIZE * 0.666f));

        b = 0;
        if (i < PALETTE_SIZE * 0.333f)
            b = i;
        else if (i < PALETTE_SIZE * 0.666f)
            b = -i + 510;

        r = 0;
        if (i > PALETTE_SIZE * 0.666f)
            r = 255;
        else if (i > PALETTE_SIZE * 0.333f)
            r = i - 255;

        g = 0;
        if (i > PALETTE_SIZE * 0.666f)
            g = i - 510;

        colors[i] = Emgui_color32((uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a);
    }

    float f = (float)(spectrumLength / log((float)(imageHeight + 1)));
    float f2 = (float)((PALETTE_SIZE - 1) / log(maxIntensity + 1));

    (void)f2;

    for (int rowIndex = 0; rowIndex < imageHeight; ++rowIndex)
    {
        int j_ = (int)(f * log(rowIndex + 1));
        int pj_ = (int)(rowIndex > 0 ? f * log(rowIndex - 1 + 1) : j_);
        int nj_ = (int)(rowIndex < imageHeight - 1 ? f * log(rowIndex + 1 + 1) : j_);

        j_table[rowIndex] = j_;
        pj_table[rowIndex] = pj_;
        nj_table[rowIndex] = nj_;
    }

    step = (float)(99.0f / numSamples);
    percentDone = 1.0f;

    for (int sampleIndex = 0; sampleIndex < numSamples; ++sampleIndex)
    {
        BASS_ChannelSetPosition(chan, sampleIndex * sampleLength, BASS_POS_BYTE);
        BASS_ChannelGetData(chan, fftData, BASS_DATA_FFT2048);

        data->percentDone = (int)(percentDone);

        //printf("%d/%d\n", sampleIndex, numSamples);

        for (int rowIndex = 0; rowIndex < imageHeight; ++rowIndex)
        {
            //int j_ = (int)(f * log(rowIndex + 1));
            //int pj_ = (int)(rowIndex > 0 ? f * log(rowIndex - 1 + 1) : j_);
            //int nj_ = (int)(rowIndex < imageHeight - 1 ? f * log(rowIndex + 1 + 1) : j_);

            int j_ = j_table[(imageHeight - rowIndex) - 1];
            int pj_ = pj_table[(imageHeight - rowIndex) - 1];
            int nj_ = nj_table[(imageHeight - rowIndex) - 1];

            //printf("index %d - %d %d %d\n", rowIndex, j_, pj_, nj_);

            float intensity = 125.0f * 4.0f * fftData[spectrumLength - pj_ - 1] +
                              750.0f * 4.0f * fftData[spectrumLength - j_ - 1] +
                              125.0f * 4.0f * fftData[spectrumLength - nj_ - 1];
            if (intensity > maxIntensity)
                intensity = maxIntensity;

            if (intensity < 0.0f)
                intensity = 0.0f;

            int palettePos = (int)(f2 * log(intensity + 1));

            *fftOutput++ = colors[palettePos];
        }

        percentDone += step;
    }

    BASS_StreamFree(chan);

    free(threadData);

    data->percentDone = 100;
    data->fftData = fftPtr;

    mtx_unlock(&s_mutex);

    //printf("thread done\n");

    return 1;
}
/*
	Диалоговая процедура
*/
INT_PTR CALLBACK Application::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		HANDLE_MSG(hWnd, WM_CTLCOLORSTATIC, _this->OnColorStatic);
		HANDLE_MSG(hWnd, WM_CTLCOLORDLG, _this->OnCtlColor);
		HANDLE_MSG(hWnd, WM_TIMER, _this->Cls_OnTimer);
		HANDLE_MSG(hWnd, WM_INITDIALOG, _this->Cls_OnInitDialog);
		HANDLE_MSG(hWnd, WM_HSCROLL, _this->Cls_OnHScroll);
		HANDLE_MSG(hWnd, WM_COMMAND, _this->Cls_OnCommand);
		HANDLE_MSG(hWnd, WM_SYSCOMMAND, _this->Cls_OnSysCommand);
		HANDLE_MSG(hWnd, WM_RBUTTONDOWN, _this->Cls_OnRButtonDown);
		/*
			Управление с трея
		*/
		case WM_USER + 200:
		{
			switch (lParam)
			{
				case WM_LBUTTONDOWN:
				{
					_this->DeleteIconOfTray(hWnd);
					break;
				}
				case WM_RBUTTONDOWN:
				{
					HMENU hContextByTray;
					POINT pos;
					GetCursorPos(&pos);
					hContextByTray = CreatePopupMenu();
					AppendMenu(hContextByTray, MF_STRING, IDC_BTNPLAY, TEXT("Play"));
					AppendMenu(hContextByTray, MF_STRING, IDC_BTNPAUSE, TEXT("Pause"));
					AppendMenu(hContextByTray, MF_STRING, IDC_BTNSTOP, TEXT("Stop"));
					AppendMenu(hContextByTray, MF_STRING, IDC_NEXTSONG, TEXT("Next"));
					AppendMenu(hContextByTray, MF_STRING, IDC_PREVSONG, TEXT("Prev"));
					AppendMenu(hContextByTray, MF_SEPARATOR, 0, 0);
					AppendMenu(hContextByTray, MF_STRING, IDC_BTNCLOSE, TEXT("&Close"));
					SetForegroundWindow(hWnd);
					TrackPopupMenu(hContextByTray, TPM_LEFTALIGN, pos.x, pos.y, 0, hWnd, 0);
					DestroyMenu(hContextByTray);
					break;
				}
				default:
					break;
			}
			break;
		}
		case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &ps);

			RECT rect;
			GetClientRect(hWnd, &rect);
			INT height = rect.bottom / 2 - 10;
			/*
				Initialization size rectangle by redraw spectrum
			*/
			_this->spectrRECT.left = rect.left;
			_this->spectrRECT.top = rect.top;
			_this->spectrRECT.right = rect.right;
			_this->spectrRECT.bottom = height;
			/*
				Yellow pen
			*/
			static int fred = 0 , fblue = 0, fgreen = 0;
			if (fred != _this->fill_red ||
				fgreen != _this->fill_green ||
				fblue != _this->fill_blue)
			{
				_this->black_brush = CreateSolidBrush
				(
					RGB(_this->fill_red,
						_this->fill_green,
						_this->fill_blue)
				);
			}
			fred = _this->fill_red;
			fgreen = _this->fill_green;
			fblue = _this->fill_blue;
			/*
				Red pen
			*/
			static int cred = 0, cgreen = 0, cblue = 0;
			if (cred != _this->contour_red ||
				cblue != _this->contour_blue ||
				cgreen != _this->contour_green)
			{
				_this->red_pen = CreatePen
				(PS_SOLID, 1,
					RGB(_this->contour_red,
						_this->contour_green,
						_this->contour_blue)
				);
			}
			cred = _this->contour_red;
			cblue = _this->contour_blue;
			cgreen = _this->contour_green;
			int x;
			int y = height;
			int offset = 35;
			int columns = 77;			//count columns
			int w = (rect.right - rect.left - 35) / columns; // ширина столбика
			FLOAT buffer_peaks[128] = { height };
			BASS_ChannelGetData(_this->hStream, buffer_peaks, BASS_DATA_FFT256);

			for (int i = 0; i < columns;i++)
			{
				SelectPen(hdc, _this->red_pen);
				x = rect.left + offset + w * i;
				y = abs(buffer_peaks[i] * 400 * 3 - height);
				if (y > height)
					y = height;
				SelectObject(hdc, _this->black_brush);
				SelectPen(hdc, _this->red_pen);
				if (height - y > 1)
					Rectangle(hdc, x, y, x + w, height);
			}

			EndPaint(hWnd, &ps);
			ReleaseDC(hWnd, hdc);
			break;
		}
		case WM_CLOSE:
		{
			BASS_Free();
			BASS_StreamFree(_this->hStream);
			EndDialog(hWnd, NULL);
			break;
		}
		default:
			return FALSE;
	}
	return FALSE;
}
Example #24
0
//-----------------------------------------------------------------------------
void LLFFTSound::update(float addedTime)
{
	if(!m_bInitialized || !m_bPlaying)
		return;

#ifdef _WINDOWS
	
	// update current waveform level
#if BASSVERSION == 0x204
	DWORD pos = BASS_ChannelGetPosition(m_dChannel, BASS_POS_BYTE);
	if (pos == BASS_ChannelGetLength(m_dChannel, BASS_POS_BYTE))
#else
	DWORD pos = BASS_ChannelGetPosition(m_dChannel);
	if (pos == BASS_ChannelGetLength(m_dChannel))
#endif
	{
		m_fCurrLevelLeft = 0.0f;
		m_fCurrLevelRight = 0.0f;
		m_bPlaying = false;
		BASS_ChannelStop(m_dChannel);
		// reset bands values
		for (int i=0; i< BANDS; i++)
			m_fBands[i] = 0.0f;

		// reset events queue
		resetEvent();
	}
	else
	{
		// update lever for each channel
		DWORD level = BASS_ChannelGetLevel(m_dChannel);
		m_fCurrLevelLeft = ((double)LOWORD(level) / 32768);		// range 0 to 1: left channel is low word
		m_fCurrLevelRight = ((double)HIWORD(level) / 32768);	// range 0 to 1: right channel is high word

		// update band spectrum
		float fft[1024];
		BASS_ChannelGetData(m_dChannel,fft,BASS_DATA_FFT2048); // get the FFT data

		int b0=0;
		int x,y;
#define FFTCAP 256.0f

		for (x=0; x<BANDS; x++) {
			float sum=0;
			int sc,b1 = pow(2,x*10.0/(BANDS-1));
			if (b1>1023) b1=1023;
			if (b1<=b0) b1=b0+1; // make sure it uses at least 1 FFT bin
			sc = 10 + b1 - b0;
			
			for (;b0<b1;b0++) sum+=fft[1+b0];
			
			y=(sqrt(sum/log10((double)sc))*1.7*FFTCAP)-4; // scale it
			
			if (y>FFTCAP) y=FFTCAP; // cap it
			
			// store band value
			m_fBands[x] = y;	
			m_fBands[x] /= FFTCAP;	// normalized band value (0.0 - 1.0)
		}

		// check event associated with this sound file: use pos variable to detect timing...
		float elapsedTime = BASS_ChannelBytes2Seconds(m_dChannel,pos); 

		if (m_iNumEvents && !m_bEventDone)
		{
			if (elapsedTime > 0.0f)
			{
				// there is possibility that multiple events have the same timestamp...
				// should do some kind of iteration.
				bool running = true;
				while(running)
				{
					if (m_fNextEventTime < elapsedTime)
					{
						// execute callback function
						i_CharacterEventCallback.execute(m_vEventVec[m_iNextEvent]);

						// move to next event
						m_iNextEvent++;
						if (m_iNextEvent == m_iNumEvents)
						{
							// reached the last event
							m_iNextEvent = 0;
							m_bEventDone = true;
							running = false;
						}
						m_fNextEventTime = m_vEventVec[m_iNextEvent]->eTime;

					}
					else
						running = false;
				}
			}
		}


	}
#endif
}
Example #25
0
// update the spectrum display - the interesting bit :)
void CALLBACK UpdateSpectrum(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	HDC dc;
	int x,y,y1;

	if (specmode==3) { // waveform
		int c;
		float *buf;
		BASS_CHANNELINFO ci;
		memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
		BASS_ChannelGetInfo(chan,&ci); // get number of channels
		buf=alloca(ci.chans*SPECWIDTH*sizeof(float)); // allocate buffer for data
		BASS_ChannelGetData(chan,buf,(ci.chans*SPECWIDTH*sizeof(float))|BASS_DATA_FLOAT); // get the sample data (floating-point to avoid 8 & 16 bit processing)
		for (c=0;c<ci.chans;c++) {
			for (x=0;x<SPECWIDTH;x++) {
				int v=(1-buf[x*ci.chans+c])*SPECHEIGHT/2; // invert and scale to fit display
				if (v<0) v=0;
				else if (v>=SPECHEIGHT) v=SPECHEIGHT-1;
				if (!x) y=v;
				do { // draw line from previous sample...
					if (y<v) y++;
					else if (y>v) y--;
					specbuf[y*SPECWIDTH+x]=c&1?127:1; // left=green, right=red (could add more colours to palette for more chans)
				} while (y!=v);
			}
		}
	} else {
		float fft[1024];
		BASS_ChannelGetData(chan,fft,BASS_DATA_FFT2048); // get the FFT data

		if (!specmode) { // "normal" FFT
			memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
			for (x=0;x<SPECWIDTH/2;x++) {
#if 1
				y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
#else
				y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
#endif
				if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
				if (x && (y1=(y+y1)/2)) // interpolate from previous to make the display smoother
					while (--y1>=0) specbuf[y1*SPECWIDTH+x*2-1]=y1+1;
				y1=y;
				while (--y>=0) specbuf[y*SPECWIDTH+x*2]=y+1; // draw level
			}
		} else if (specmode==1) { // logarithmic, acumulate & average bins
			int b0=0;
			memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
#define BANDS 28
			for (x=0;x<BANDS;x++) {
				float sum=0;
				int sc,b1=pow(2,x*10.0/(BANDS-1));
				if (b1>1023) b1=1023;
				if (b1<=b0) b1=b0+1; // make sure it uses at least 1 FFT bin
				sc=10+b1-b0;
				for (;b0<b1;b0++) sum+=fft[1+b0];
				y=(sqrt(sum/log10(sc))*1.7*SPECHEIGHT)-4; // scale it
				if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
				while (--y>=0)
					memset(specbuf+y*SPECWIDTH+x*(SPECWIDTH/BANDS),y+1,SPECWIDTH/BANDS-2); // draw bar
			}
		} else { // "3D"
			for (x=0;x<SPECHEIGHT;x++) {
				y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
				if (y>127) y=127; // cap it
				specbuf[x*SPECWIDTH+specpos]=128+y; // plot it
			}
			// move marker onto next position
			specpos=(specpos+1)%SPECWIDTH;
			for (x=0;x<SPECHEIGHT;x++) specbuf[x*SPECWIDTH+specpos]=255;
		}
	}

	// update the display
	dc=GetDC(win);
	BitBlt(dc,0,0,SPECWIDTH,SPECHEIGHT,specdc,0,0,SRCCOPY);
	ReleaseDC(win,dc);
}
Example #26
0
void CALLBACK CustFXDSPProc (HFX hfx, DWORD chan, void* buf, DWORD len, HCustFX* hc) {
BASS_StreamPutData(hc->push, buf, len);
BASS_ChannelGetData(hc->pitch, buf, len);
}
int Player::stateOfBuffer()
{
    return BASS_ChannelGetData(_output,NULL,BASS_DATA_AVAILABLE);
}
Example #28
0
BOOL 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;
}
Example #29
0
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CSoundStream
//  - prototype : bool GetFFT512(float* pfBuffer) const
//
//  - Purpose   : Gets the current FFT representation of the playing stream.
//                The buffer is filled with 512 floating point values.
//
// -----------------------------------------------------------------------------
bool CSoundStream::GetFFT512(float* pfBuffer) const
{
    return BASS_ChannelGetData(m_handle, pfBuffer, BASS_DATA_FFT1024) != -1;
}
Example #30
0
void Spectrum::step(std::vector<DWORD> &rVecCurrentChannel)
{
    //data[i]
    int nCount = 0;
    unsigned int *data3 = data + size * 2;
    for (unsigned int i = 0; i<size; i++)
    {
        data3[i] = 0;
    }
    for (int i = 0; i < rVecCurrentChannel.size(); i++)
    {
        unsigned int *data2 = data + size;
        float buf[256];
        if (BASS_ChannelGetData(
            rVecCurrentChannel[i],
            buf,
            BASS_DATA_FFT512
            ) == sizeof(buf))
        {
            float maxf = 0;
            for (unsigned int i = 0; i<256; i++)
            {
                if (maxf < buf[i])
                {
                    maxf = buf[i];
                }
            }
            for (unsigned int i = 0; i<size; i++)
            {
                data2[i] = height * (1 - buf[i * 50 / size] / maxf);
                if (data2[i] > height)
                    data2[i] = height;
                if (data2[i] < 0) 
                    data2[i] = 0;
                data3[i] += data2[i];
            }
            nCount++;
        }
    }

    if (nCount)
    {
        for (unsigned int i = 0; i<size; i++)
        {
            data[i] = (data[i] + 7 * data3[i]) / (nCount * 8);
            if (data[i] > height)
                data[i] = height;
            if (data[i] < 0) 
                data[i] = 0;
        }
    }
    else
    {
        for (unsigned int i = 0; i<size; i++)
        {
            data[i] += rand()%3-1;
            if (data[i] > height)
                data[i] = height;
            if (data[i] < 0) 
                data[i] = 0;
        }
    }
}