关于数据音频数据的处理

dczu110 2016-12-26 05:10:15
因为工作需要现在在研究音频数据处理的算法。本来是想在网上找找,看有没有一类可以改善IP电话语音质量的算法的,后来找到一个叫低音增强的算法,想试下这个算法能起到一个怎么样的作用,可是搜了好久没有具体的实现方案,求救无所不能的术友们,求一个该算法。顺便提多一个,在网上看到很多变音,均衡器等软件,这些软件里面的实现是用什么库进行开发,为什么他们可以做到如此强悍的功能?
...全文
373 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
rightorwrong 2016-12-27
  • 打赏
  • 举报
回复
有很多语音库,找找看有什么功能
sunny7862632 2016-12-27
  • 打赏
  • 举报
回复
引用 3 楼 dczu110 的回复:
@sunny7862632 很早看到你答复,后来在网上搜了一个FIR算法,效果也出来,不过可能是我想错了,因为针对IP电话,如果要通过软件改善语音质量,重低音不是好的选择,不知道在IP电话这块,你还有什么好的建议呢? 例外,我把fir的算法公布出来,让后面的人可以参考一下,当然代码也是人家的,这里要特别说明下。 //FirAlgs.h #ifndef FIR_ALGS_H #define FIR_ALGS_H #define FIR_ALGS_INTERNAL #define FIR_EXTERN #else #define FIR_EXTERN extern #endif FIR_EXTERN void Init_FIR_Parameter(void); FIR_EXTERN signed short ToLowPitchForVoice(float in); #endif //FirAlgs.c /**************************************************************************** * * Name: FirAlgs.c * * Synopsis: FIR filter algorithms for use in C * * Description: * * This module provides functions to implement Finite Impulse Response (FIR) * filters using a variety of algorithms. * * These functions use most or all of the following input parameters: * * input - the input sample data * ntaps - the number of taps in the filter * h[] - the FIR coefficient array * z[] - the FIR delay line array * *p_state - the "state" of the filter; initialize this to 0 before * the first call * * The functions fir_basic, fir_shuffle, and fir_circular are not very * efficient in C, and are provided here mainly to illustrate FIR * algorithmic concepts. However, the functions fir_split,fir_double_z * and fir_double_h are all fairly efficient ways to implement FIR filters * in C. * * Copyright 2000 by Grant R. Griffin * * Thanks go to contributors of comp.dsp for teaching me some of these * techniques, and to Jim Thomas for his review and great suggestions. * * The Wide Open License (WOL) * * Permission to use, copy, modify, distribute and sell this software and its * documentation for any purpose is hereby granted without fee,provided that * the above copyright notice and this license appear in all source copies. * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF * ANY KIND. See http://www.dspguru.com/wol.htm for more information. * *****************************************************************************/ #include <stdio.h> #ifdef WIN32 #include <conio.h> #endif #define SAMPLE float /* define the type used for data samples */ /****************************************************************************/ /* clear: zeroize a FIR delay line */ /****************************************************************************/ void clear(int ntaps, SAMPLE z[]) { int ii; for (ii = 0; ii < ntaps; ii++) { z[ii] = 0; } } /**************************************************************************** * fir_basic: Does the basic FIR algorithm: store input sample, calculate * output sample, move delay line *****************************************************************************/ SAMPLE fir_basic(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[]) { int ii; SAMPLE accum; /* store input at the beginning of the delay line */ z[0] = input; /* calc FIR */ accum = 0; for (ii = 0; ii < ntaps; ii++) { accum += h[ii] * z[ii]; } /* shift delay line */ for (ii = ntaps - 2; ii >= 0; ii--) { z[ii + 1] = z[ii]; } return accum; } /**************************************************************************** * fir_circular: This function illustrates the use of "circular" buffers * in FIR implementations. The advantage of circular buffers is that they * alleviate the need to move data samples around in the delay line (as * was done in all the functions above). Most DSP microprocessors implement * circular buffers in hardware, which allows a single FIR tap can be * calculated in a single instruction. That works fine when programming in * assembly, but since C doesn't have any constructs to represent circular * buffers, you need to "fake" them in C by adding an extra "if" statement * inside the FIR calculation, even if the DSP processor provides hardware to * implement them without overhead. *****************************************************************************/ SAMPLE fir_circular(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[], int *p_state) { int ii, state; SAMPLE accum; state = *p_state; /* copy the filter's state to a local */ /* store input at the beginning of the delay line */ z[state] = input; if (++state >= ntaps) { /* incr state and check for wrap */ state = 0; } /* calc FIR and shift data */ accum = 0; for (ii = ntaps - 1; ii >= 0; ii--) { accum += h[ii] * z[state]; if (++state >= ntaps) { /* incr state and check for wrap */ state = 0; } } *p_state = state; /* return new state to caller */ return accum; } /**************************************************************************** * fir_shuffle: This is like fir_basic, except that data is shuffled by * moving it _inside_ the calculation loop. This is similar to the MACD * instruction on TI's fixed-point processors *****************************************************************************/ SAMPLE fir_shuffle(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[]) { int ii; SAMPLE accum; /* store input at the beginning of the delay line */ z[0] = input; /* calc FIR and shift data */ accum = h[ntaps - 1] * z[ntaps - 1]; for (ii = ntaps - 2; ii >= 0; ii--) { accum += h[ii] * z[ii]; z[ii + 1] = z[ii]; } return accum; } /**************************************************************************** * fir_split: This splits the calculation into two parts so the circular * buffer logic doesn't have to be done inside the calculation loop *****************************************************************************/ SAMPLE fir_split(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[],int *p_state) { int ii, end_ntaps, state = *p_state; SAMPLE accum; SAMPLE const *p_h; SAMPLE *p_z; /* setup the filter */ accum = 0; p_h = h; /* calculate the end part */ p_z = z + state; *p_z = input; end_ntaps = ntaps - state; for (ii = 0; ii < end_ntaps; ii++) { accum += *p_h++ * *p_z++; } /* calculate the beginning part */ p_z = z; for (ii = 0; ii < state; ii++) { accum += *p_h++ * *p_z++; } /* decrement the state, wrapping if below zero */ if (--state < 0) { state += ntaps; } *p_state = state; /* return new state to caller */ return accum; } /**************************************************************************** * fir_double_z: double the delay line so the FIR calculation always * operates on a flat buffer *****************************************************************************/ SAMPLE fir_double_z(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[],int *p_state) { SAMPLE accum; int ii, state = *p_state; SAMPLE const *p_h, *p_z; /* store input at the beginning of the delay line as well as ntaps more */ z[state] = z[state + ntaps] = input; /* calculate the filter */ p_h = h; p_z = z + state; accum = 0; for (ii = 0; ii < ntaps; ii++) { accum += *p_h++ * *p_z++; } /* decrement state, wrapping if below zero */ if (--state < 0) { state += ntaps; } *p_state = state; /* return new state to caller */ return accum; } /**************************************************************************** * fir_double_h: uses doubled coefficients (supplied by caller) so that the * filter calculation always operates on a flat buffer. *****************************************************************************/ SAMPLE fir_double_h(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[],int *p_state) { SAMPLE accum; int ii, state = *p_state; SAMPLE const *p_h, *p_z; /* store input at the beginning of the delay line */ z[state] = input; /* calculate the filter */ p_h = h + ntaps - state; p_z = z; accum = 0; for (ii = 0; ii < ntaps; ii++) { accum += *p_h++ * *p_z++; } /* decrement state, wrapping if below zero */ if (--state < 0) { state += ntaps; } *p_state = state; /* return new state to caller */ return accum; } #define NTAPS 6 #define IMP_SIZE (3 * NTAPS) static const SAMPLE sFirH[NTAPS] = { 1.0, 2.0, 3.0, 4.0, 5.0,6.0 }; static SAMPLE sFirH2[2 * NTAPS]; static SAMPLE sFirZ[2 * NTAPS]; void Init_FIR_Parameter(void) { int ii; for (ii = 0; ii < NTAPS; ii++) { sFirH2[ii] = sFirH2[ii + NTAPS] = sFirH[ii]; } clear(NTAPS, sFirZ); } signed short ToLowPitchForVoice(float in) { return (signed short)fir_basic(in,NTAPS,sFirH,sFirZ); }
fir不用这么复杂,十多行代码就搞定了,不过对于语音来说不知道管不管用。想要效果那只能分析出现问题的噪声类型,然后针对性的设计一个滤波器来处理了。
dczu110 2016-12-27
  • 打赏
  • 举报
