mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Merge branch 'master' of git://0pointer.de/pulseaudio
This commit is contained in:
		
						commit
						9c61465c79
					
				
					 3 changed files with 129 additions and 127 deletions
				
			
		| 
						 | 
					@ -1513,6 +1513,11 @@ if test "x${HAVE_SIMPLEDB}" = "x1" ; then
 | 
				
			||||||
    ENABLE_SIMPLEDB=yes
 | 
					    ENABLE_SIMPLEDB=yes
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENABLE_FFTW=no
 | 
				
			||||||
 | 
					if test "x${HAVE_FFTW}" = "x1" ; then
 | 
				
			||||||
 | 
					   ENABLE_FFTW=yes
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENABLE_OPENSSL=no
 | 
					ENABLE_OPENSSL=no
 | 
				
			||||||
if test "x${HAVE_OPENSSL}" = "x1" ; then
 | 
					if test "x${HAVE_OPENSSL}" = "x1" ; then
 | 
				
			||||||
   ENABLE_OPENSSL=yes
 | 
					   ENABLE_OPENSSL=yes
 | 
				
			||||||
| 
						 | 
					@ -1563,6 +1568,7 @@ echo "
 | 
				
			||||||
    Enable tdb:                    ${ENABLE_TDB}
 | 
					    Enable tdb:                    ${ENABLE_TDB}
 | 
				
			||||||
    Enable gdbm:                   ${ENABLE_GDBM}
 | 
					    Enable gdbm:                   ${ENABLE_GDBM}
 | 
				
			||||||
    Enable simple database:        ${ENABLE_SIMPLEDB}
 | 
					    Enable simple database:        ${ENABLE_SIMPLEDB}
 | 
				
			||||||
 | 
					    Enable fftw:                   ${ENABLE_FFTW}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    System User:                   ${PA_SYSTEM_USER}
 | 
					    System User:                   ${PA_SYSTEM_USER}
 | 
				
			||||||
    System Group:                  ${PA_SYSTEM_GROUP}
 | 
					    System Group:                  ${PA_SYSTEM_GROUP}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1033,13 +1033,13 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 | 
				
			||||||
        if ((e = read_entry(u, name))) {
 | 
					        if ((e = read_entry(u, name))) {
 | 
				
			||||||
            uint32_t idx;
 | 
					            uint32_t idx;
 | 
				
			||||||
            char *devname;
 | 
					            char *devname;
 | 
				
			||||||
            uint32_t index = PA_INVALID_INDEX;
 | 
					            uint32_t found_index = PA_INVALID_INDEX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ((devname = get_name(name, "sink:"))) {
 | 
					            if ((devname = get_name(name, "sink:"))) {
 | 
				
			||||||
                pa_sink* s;
 | 
					                pa_sink* s;
 | 
				
			||||||
                PA_IDXSET_FOREACH(s, u->core->sinks, idx) {
 | 
					                PA_IDXSET_FOREACH(s, u->core->sinks, idx) {
 | 
				
			||||||
                    if (strcmp(s->name, devname) == 0) {
 | 
					                    if (strcmp(s->name, devname) == 0) {
 | 
				
			||||||
                        index = s->index;
 | 
					                        found_index = s->index;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -1048,7 +1048,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 | 
				
			||||||
                pa_source* s;
 | 
					                pa_source* s;
 | 
				
			||||||
                PA_IDXSET_FOREACH(s, u->core->sources, idx) {
 | 
					                PA_IDXSET_FOREACH(s, u->core->sources, idx) {
 | 
				
			||||||
                    if (strcmp(s->name, devname) == 0) {
 | 
					                    if (strcmp(s->name, devname) == 0) {
 | 
				
			||||||
                        index = s->index;
 | 
					                        found_index = s->index;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -1058,7 +1058,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 | 
				
			||||||
            pa_tagstruct_puts(reply, name);
 | 
					            pa_tagstruct_puts(reply, name);
 | 
				
			||||||
            pa_tagstruct_puts(reply, e->description);
 | 
					            pa_tagstruct_puts(reply, e->description);
 | 
				
			||||||
            pa_tagstruct_puts(reply, e->icon);
 | 
					            pa_tagstruct_puts(reply, e->icon);
 | 
				
			||||||
            pa_tagstruct_putu32(reply, index);
 | 
					            pa_tagstruct_putu32(reply, found_index);
 | 
				
			||||||
            pa_tagstruct_putu32(reply, NUM_ROLES);
 | 
					            pa_tagstruct_putu32(reply, NUM_ROLES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (uint32_t i = ROLE_NONE; i < NUM_ROLES; ++i) {
 | 
					            for (uint32_t i = ROLE_NONE; i < NUM_ROLES; ++i) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										242
									
								
								src/modules/module-equalizer-sink.c
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										242
									
								
								src/modules/module-equalizer-sink.c
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
					@ -337,7 +337,7 @@ static void sink_set_mute_cb(pa_sink *s) {
 | 
				
			||||||
    pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
 | 
					    pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __SSE2__
 | 
				
			||||||
//reference implementation
 | 
					//reference implementation
 | 
				
			||||||
static void dsp_logic(
 | 
					static void dsp_logic(
 | 
				
			||||||
    float * restrict dst,//used as a temp array too, needs to be fft_length!
 | 
					    float * restrict dst,//used as a temp array too, needs to be fft_length!
 | 
				
			||||||
| 
						 | 
					@ -351,12 +351,12 @@ static void dsp_logic(
 | 
				
			||||||
    fftwf_complex * restrict output_window,//The transformed window'd src
 | 
					    fftwf_complex * restrict output_window,//The transformed window'd src
 | 
				
			||||||
    struct userdata *u){
 | 
					    struct userdata *u){
 | 
				
			||||||
    //use a linear-phase sliding STFT and overlap-add method (for each channel)
 | 
					    //use a linear-phase sliding STFT and overlap-add method (for each channel)
 | 
				
			||||||
    //zero padd the data
 | 
					 | 
				
			||||||
    memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
 | 
					 | 
				
			||||||
    //window the data
 | 
					    //window the data
 | 
				
			||||||
    for(size_t j = 0; j < u->window_size; ++j){
 | 
					    for(size_t j = 0; j < u->window_size; ++j){
 | 
				
			||||||
        dst[j] = X * W[j] * src[j];
 | 
					        dst[j] = X * W[j] * src[j];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //zero padd the the remaining fft window
 | 
				
			||||||
 | 
					    memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
 | 
				
			||||||
    //Processing is done here!
 | 
					    //Processing is done here!
 | 
				
			||||||
    //do fft
 | 
					    //do fft
 | 
				
			||||||
    fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
 | 
					    fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
 | 
				
			||||||
| 
						 | 
					@ -390,112 +390,104 @@ static void dsp_logic(
 | 
				
			||||||
        (u->samples_gathered - u->R) * sizeof(float)
 | 
					        (u->samples_gathered - u->R) * sizeof(float)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
typedef float v4sf __attribute__ ((__aligned__(v_size * sizeof(float))));
 | 
					typedef float v4sf __attribute__ ((__aligned__(v_size * sizeof(float))));
 | 
				
			||||||
typedef union float_vector {
 | 
					typedef union float_vector {
 | 
				
			||||||
    float f[v_size];
 | 
					    float f[v_size];
 | 
				
			||||||
    v4sf v;
 | 
					    v4sf v;
 | 
				
			||||||
#ifdef __SSE2__
 | 
					 | 
				
			||||||
    __m128 m;
 | 
					    __m128 m;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
} float_vector_t;
 | 
					} float_vector_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////regardless of sse enabled, the loops in here assume
 | 
					//regardless of sse enabled, the loops in here assume
 | 
				
			||||||
////16 byte aligned addresses and memory allocations divisible by v_size
 | 
					//16 byte aligned addresses and memory allocations divisible by v_size
 | 
				
			||||||
//void dsp_logic(
 | 
					static void dsp_logic(
 | 
				
			||||||
//    float * restrict dst,//used as a temp array too, needs to be fft_length!
 | 
					    float * restrict dst,//used as a temp array too, needs to be fft_length!
 | 
				
			||||||
//    float * restrict src,/*input data w/ overlap at start,
 | 
					    float * restrict src,/*input data w/ overlap at start,
 | 
				
			||||||
//                               *automatically cycled in routine
 | 
					                               *automatically cycled in routine
 | 
				
			||||||
//                               */
 | 
					                               */
 | 
				
			||||||
//    float * restrict overlap,//The size of the overlap
 | 
					    float * restrict overlap,//The size of the overlap
 | 
				
			||||||
//    const float X,//multipliar
 | 
					    const float X,//multipliar
 | 
				
			||||||
//    const float * restrict H,//The freq. magnitude scalers filter
 | 
					    const float * restrict H,//The freq. magnitude scalers filter
 | 
				
			||||||
//    const float * restrict W,//The windowing function
 | 
					    const float * restrict W,//The windowing function
 | 
				
			||||||
//    fftwf_complex * restrict output_window,//The transformed window'd src
 | 
					    fftwf_complex * restrict output_window,//The transformed window'd src
 | 
				
			||||||
//    struct userdata *u){//Collection of constants
 | 
					    struct userdata *u){//Collection of constants
 | 
				
			||||||
      //float_vector_t x = {X, X, X, X};
 | 
					    const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
 | 
				
			||||||
//    const size_t window_size = PA_ROUND_UP(u->window_size,v_size);
 | 
					
 | 
				
			||||||
//    const size_t fft_h = PA_ROUND_UP(FILTER_SIZE, v_size / 2);
 | 
					
 | 
				
			||||||
//    //const size_t R = PA_ROUND_UP(u->R, v_size);
 | 
					    //assert(u->samples_gathered >= u->R);
 | 
				
			||||||
//    const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
 | 
					    //use a linear-phase sliding STFT and overlap-add method
 | 
				
			||||||
//     overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
 | 
					    for(size_t j = 0; j < u->window_size; j += v_size){
 | 
				
			||||||
//
 | 
					        //dst[j] = W[j] * src[j];
 | 
				
			||||||
//    //assert(u->samples_gathered >= u->R);
 | 
					        float_vector_t *d = (float_vector_t*) (dst + j);
 | 
				
			||||||
//    //zero out the bit beyond the real overlap so we don't add garbage
 | 
					        float_vector_t *w = (float_vector_t*) (W + j);
 | 
				
			||||||
//    for(size_t j = overlap_size; j > u->overlap_size; --j){
 | 
					        float_vector_t *s = (float_vector_t*) (src + j);
 | 
				
			||||||
//       overlap[j-1] = 0;
 | 
					 | 
				
			||||||
//    }
 | 
					 | 
				
			||||||
//    //use a linear-phase sliding STFT and overlap-add method
 | 
					 | 
				
			||||||
//    //zero padd the data
 | 
					 | 
				
			||||||
//    memset(dst + u->window_size, 0, (u->fft_size - u->window_size)*sizeof(float));
 | 
					 | 
				
			||||||
//    //window the data
 | 
					 | 
				
			||||||
//    for(size_t j = 0; j < window_size; j += v_size){
 | 
					 | 
				
			||||||
//        //dst[j] = W[j]*src[j];
 | 
					 | 
				
			||||||
//        float_vector_t *d = (float_vector_t*) (dst+j);
 | 
					 | 
				
			||||||
//        float_vector_t *w = (float_vector_t*) (W+j);
 | 
					 | 
				
			||||||
//        float_vector_t *s = (float_vector_t*) (src+j);
 | 
					 | 
				
			||||||
//#if __SSE2__
 | 
					//#if __SSE2__
 | 
				
			||||||
//        d->m = _mm_mul_ps(x->m, _mm_mul_ps(w->m, s->m));
 | 
					        d->m = _mm_mul_ps(w->m, s->m);
 | 
				
			||||||
//#else
 | 
					//#else
 | 
				
			||||||
//        d->v = x->v * w->v * s->v;
 | 
					//        d->v = w->v * s->v;
 | 
				
			||||||
//#endif
 | 
					//#endif
 | 
				
			||||||
//    }
 | 
					    }
 | 
				
			||||||
//    //Processing is done here!
 | 
					    //zero padd the the remaining fft window
 | 
				
			||||||
//    //do fft
 | 
					    memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
 | 
				
			||||||
//    fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
 | 
					
 | 
				
			||||||
//
 | 
					    //Processing is done here!
 | 
				
			||||||
//
 | 
					    //do fft
 | 
				
			||||||
//    //perform filtering - purely magnitude based
 | 
					    fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
 | 
				
			||||||
//    for(size_t j = 0;j < fft_h; j+=v_size/2){
 | 
					    //perform filtering - purely magnitude based
 | 
				
			||||||
//        //output_window[j][0]*=H[j];
 | 
					    for(size_t j = 0; j < FILTER_SIZE; j += v_size / 2){
 | 
				
			||||||
//        //output_window[j][1]*=H[j];
 | 
					        //output_window[j][0]*=H[j];
 | 
				
			||||||
//        float_vector_t *d = (float_vector_t*)(output_window+j);
 | 
					        //output_window[j][1]*=H[j];
 | 
				
			||||||
//        float_vector_t h;
 | 
					        float_vector_t *d = (float_vector_t*)( ((float *) output_window) + 2 * j);
 | 
				
			||||||
//        h.f[0] = h.f[1] = H[j];
 | 
					        float_vector_t h;
 | 
				
			||||||
//        h.f[2] = h.f[3] = H[j+1];
 | 
					        h.f[0] = h.f[1] = H[j];
 | 
				
			||||||
 | 
					        h.f[2] = h.f[3] = H[j + 1];
 | 
				
			||||||
//#if __SSE2__
 | 
					//#if __SSE2__
 | 
				
			||||||
//        d->m = _mm_mul_ps(d->m, h.m);
 | 
					        d->m = _mm_mul_ps(d->m, h.m);
 | 
				
			||||||
//#else
 | 
					//#else
 | 
				
			||||||
//        d->v = d->v*h->v;
 | 
					//        d->v = d->v * h.v;
 | 
				
			||||||
//#endif
 | 
					//#endif
 | 
				
			||||||
//    }
 | 
					    }
 | 
				
			||||||
//    //inverse fft
 | 
					
 | 
				
			||||||
//    fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
 | 
					    //inverse fft
 | 
				
			||||||
//
 | 
					    fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
 | 
				
			||||||
//    ////debug: tests overlaping add
 | 
					
 | 
				
			||||||
//    ////and negates ALL PREVIOUS processing
 | 
					    ////debug: tests overlaping add
 | 
				
			||||||
//    ////yields a perfect reconstruction if COLA is held
 | 
					    ////and negates ALL PREVIOUS processing
 | 
				
			||||||
//    //for(size_t j = 0; j < u->window_size; ++j){
 | 
					    ////yields a perfect reconstruction if COLA is held
 | 
				
			||||||
//    //    dst[j] = W[j]*src[j];
 | 
					    //for(size_t j = 0; j < u->window_size; ++j){
 | 
				
			||||||
//    //}
 | 
					    //    dst[j] = W[j] * src[j];
 | 
				
			||||||
//
 | 
					    //}
 | 
				
			||||||
//    //overlap add and preserve overlap component from this window (linear phase)
 | 
					
 | 
				
			||||||
//    for(size_t j = 0; j < overlap_size; j+=v_size){
 | 
					    //overlap add and preserve overlap component from this window (linear phase)
 | 
				
			||||||
//        //dst[j]+=overlap[j];
 | 
					    for(size_t j = 0; j < overlap_size; j += v_size){
 | 
				
			||||||
//        //overlap[j]+=dst[j+R];
 | 
					        //dst[j]+=overlap[j];
 | 
				
			||||||
//        float_vector_t *d = (float_vector_t*)(dst+j);
 | 
					        //overlap[j]+=dst[j+R];
 | 
				
			||||||
//        float_vector_t *o = (float_vector_t*)(overlap+j);
 | 
					        float_vector_t *d = (float_vector_t*)(dst + j);
 | 
				
			||||||
 | 
					        float_vector_t *o = (float_vector_t*)(overlap + j);
 | 
				
			||||||
//#if __SSE2__
 | 
					//#if __SSE2__
 | 
				
			||||||
//        d->m = _mm_add_ps(d->m, o->m);
 | 
					        d->m = _mm_add_ps(d->m, o->m);
 | 
				
			||||||
//        o->m = ((float_vector_t*)(dst+u->R+j))->m;
 | 
					        o->m = ((float_vector_t*)(dst + u->R + j))->m;
 | 
				
			||||||
//#else
 | 
					//#else
 | 
				
			||||||
//        d->v = d->v+o->v;
 | 
					//        d->v = d->v + o->v;
 | 
				
			||||||
//        o->v = ((float_vector_t*)(dst+u->R+j))->v;
 | 
					//        o->v = ((float_vector_t*)(dst + u->R + j))->v;
 | 
				
			||||||
//#endif
 | 
					//#endif
 | 
				
			||||||
//    }
 | 
					    }
 | 
				
			||||||
//    //memcpy(overlap, dst+u->R, u->overlap_size*sizeof(float));
 | 
					    //memcpy(overlap, dst+u->R, u->overlap_size * sizeof(float)); //overlap preserve (debug)
 | 
				
			||||||
//
 | 
					    //zero out the bit beyond the real overlap so we don't add garbage next iteration
 | 
				
			||||||
//    //////debug: tests if basic buffering works
 | 
					    memset(overlap + u->overlap_size, 0, overlap_size - u->overlap_size);
 | 
				
			||||||
//    //////shouldn't modify the signal AT ALL (beyond roundoff)
 | 
					
 | 
				
			||||||
//    //for(size_t j = 0; j < u->window_size; ++j){
 | 
					    ////debug: tests if basic buffering works
 | 
				
			||||||
//    //    dst[j] = src[j];
 | 
					    ////shouldn't modify the signal AT ALL (beyond roundoff)
 | 
				
			||||||
//    //}
 | 
					    //for(size_t j = 0; j < u->window_size; ++j){
 | 
				
			||||||
//
 | 
					    //    dst[j] = src[j];
 | 
				
			||||||
//    //preseve the needed input for the next window's overlap
 | 
					    //}
 | 
				
			||||||
//    memmove(src, src + u->R,
 | 
					
 | 
				
			||||||
//        u->overlap_size * sizeof(float)
 | 
					    //preseve the needed input for the next window's overlap
 | 
				
			||||||
//    );
 | 
					    memmove(src, src + u->R,
 | 
				
			||||||
//}
 | 
					        (u->samples_gathered - u->R) * sizeof(float)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void process_samples(struct userdata *u, pa_memchunk *tchunk){
 | 
					static void process_samples(struct userdata *u, pa_memchunk *tchunk){
 | 
				
			||||||
    size_t fs = pa_frame_size(&(u->sink->sample_spec));
 | 
					    size_t fs = pa_frame_size(&(u->sink->sample_spec));
 | 
				
			||||||
| 
						 | 
					@ -685,7 +677,7 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
 | 
				
			||||||
            //invalidate the output q
 | 
					            //invalidate the output q
 | 
				
			||||||
            pa_memblockq_seek(u->input_q, - (int64_t) amount, PA_SEEK_RELATIVE, TRUE);
 | 
					            pa_memblockq_seek(u->input_q, - (int64_t) amount, PA_SEEK_RELATIVE, TRUE);
 | 
				
			||||||
            pa_log("Resetting filter");
 | 
					            pa_log("Resetting filter");
 | 
				
			||||||
            reset_filter(u);
 | 
					            //reset_filter(u); //this is the "proper" thing to do...
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -814,33 +806,35 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
 | 
				
			||||||
static void pack(char **strs, size_t len, char **packed, size_t *length){
 | 
					static void pack(char **strs, size_t len, char **packed, size_t *length){
 | 
				
			||||||
    size_t t_len = 0;
 | 
					    size_t t_len = 0;
 | 
				
			||||||
    size_t headers = (1+len) * sizeof(uint16_t);
 | 
					    size_t headers = (1+len) * sizeof(uint16_t);
 | 
				
			||||||
    size_t offset = sizeof(uint16_t);
 | 
					    char *p;
 | 
				
			||||||
    for(size_t i = 0; i < len; ++i){
 | 
					    for(size_t i = 0; i < len; ++i){
 | 
				
			||||||
        t_len += strlen(strs[i]);
 | 
					        t_len += strlen(strs[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *length = headers + t_len;
 | 
					    *length = headers + t_len;
 | 
				
			||||||
    *packed = pa_xmalloc0(*length);
 | 
					    p = *packed = pa_xmalloc0(*length);
 | 
				
			||||||
    ((uint16_t *) *packed)[0] = (uint16_t) len;
 | 
					    *((uint16_t *) p) = (uint16_t) len;
 | 
				
			||||||
 | 
					    p += sizeof(uint16_t);
 | 
				
			||||||
    for(size_t i = 0; i < len; ++i){
 | 
					    for(size_t i = 0; i < len; ++i){
 | 
				
			||||||
        uint16_t l = strlen(strs[i]);
 | 
					        uint16_t l = strlen(strs[i]);
 | 
				
			||||||
        *((uint16_t *)(*packed + offset)) = l;
 | 
					        *((uint16_t *) p) = (uint16_t) l;
 | 
				
			||||||
        offset += sizeof(uint16_t);
 | 
					        p += sizeof(uint16_t);
 | 
				
			||||||
        memcpy(*packed + offset, strs[i], l);
 | 
					        memcpy(p, strs[i], l);
 | 
				
			||||||
        offset += l;
 | 
					        p += l;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static void unpack(char *str, size_t length, char ***strs, size_t *len){
 | 
					static void unpack(char *str, size_t length, char ***strs, size_t *len){
 | 
				
			||||||
    size_t offset = sizeof(uint16_t);
 | 
					    char *p = str;
 | 
				
			||||||
    *len = ((uint16_t *)str)[0];
 | 
					    *len = *((uint16_t *) p);
 | 
				
			||||||
 | 
					    p += sizeof(uint16_t);
 | 
				
			||||||
    *strs = pa_xnew(char *, *len);
 | 
					    *strs = pa_xnew(char *, *len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(size_t i = 0; i < *len; ++i){
 | 
					    for(size_t i = 0; i < *len; ++i){
 | 
				
			||||||
        size_t l = *((uint16_t *)(str+offset));
 | 
					        size_t l = *((uint16_t *) p);
 | 
				
			||||||
        size_t e = PA_MIN(offset + l, length) - offset;
 | 
					        p += sizeof(uint16_t);
 | 
				
			||||||
        offset = PA_MIN(offset + sizeof(uint16_t), length);
 | 
					        (*strs)[i] = pa_xnew(char, l + 1);
 | 
				
			||||||
        (*strs)[i] = pa_xnew(char, e + 1);
 | 
					        memcpy((*strs)[i], p, l);
 | 
				
			||||||
        memcpy((*strs)[i], str + offset, e);
 | 
					        (*strs)[i][l] = '\0';
 | 
				
			||||||
        (*strs)[i][e] = '\0';
 | 
					        p += l;
 | 
				
			||||||
        offset += l;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static void save_profile(struct userdata *u, size_t channel, char *name){
 | 
					static void save_profile(struct userdata *u, size_t channel, char *name){
 | 
				
			||||||
| 
						 | 
					@ -885,17 +879,17 @@ static void save_state(struct userdata *u){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pack(u->base_profiles, u->channels, &packed, &packed_length);
 | 
					    pack(u->base_profiles, u->channels, &packed, &packed_length);
 | 
				
			||||||
    state = (float *) pa_xmalloc0(filter_state_size + packed_length);
 | 
					    state = (float *) pa_xmalloc0(filter_state_size + packed_length);
 | 
				
			||||||
 | 
					    memcpy(state + FILTER_STATE_SIZE, packed, packed_length);
 | 
				
			||||||
 | 
					    pa_xfree(packed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(size_t c = 0; c < u->channels; ++c){
 | 
					    for(size_t c = 0; c < u->channels; ++c){
 | 
				
			||||||
        a_i = pa_aupdate_read_begin(u->a_H[c]);
 | 
					        a_i = pa_aupdate_read_begin(u->a_H[c]);
 | 
				
			||||||
        state[c * CHANNEL_PROFILE_SIZE] = u->Xs[a_i][c];
 | 
					        state[c * CHANNEL_PROFILE_SIZE] = u->Xs[c][a_i];
 | 
				
			||||||
        H = u->Hs[c][a_i];
 | 
					        H = u->Hs[c][a_i];
 | 
				
			||||||
        H_n = state + c * CHANNEL_PROFILE_SIZE + 1;
 | 
					        H_n = &state[c * CHANNEL_PROFILE_SIZE + 1];
 | 
				
			||||||
        memcpy(H_n, H, FILTER_SIZE * sizeof(float));
 | 
					        memcpy(H_n, H, FILTER_SIZE * sizeof(float));
 | 
				
			||||||
        pa_aupdate_read_end(u->a_H[c]);
 | 
					        pa_aupdate_read_end(u->a_H[c]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    memcpy(((char *)state) + filter_state_size, packed, packed_length);
 | 
					 | 
				
			||||||
    pa_xfree(packed);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    key.data = state_name;
 | 
					    key.data = state_name;
 | 
				
			||||||
    key.size = strlen(key.data);
 | 
					    key.size = strlen(key.data);
 | 
				
			||||||
| 
						 | 
					@ -978,13 +972,13 @@ static void load_state(struct userdata *u){
 | 
				
			||||||
                memcpy(u->Hs[c][a_i], H, FILTER_SIZE * sizeof(float));
 | 
					                memcpy(u->Hs[c][a_i], H, FILTER_SIZE * sizeof(float));
 | 
				
			||||||
                pa_aupdate_write_end(u->a_H[c]);
 | 
					                pa_aupdate_write_end(u->a_H[c]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            //unpack(((char *)value.data) + FILTER_STATE_SIZE, value.size - FILTER_STATE_SIZE, &names, &n_profs);
 | 
					            unpack(((char *)value.data) + FILTER_STATE_SIZE * sizeof(float), value.size - FILTER_STATE_SIZE * sizeof(float), &names, &n_profs);
 | 
				
			||||||
            //n_profs = PA_MIN(n_profs, u->channels);
 | 
					            n_profs = PA_MIN(n_profs, u->channels);
 | 
				
			||||||
            //for(size_t c = 0; c < n_profs; ++c){
 | 
					            for(size_t c = 0; c < n_profs; ++c){
 | 
				
			||||||
            //    pa_xfree(u->base_profiles[c]);
 | 
					                pa_xfree(u->base_profiles[c]);
 | 
				
			||||||
            //    u->base_profiles[c] = names[c];
 | 
					                u->base_profiles[c] = names[c];
 | 
				
			||||||
            //}
 | 
					            }
 | 
				
			||||||
            //pa_xfree(names);
 | 
					            pa_xfree(names);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        pa_datum_free(&value);
 | 
					        pa_datum_free(&value);
 | 
				
			||||||
    }else{
 | 
					    }else{
 | 
				
			||||||
| 
						 | 
					@ -1062,9 +1056,12 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_modargs_get_value_boolean(ma, "set_default", &u->set_default);
 | 
					    pa_modargs_get_value_boolean(ma, "set_default", &u->set_default);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u->channels = ss.channels;
 | 
					    u->channels = ss.channels;
 | 
				
			||||||
    u->fft_size = pow(2, ceil(log(ss.rate)/log(2)));//probably unstable near corner cases of powers of 2
 | 
					    u->fft_size = pow(2, ceil(log(ss.rate) / log(2)));//probably unstable near corner cases of powers of 2
 | 
				
			||||||
    pa_log_debug("fft size: %ld", u->fft_size);
 | 
					    pa_log_debug("fft size: %ld", u->fft_size);
 | 
				
			||||||
    u->window_size = 15999;
 | 
					    u->window_size = 15999;
 | 
				
			||||||
 | 
					    if(u->window_size % 2 == 0){
 | 
				
			||||||
 | 
					        u->window_size--;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    u->R = (u->window_size + 1) / 2;
 | 
					    u->R = (u->window_size + 1) / 2;
 | 
				
			||||||
    u->overlap_size = u->window_size - u->R;
 | 
					    u->overlap_size = u->window_size - u->R;
 | 
				
			||||||
    u->samples_gathered = 0;
 | 
					    u->samples_gathered = 0;
 | 
				
			||||||
| 
						 | 
					@ -1088,7 +1085,6 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
        u->a_H[c] = pa_aupdate_new();
 | 
					        u->a_H[c] = pa_aupdate_new();
 | 
				
			||||||
        u->input[c] = NULL;
 | 
					        u->input[c] = NULL;
 | 
				
			||||||
        u->overlap_accum[c] = alloc(u->overlap_size, sizeof(float));
 | 
					        u->overlap_accum[c] = alloc(u->overlap_size, sizeof(float));
 | 
				
			||||||
        memset(u->overlap_accum[c], 0, u->overlap_size*sizeof(float));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    u->output_window = alloc((FILTER_SIZE), sizeof(fftwf_complex));
 | 
					    u->output_window = alloc((FILTER_SIZE), sizeof(fftwf_complex));
 | 
				
			||||||
    u->forward_plan = fftwf_plan_dft_r2c_1d(u->fft_size, u->work_buffer, u->output_window, FFTW_ESTIMATE);
 | 
					    u->forward_plan = fftwf_plan_dft_r2c_1d(u->fft_size, u->work_buffer, u->output_window, FFTW_ESTIMATE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue