AVSsupereq(PClip _child, const char* filename, IScriptEnvironment* env) : GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_FLOAT, SAMPLE_FLOAT)) { last_nch = vi.AudioChannels(); last_srate = vi.audio_samples_per_second; FILE *settingsfile; settingsfile = fopen(filename, "r"); if (settingsfile != NULL) { int n; for(n=0;n<N_BANDS;n++) { int readval; if (fscanf(settingsfile, "%d", &readval) == 1) { my_eq.bands[n] = ((-readval)+20); } } fclose(settingsfile); } else { env->ThrowError("SuperEQ: Could not open file"); } UINT n; for(n=0;n<last_nch;n++) eqs.add_item(new supereq<float>); double bands[N_BANDS]; // my_eq = cfg_eq; setup_bands(my_eq,bands); for(n=0;n<last_nch;n++) eqs[n]->equ_makeTable(bands,¶mroot,(double)last_srate); dstbuffer = new SFLOAT[vi.audio_samples_per_second * vi.AudioChannels()]; // Our buffer can minimum contain one second. passbuffer = new SFLOAT[vi.audio_samples_per_second * vi.AudioChannels()]; // Our buffer can minimum contain one second. dstbuffer_size = vi.audio_samples_per_second; next_sample = 0; // Next output sample inputReadOffset = 0; // Next input sample dst_samples_filled = 0; }
void __stdcall AVSsupereq::GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) { if (start != next_sample) { // Reset on seek inputReadOffset = start; // Reset at new read position. dst_samples_filled=0; eqs.delete_all(); UINT n; for(n=0;n<last_nch;n++) eqs.add_item(new supereq<float>); double bands[N_BANDS]; setup_bands(my_eq,bands); for(n=0;n<last_nch;n++) eqs[n]->equ_makeTable(bands,¶mroot,(double)last_srate); } bool buffer_full = false; int samples_filled = 0; do { // Empty buffer if something is still left. if (dst_samples_filled) { int copysamples = min((int)count-samples_filled, dst_samples_filled); // Copy finished samples env->BitBlt((BYTE*)buf+samples_filled*last_nch*sizeof(SFLOAT),0, (BYTE*)dstbuffer,0,copysamples*last_nch*sizeof(SFLOAT),1); dst_samples_filled -= copysamples; if (dst_samples_filled) { // Move non-used samples memcpy(dstbuffer, &dstbuffer[copysamples*last_nch], dst_samples_filled*sizeof(SFLOAT)*last_nch); } samples_filled += copysamples; if (samples_filled >= count) buffer_full = true; } // If buffer empty - refill if (dst_samples_filled<=0) { // Feed new samples to filter child->GetAudio(dstbuffer, inputReadOffset, last_srate, env); inputReadOffset += last_srate; for(UINT n=0;n<last_nch;n++) // Copies n channels to separate buffers to individual filters { UINT s; for(s=0;s<last_srate;s++) passbuffer[s]=dstbuffer[s*last_nch+n]; eqs[n]->write_samples(passbuffer, last_srate); } // Read back samples from filter int samples_out = 0; for(UINT n=0;n<last_nch;n++) // Copies back samples from individual filters { SFLOAT *data_out = eqs[n]->get_output(&samples_out); // Check temp buffer size if (dstbuffer_size < samples_out) { if (dstbuffer_size) delete[] dstbuffer; dstbuffer = new SFLOAT[samples_out*last_nch]; dstbuffer_size = samples_out; } UINT s; for(s=0;s<(UINT)samples_out;s++) dstbuffer[s*last_nch+n]=data_out[s]; } dst_samples_filled = samples_out; } } while (!buffer_full); next_sample += count; }
int transpose_inplace( float *a, // matrix to transpose (row-major order) long nrows, // number of rows in matrix a long ncols, // number of columns in matrix a const struct Transpose_Progress_Callback *progress // optional callback functor for status; NULL for none ) // Transposes matrix of nrows x ncols elements to ncols x nrows. // Returns 0 on success, 1 if a memory allocation error occurred (with matrix unchanged), // or -1 if canceled via progress callback (leaving matrix corrupted). { int error; int cancel = 0; void *bufin = NULL; void *bufout = NULL; Band_Info *RESTRICT pinfo = NULL; Band_Info *RESTRICT qinfo = NULL; struct Transpose_Progress_Info progress_info; struct Transpose_Progress_Info *progress_ptr = NULL; int nbands = choose_bands_inplace( nrows, ncols ); if (nbands == 0) { return 0; // no work to do (nrows <= 1 or ncols <= 1) } if (nbands <= 2) { return transpose_inplace_small( a, nrows, ncols ); } error = setup_bands( a, a, nrows, ncols, nbands, nbands, &bufin, &bufout, &pinfo, &qinfo ); if (error) { return 1; } if (progress) { progress_info.progress = progress; progress_info.per_move = 2.0 / (float)( 7 * (LONG)nbands * (LONG)nbands - (LONG)nbands ); progress_info.moves_done = 0; progress_ptr = &progress_info; } cancel = cancel || isolate_blocks( a, pinfo, qinfo, nrows, ncols, nbands, progress_ptr ); cancel = cancel || transpose_blocks( pinfo, qinfo, nbands, progress_ptr ); free( bufin ); // pinfo[nbands-1].addr = NULL; cancel = cancel || merge_blocks( a, pinfo, qinfo, nrows, ncols, nbands, progress_ptr ); free( bufout ); free( pinfo ); free( qinfo ); if (cancel) { return -1; } return 0; }