回复
@rightorwrong 就是因为不知道有什么库,所以来这里求救万能的术友
dczu110 2016-12-27
  • 打赏
  • 举报
回复
@sunny7862632 很早看到你答复,后来在网上搜了一个FIR算法,效果也出来,不过可能是我想错了,因为针对IP电话,如果要通过软件改善语音质量,重低音不是好的选择,不知道在IP电话这块,你还有什么好的建议呢? 例外,我把fir的算法公布出来,让后面的人可以参考一下,当然代码也是人家的,这里要特别说明下。 //FirAlgs.h #ifndef FIR_ALGS_H #define FIR_ALGS_H #define FIR_ALGS_INTERNAL #define FIR_EXTERN #else #define FIR_EXTERN extern #endif FIR_EXTERN void Init_FIR_Parameter(void); FIR_EXTERN signed short ToLowPitchForVoice(float in); #endif //FirAlgs.c /**************************************************************************** * * Name: FirAlgs.c * * Synopsis: FIR filter algorithms for use in C * * Description: * * This module provides functions to implement Finite Impulse Response (FIR) * filters using a variety of algorithms. * * These functions use most or all of the following input parameters: * * input - the input sample data * ntaps - the number of taps in the filter * h[] - the FIR coefficient array * z[] - the FIR delay line array * *p_state - the "state" of the filter; initialize this to 0 before * the first call * * The functions fir_basic, fir_shuffle, and fir_circular are not very * efficient in C, and are provided here mainly to illustrate FIR * algorithmic concepts. However, the functions fir_split,fir_double_z * and fir_double_h are all fairly efficient ways to implement FIR filters * in C. * * Copyright 2000 by Grant R. Griffin * * Thanks go to contributors of comp.dsp for teaching me some of these * techniques, and to Jim Thomas for his review and great suggestions. * * The Wide Open License (WOL) * * Permission to use, copy, modify, distribute and sell this software and its * documentation for any purpose is hereby granted without fee,provided that * the above copyright notice and this license appear in all source copies. * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF * ANY KIND. See http://www.dspguru.com/wol.htm for more information. * *****************************************************************************/ #include <stdio.h> #ifdef WIN32 #include <conio.h> #endif #define SAMPLE float /* define the type used for data samples */ /****************************************************************************/ /* clear: zeroize a FIR delay line */ /****************************************************************************/ void clear(int ntaps, SAMPLE z[]) { int ii; for (ii = 0; ii < ntaps; ii++) { z[ii] = 0; } } /**************************************************************************** * fir_basic: Does the basic FIR algorithm: store input sample, calculate * output sample, move delay line *****************************************************************************/ SAMPLE fir_basic(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[]) { int ii; SAMPLE accum; /* store input at the beginning of the delay line */ z[0] = input; /* calc FIR */ accum = 0; for (ii = 0; ii < ntaps; ii++) { accum += h[ii] * z[ii]; } /* shift delay line */ for (ii = ntaps - 2; ii >= 0; ii--) { z[ii + 1] = z[ii]; } return accum; } /**************************************************************************** * fir_circular: This function illustrates the use of "circular" buffers * in FIR implementations. The advantage of circular buffers is that they * alleviate the need to move data samples around in the delay line (as * was done in all the functions above). Most DSP microprocessors implement * circular buffers in hardware, which allows a single FIR tap can be * calculated in a single instruction. That works fine when programming in * assembly, but since C doesn't have any constructs to represent circular * buffers, you need to "fake" them in C by adding an extra "if" statement * inside the FIR calculation, even if the DSP processor provides hardware to * implement them without overhead. *****************************************************************************/ SAMPLE fir_circular(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[], int *p_state) { int ii, state; SAMPLE accum; state = *p_state; /* copy the filter's state to a local */ /* store input at the beginning of the delay line */ z[state] = input; if (++state >= ntaps) { /* incr state and check for wrap */ state = 0; } /* calc FIR and shift data */ accum = 0; for (ii = ntaps - 1; ii >= 0; ii--) { accum += h[ii] * z[state]; if (++state >= ntaps) { /* incr state and check for wrap */ state = 0; } } *p_state = state; /* return new state to caller */ return accum; } /**************************************************************************** * fir_shuffle: This is like fir_basic, except that data is shuffled by * moving it _inside_ the calculation loop. This is similar to the MACD * instruction on TI's fixed-point processors *****************************************************************************/ SAMPLE fir_shuffle(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[]) { int ii; SAMPLE accum; /* store input at the beginning of the delay line */ z[0] = input; /* calc FIR and shift data */ accum = h[ntaps - 1] * z[ntaps - 1]; for (ii = ntaps - 2; ii >= 0; ii--) { accum += h[ii] * z[ii]; z[ii + 1] = z[ii]; } return accum; } /**************************************************************************** * fir_split: This splits the calculation into two parts so the circular * buffer logic doesn't have to be done inside the calculation loop *****************************************************************************/ SAMPLE fir_split(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[],int *p_state) { int ii, end_ntaps, state = *p_state; SAMPLE accum; SAMPLE const *p_h; SAMPLE *p_z; /* setup the filter */ accum = 0; p_h = h; /* calculate the end part */ p_z = z + state; *p_z = input; end_ntaps = ntaps - state; for (ii = 0; ii < end_ntaps; ii++) { accum += *p_h++ * *p_z++; } /* calculate the beginning part */ p_z = z; for (ii = 0; ii < state; ii++) { accum += *p_h++ * *p_z++; } /* decrement the state, wrapping if below zero */ if (--state < 0) { state += ntaps; } *p_state = state; /* return new state to caller */ return accum; } /**************************************************************************** * fir_double_z: double the delay line so the FIR calculation always * operates on a flat buffer *****************************************************************************/ SAMPLE fir_double_z(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[],int *p_state) { SAMPLE accum; int ii, state = *p_state; SAMPLE const *p_h, *p_z; /* store input at the beginning of the delay line as well as ntaps more */ z[state] = z[state + ntaps] = input; /* calculate the filter */ p_h = h; p_z = z + state; accum = 0; for (ii = 0; ii < ntaps; ii++) { accum += *p_h++ * *p_z++; } /* decrement state, wrapping if below zero */ if (--state < 0) { state += ntaps; } *p_state = state; /* return new state to caller */ return accum; } /**************************************************************************** * fir_double_h: uses doubled coefficients (supplied by caller) so that the * filter calculation always operates on a flat buffer. *****************************************************************************/ SAMPLE fir_double_h(SAMPLE input, int ntaps, const SAMPLE h[],SAMPLE z[],int *p_state) { SAMPLE accum; int ii, state = *p_state; SAMPLE const *p_h, *p_z; /* store input at the beginning of the delay line */ z[state] = input; /* calculate the filter */ p_h = h + ntaps - state; p_z = z; accum = 0; for (ii = 0; ii < ntaps; ii++) { accum += *p_h++ * *p_z++; } /* decrement state, wrapping if below zero */ if (--state < 0) { state += ntaps; } *p_state = state; /* return new state to caller */ return accum; } #define NTAPS 6 #define IMP_SIZE (3 * NTAPS) static const SAMPLE sFirH[NTAPS] = { 1.0, 2.0, 3.0, 4.0, 5.0,6.0 }; static SAMPLE sFirH2[2 * NTAPS]; static SAMPLE sFirZ[2 * NTAPS]; void Init_FIR_Parameter(void) { int ii; for (ii = 0; ii < NTAPS; ii++) { sFirH2[ii] = sFirH2[ii + NTAPS] = sFirH[ii]; } clear(NTAPS, sFirZ); } signed short ToLowPitchForVoice(float in) { return (signed short)fir_basic(in,NTAPS,sFirH,sFirZ); }
sunny7862632 2016-12-26
  • 打赏
  • 举报
回复
声音不就是各种滤波器?低音的简单,一个汉明低通滤波器就搞定了。

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