这个WAV是双声道、16位的,相关的参数已经取得。
请教高手,Byte的形式存放在变量中的数据,如何分离出来,并提高音量。最好给出代码,谢谢。
31 个解决方案
#1
用DirectX应该要容易些吧,不过我对那个不怎么熟悉,抱歉帮顶了。。。
#2
有人会这个么?谢谢
#4
楼上的是说WAV格式,要是能调节音量就好了
#5
将 WAV 里面的声道数据按 8bit/16bit 值进行等比放大就是调高音量。
#6
Dim yByte() As Byte '音乐数据字节数组
ReDim yByte(my_wavData.nSize) 'my_wavData.nSize就是音乐数据的长度
Open App.Path & "\123.wav" For Binary Access Read As #1
Open App.Path & "\456.wav" For Binary Access Write As #2
X$ = Input(44, #1) '文件头长度为44
Get #1, , yByte
至此,如果这个WAV已知是16bit、双声道的,如何写入456.WAV,以提高音量?
ReDim yByte(my_wavData.nSize) 'my_wavData.nSize就是音乐数据的长度
Open App.Path & "\123.wav" For Binary Access Read As #1
Open App.Path & "\456.wav" For Binary Access Write As #2
X$ = Input(44, #1) '文件头长度为44
Get #1, , yByte
至此,如果这个WAV已知是16bit、双声道的,如何写入456.WAV,以提高音量?
#7
#8
#9
学习,帮顶!
要研究一下WAV格式,然后再去操作它.
要研究一下WAV格式,然后再去操作它.
#10
推荐使用NCTAudioStudio控件
#11
最好不用控件,对WAV的数据按字节进行操作不行么?
#12
Private Type WAVERIFF
sID As String
nSize As Long
sType As String
End Type
Private Type WAVEdata
sID As String
nSize As Long
dData As Byte
End Type
Private Type WAVEfact
sID As String
nSize As Long
dData As Long
End Type
Private Type WAVEFORMAT
nID As String
nSize As Long '值为16或18,为18时则最后又附加信息
wFormatTag As Integer '编码方式
nChannels As Integer '声道1-单声道;2-双声道
nSamplesPerSec As Long '采样频率
nAvgBytesPerSec As Long '每秒字节数
nBlockAlign As Integer '数据块对齐单位(每个采样需要的字节数)
nBitsPerSample As Integer '块调整值=声道数*采样位数/8 (注意数据类型,不是Long,微软的数据结构定义错了)
nBitsPerSample1 As String '附加信息
End Type
Dim my_wav As WAVEFORMAT
Dim my_wavfact As WAVEfact
Dim my_wavData As WAVEdata
Dim my_wavRIFF As WAVERIFF
Dim yByte() As Byte '音乐数据字节数组
Dim waveHDR(43) As Byte
Private Sub Form_Load()
'导入的声音文件Fname
Dim Fname As String
Fname = App.Path & "\888.wav"
Label3.Caption = "修改时间: " & FileDateTime(Fname)
Label1.Caption = "文件: " & Fname
Open Fname For Binary Access Read As #1
Label2.Caption = "大小: " & LOF(1) & " 字节"
Close #1
Open Fname For Binary Access Read As #1
Get #1, , waveHDR 'WAV文件的头部
Close #1
Open Fname For Binary Access Read As #1
'第一部分“RIFF”
With my_wavRIFF
.sID = Input(4, #1) '格式标志“RIFF”,4个字节
Get #1, , .nSize '文件长度LONG类型,大小等于WAV文件大小减去ID和Size所占用的字节
.sType = Input(4, #1) '“WAVE”,4个字节
End With
'第二部分“fmt ”
With my_wav
.nID = Input(4, #1) '“fmt ”,4个字节
Get #1, , .nSize 'size,值为16或18,为18时则最后又附加信息
Get #1, , .wFormatTag '编码方式
Get #1, , .nChannels '声道1-单声道;2-双声道
Get #1, , .nSamplesPerSec '采样率(单位:赫兹)典型值:11025、22050、44100、48000Hz
Get #1, , .nAvgBytesPerSec '每秒字节数
Get #1, , .nBlockAlign '数据块对齐单位(每个采样需要的字节数)设定资料区所占的byte数
Get #1, , .nBitsPerSample '块调整值=声道数*采样位数/8
If .nSize = 18 Then .nBitsPerSample1 = Input(2, #1)
End With
Label8 = my_wav.nID & " 声道:" & my_wav.nChannels & " 采样率:" & my_wav.nSamplesPerSec & _
" 每秒字节数:" & my_wav.nAvgBytesPerSec & " 每个采样点数:" & my_wav.nBitsPerSample
'第三部分
With my_wavfact
.sID = Input(4, #1) '标志"fact"
If .sID = "data" Then GoTo dataA
Get #1, , .nSize '数值为4
Get #1, , .dData
End With
dataA:
'第四部分
With my_wavData
If my_wavfact.sID = "data" Then
my_wavfact.sID = ""
.sID = "data"
Get #1, , .nSize
'Get #1, , .dData '数据暂时不读取
End If
End With
Label4 = my_wavfact.sID & my_wavData.sID & "数据长度:" & my_wavData.nSize
'以下是将相关数据处理后,写入999.WAV文件
Open App.Path & "\999.wav" For Binary Access Write As #2 '打开目标文件
Put #2, 1, waveHDR '写入文件头部
Dim a() As Byte
Dim ii As Long
Dim b As Byte
ReDim a(my_wavData.nSize) '定义WAV文件的数据长度数组
Get #1, , a
For ii = 45 To my_wavData.nSize + 44
'音频数据以128(8位)或32768(16位)两个数为音频波形中线值
'我想将音量放大50%,就应该用下边的算法了
'可以写入后的文件没有一点声音
If a(i) >= 32768 Then
a(i) = a(i) * 1.5
Else
a(i) = a(i) * 0.5
End If
Put #2, ii, a(i)
Next
Close #1
Close #2
End Sub
我的源程序是这样的,请大家看看。
#13
1)你用 Beyond Compare 2 之类的工具二进制比较两个文件,除了声道数据部分其他是否相同。
2)16位数据是两个字节,a(i) 始终是一个字节,怎么想的?
3)For ii 的循环中 i 没变过,你一直处理始终不变的 a(i)?
4)
2)16位数据是两个字节,a(i) 始终是一个字节,怎么想的?
3)For ii 的循环中 i 没变过,你一直处理始终不变的 a(i)?
4)
Get #1, , a是从文件头之后开始读取,
Put #2, ii, a(i)是从文件位置 45 开始写?
#14
16位数据是两个字节
音质方面还需要改进,请指教了。
Dim q As Byte
Dim b As Byte
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
'Debug.Print q
'对这个q 进行操作才有效,不过就是音质方面不是很饱满,放大的效果达到了
If q = 256 Then GoTo aaq
Select Case q
Case Is > 128
b = q * 0.6
Case Is < 128
b = q * 1.4
Case 128
b = q
End Select
aaq:
Put #2, ii, b
音质方面还需要改进,请指教了。
#15
音质是没什么办法的,一但达到十六位数的上限值,再想调高肯定就要牺牲音质了
#16
要用 Integer 类型 2 字节一起处理,按照你的做法
&H1280 ( 4736) -> &H1980 ( 6528)
&H8080 (-32640) -> &H8080 (-32640)
&H7090 ( 28816) -> &H9D56 (-25258)
怎么不失真?
&H1280 ( 4736) -> &H1980 ( 6528)
&H8080 (-32640) -> &H8080 (-32640)
&H7090 ( 28816) -> &H9D56 (-25258)
怎么不失真?
#17
是这样么?
Dim q As Integer
Dim b As Integer
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
'Debug.Print q
'对这个q 进行操作才有效,不过就是音质方面不是很饱满,放大的效果达到了
If q = 256 Then GoTo aaq
Select Case q
Case Is > 128
b = q * 0.6
Case Is < 128
b = q * 1.4
Case 128
b = q
End Select
aaq:
Put #2, ii, b
next
#18
Integer 的区间是 [-32768, 32767],再仔细想想!
还有要不失真地放大,应该先扫描一遍数据,求出现有波形的振幅,计算
放大比率 = 32767 / 现有振幅
然后用这个比率去放大波形。
否则波形的峰、谷可能会被切平。
还有要不失真地放大,应该先扫描一遍数据,求出现有波形的振幅,计算
放大比率 = 32767 / 现有振幅
然后用这个比率去放大波形。
否则波形的峰、谷可能会被切平。
#19
说这个原理是很容易的,能给出具体的程序么?
放大比率 = 32767 / 现有振幅
这么做,就是要将声音放大到最大。要是有原码就好了
#20
Dim q As Integer
Dim b As Integer
Dim lPosition As Long
Dim lMax As Long
Dim dScale As Double
lPosition = Seek(1)
lMax = 0
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
lMax 为 Abs(q) 的最大值
Next
dScale = 32767 / lMax
Seek #1, lPosition
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
b 为 q 按 dScale 倍率放大
Put #2, ii, b
Next
#21
lMax 为 Abs(q) 的最大值
b 为 q 按 dScale 倍率放大
这个运行效率可能太低了,要是将这2个过程写出来就好了
#22
每个都只是一行代码,不要太懒了!
#23
已经解决。不过说明一下,用VB写效率不是太高。一段不长的音乐文件,置换一下时间较长。
#24
我也碰到类似的问题,请问楼主是怎么解决音质问题的,急求。
#25
音质问题,实际上讲上没有得到解决,只不过音量是提高了,勉强能听听而已。
就是要做到音质不降低,不知道如何做。或许可能需要插入一些数据才行。
想像那个波形文件,好像应该加上一个数可能不会失真,如果用乘,貌似会出击失真。
就是要做到音质不降低,不知道如何做。或许可能需要插入一些数据才行。
想像那个波形文件,好像应该加上一个数可能不会失真,如果用乘,貌似会出击失真。
#26
我按照Tiger_Zhao说的方法做,得到的是一片杂音。还希望Tiger_Zhao能具体贴一下代码
#27
用Cool Edit Pro软件?
#28
Cool Edit Pro软件应该可以,不过想要的是代码
#29
分是给了,不过Tiger_Zhao说的做法,还是没有做出来。
#30
找到了一份C++的代码,哪位大侠可以改写成VB的代码吗。
/*---------------------------------------
method name : AmplifyPCMData
comment : 对PCM数据的音量进行放大
parameter :
pData PCM数据
nLen PCM数据的长度
nBitsPerSample 每个Sample的位数,一般为8的整数
multiple 放大倍数
result : S_OK 成功
---------------------------------------*/
int AmplifyPCMData(BYTE* pData, int nLen, int nBitsPerSample, float multiple)
{
int nCur = 0;
if (16 == nBitsPerSample)
{
while (nCur < nLen)
{
short* volum = (short*)(pData + nCur);
*volum = (*volum) * multiple;
if (*volum > SHRT_MAX)//爆音的处理
{
*volum = SHRT_MAX;
}
*(short*)(pData + nCur) = *volum ;
nCur += 2;
}
}
else if (8 == nBitsPerSample)
{
while (nCur < nLen)
{
BYTE* volum = pData + nCur;
*volum = (*volum) * multiple;
if (*volum > 255)//爆音的处理
{
*volum = 255;
}
*pData = *volum ;
nCur ++;
}
}
return S_OK;
}
#31
#1
用DirectX应该要容易些吧,不过我对那个不怎么熟悉,抱歉帮顶了。。。
#2
有人会这个么?谢谢
#3
参考:
#4
楼上的是说WAV格式,要是能调节音量就好了
#5
将 WAV 里面的声道数据按 8bit/16bit 值进行等比放大就是调高音量。
#6
Dim yByte() As Byte '音乐数据字节数组
ReDim yByte(my_wavData.nSize) 'my_wavData.nSize就是音乐数据的长度
Open App.Path & "\123.wav" For Binary Access Read As #1
Open App.Path & "\456.wav" For Binary Access Write As #2
X$ = Input(44, #1) '文件头长度为44
Get #1, , yByte
至此,如果这个WAV已知是16bit、双声道的,如何写入456.WAV,以提高音量?
ReDim yByte(my_wavData.nSize) 'my_wavData.nSize就是音乐数据的长度
Open App.Path & "\123.wav" For Binary Access Read As #1
Open App.Path & "\456.wav" For Binary Access Write As #2
X$ = Input(44, #1) '文件头长度为44
Get #1, , yByte
至此,如果这个WAV已知是16bit、双声道的,如何写入456.WAV,以提高音量?
#7
#8
#9
学习,帮顶!
要研究一下WAV格式,然后再去操作它.
要研究一下WAV格式,然后再去操作它.
#10
推荐使用NCTAudioStudio控件
#11
最好不用控件,对WAV的数据按字节进行操作不行么?
#12
Private Type WAVERIFF
sID As String
nSize As Long
sType As String
End Type
Private Type WAVEdata
sID As String
nSize As Long
dData As Byte
End Type
Private Type WAVEfact
sID As String
nSize As Long
dData As Long
End Type
Private Type WAVEFORMAT
nID As String
nSize As Long '值为16或18,为18时则最后又附加信息
wFormatTag As Integer '编码方式
nChannels As Integer '声道1-单声道;2-双声道
nSamplesPerSec As Long '采样频率
nAvgBytesPerSec As Long '每秒字节数
nBlockAlign As Integer '数据块对齐单位(每个采样需要的字节数)
nBitsPerSample As Integer '块调整值=声道数*采样位数/8 (注意数据类型,不是Long,微软的数据结构定义错了)
nBitsPerSample1 As String '附加信息
End Type
Dim my_wav As WAVEFORMAT
Dim my_wavfact As WAVEfact
Dim my_wavData As WAVEdata
Dim my_wavRIFF As WAVERIFF
Dim yByte() As Byte '音乐数据字节数组
Dim waveHDR(43) As Byte
Private Sub Form_Load()
'导入的声音文件Fname
Dim Fname As String
Fname = App.Path & "\888.wav"
Label3.Caption = "修改时间: " & FileDateTime(Fname)
Label1.Caption = "文件: " & Fname
Open Fname For Binary Access Read As #1
Label2.Caption = "大小: " & LOF(1) & " 字节"
Close #1
Open Fname For Binary Access Read As #1
Get #1, , waveHDR 'WAV文件的头部
Close #1
Open Fname For Binary Access Read As #1
'第一部分“RIFF”
With my_wavRIFF
.sID = Input(4, #1) '格式标志“RIFF”,4个字节
Get #1, , .nSize '文件长度LONG类型,大小等于WAV文件大小减去ID和Size所占用的字节
.sType = Input(4, #1) '“WAVE”,4个字节
End With
'第二部分“fmt ”
With my_wav
.nID = Input(4, #1) '“fmt ”,4个字节
Get #1, , .nSize 'size,值为16或18,为18时则最后又附加信息
Get #1, , .wFormatTag '编码方式
Get #1, , .nChannels '声道1-单声道;2-双声道
Get #1, , .nSamplesPerSec '采样率(单位:赫兹)典型值:11025、22050、44100、48000Hz
Get #1, , .nAvgBytesPerSec '每秒字节数
Get #1, , .nBlockAlign '数据块对齐单位(每个采样需要的字节数)设定资料区所占的byte数
Get #1, , .nBitsPerSample '块调整值=声道数*采样位数/8
If .nSize = 18 Then .nBitsPerSample1 = Input(2, #1)
End With
Label8 = my_wav.nID & " 声道:" & my_wav.nChannels & " 采样率:" & my_wav.nSamplesPerSec & _
" 每秒字节数:" & my_wav.nAvgBytesPerSec & " 每个采样点数:" & my_wav.nBitsPerSample
'第三部分
With my_wavfact
.sID = Input(4, #1) '标志"fact"
If .sID = "data" Then GoTo dataA
Get #1, , .nSize '数值为4
Get #1, , .dData
End With
dataA:
'第四部分
With my_wavData
If my_wavfact.sID = "data" Then
my_wavfact.sID = ""
.sID = "data"
Get #1, , .nSize
'Get #1, , .dData '数据暂时不读取
End If
End With
Label4 = my_wavfact.sID & my_wavData.sID & "数据长度:" & my_wavData.nSize
'以下是将相关数据处理后,写入999.WAV文件
Open App.Path & "\999.wav" For Binary Access Write As #2 '打开目标文件
Put #2, 1, waveHDR '写入文件头部
Dim a() As Byte
Dim ii As Long
Dim b As Byte
ReDim a(my_wavData.nSize) '定义WAV文件的数据长度数组
Get #1, , a
For ii = 45 To my_wavData.nSize + 44
'音频数据以128(8位)或32768(16位)两个数为音频波形中线值
'我想将音量放大50%,就应该用下边的算法了
'可以写入后的文件没有一点声音
If a(i) >= 32768 Then
a(i) = a(i) * 1.5
Else
a(i) = a(i) * 0.5
End If
Put #2, ii, a(i)
Next
Close #1
Close #2
End Sub
我的源程序是这样的,请大家看看。
#13
1)你用 Beyond Compare 2 之类的工具二进制比较两个文件,除了声道数据部分其他是否相同。
2)16位数据是两个字节,a(i) 始终是一个字节,怎么想的?
3)For ii 的循环中 i 没变过,你一直处理始终不变的 a(i)?
4)
2)16位数据是两个字节,a(i) 始终是一个字节,怎么想的?
3)For ii 的循环中 i 没变过,你一直处理始终不变的 a(i)?
4)
Get #1, , a是从文件头之后开始读取,
Put #2, ii, a(i)是从文件位置 45 开始写?
#14
16位数据是两个字节
音质方面还需要改进,请指教了。
Dim q As Byte
Dim b As Byte
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
'Debug.Print q
'对这个q 进行操作才有效,不过就是音质方面不是很饱满,放大的效果达到了
If q = 256 Then GoTo aaq
Select Case q
Case Is > 128
b = q * 0.6
Case Is < 128
b = q * 1.4
Case 128
b = q
End Select
aaq:
Put #2, ii, b
音质方面还需要改进,请指教了。
#15
音质是没什么办法的,一但达到十六位数的上限值,再想调高肯定就要牺牲音质了
#16
要用 Integer 类型 2 字节一起处理,按照你的做法
&H1280 ( 4736) -> &H1980 ( 6528)
&H8080 (-32640) -> &H8080 (-32640)
&H7090 ( 28816) -> &H9D56 (-25258)
怎么不失真?
&H1280 ( 4736) -> &H1980 ( 6528)
&H8080 (-32640) -> &H8080 (-32640)
&H7090 ( 28816) -> &H9D56 (-25258)
怎么不失真?
#17
是这样么?
Dim q As Integer
Dim b As Integer
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
'Debug.Print q
'对这个q 进行操作才有效,不过就是音质方面不是很饱满,放大的效果达到了
If q = 256 Then GoTo aaq
Select Case q
Case Is > 128
b = q * 0.6
Case Is < 128
b = q * 1.4
Case 128
b = q
End Select
aaq:
Put #2, ii, b
next
#18
Integer 的区间是 [-32768, 32767],再仔细想想!
还有要不失真地放大,应该先扫描一遍数据,求出现有波形的振幅,计算
放大比率 = 32767 / 现有振幅
然后用这个比率去放大波形。
否则波形的峰、谷可能会被切平。
还有要不失真地放大,应该先扫描一遍数据,求出现有波形的振幅,计算
放大比率 = 32767 / 现有振幅
然后用这个比率去放大波形。
否则波形的峰、谷可能会被切平。
#19
说这个原理是很容易的,能给出具体的程序么?
放大比率 = 32767 / 现有振幅
这么做,就是要将声音放大到最大。要是有原码就好了
#20
Dim q As Integer
Dim b As Integer
Dim lPosition As Long
Dim lMax As Long
Dim dScale As Double
lPosition = Seek(1)
lMax = 0
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
lMax 为 Abs(q) 的最大值
Next
dScale = 32767 / lMax
Seek #1, lPosition
For ii = 45 To my_wavData.nSize + 44
Get #1, , q
b 为 q 按 dScale 倍率放大
Put #2, ii, b
Next
#21
lMax 为 Abs(q) 的最大值
b 为 q 按 dScale 倍率放大
这个运行效率可能太低了,要是将这2个过程写出来就好了
#22
每个都只是一行代码,不要太懒了!
#23
已经解决。不过说明一下,用VB写效率不是太高。一段不长的音乐文件,置换一下时间较长。
#24
我也碰到类似的问题,请问楼主是怎么解决音质问题的,急求。
#25
音质问题,实际上讲上没有得到解决,只不过音量是提高了,勉强能听听而已。
就是要做到音质不降低,不知道如何做。或许可能需要插入一些数据才行。
想像那个波形文件,好像应该加上一个数可能不会失真,如果用乘,貌似会出击失真。
就是要做到音质不降低,不知道如何做。或许可能需要插入一些数据才行。
想像那个波形文件,好像应该加上一个数可能不会失真,如果用乘,貌似会出击失真。
#26
我按照Tiger_Zhao说的方法做,得到的是一片杂音。还希望Tiger_Zhao能具体贴一下代码
#27
用Cool Edit Pro软件?
#28
Cool Edit Pro软件应该可以,不过想要的是代码
#29
分是给了,不过Tiger_Zhao说的做法,还是没有做出来。
#30
找到了一份C++的代码,哪位大侠可以改写成VB的代码吗。
/*---------------------------------------
method name : AmplifyPCMData
comment : 对PCM数据的音量进行放大
parameter :
pData PCM数据
nLen PCM数据的长度
nBitsPerSample 每个Sample的位数,一般为8的整数
multiple 放大倍数
result : S_OK 成功
---------------------------------------*/
int AmplifyPCMData(BYTE* pData, int nLen, int nBitsPerSample, float multiple)
{
int nCur = 0;
if (16 == nBitsPerSample)
{
while (nCur < nLen)
{
short* volum = (short*)(pData + nCur);
*volum = (*volum) * multiple;
if (*volum > SHRT_MAX)//爆音的处理
{
*volum = SHRT_MAX;
}
*(short*)(pData + nCur) = *volum ;
nCur += 2;
}
}
else if (8 == nBitsPerSample)
{
while (nCur < nLen)
{
BYTE* volum = pData + nCur;
*volum = (*volum) * multiple;
if (*volum > 255)//爆音的处理
{
*volum = 255;
}
*pData = *volum ;
nCur ++;
}
}
return S_OK;
}