Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4846248
simple_mixer.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Subscribers
None
simple_mixer.cpp
View Options
//
// Created by yangjianli on 2019-09-09.
//
/**
* 输入一个音频和伴奏自动进行混合
* gated_loudness 当前音量
* gain 预期增益
*/
#include "iostream"
#include "WaveFile.h"
#include "math.h"
#include "ebur128.h"
#include "AudioMixer.h"
#include "alimiter.h"
#include "waves/inc/WaveFile.h"
#include "CAudioEffectsChainApi.h"
#include "string"
#include "ae_server/CAeServer.h"
#include <cstdio>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <sys/time.h>
#include "denoise/webrtc/include/WebrtcDenoise.h"
#define PROC_LEN 1024
#define DEFAULT_BASELINE_DB (float)-14.57f
int
short2float
(
short
*
pInBuf
,
int
nLen
,
float
*
pOutBuf
)
{
for
(
int
i
=
0
;
i
<
nLen
;
i
++
)
{
pOutBuf
[
i
]
=
pInBuf
[
i
]
*
1.0
/
32768
;
}
return
0
;
}
int
float2short
(
float
*
pInBuf
,
int
nLen
,
short
*
pOutBuf
)
{
for
(
int
i
=
0
;
i
<
nLen
;
i
++
)
{
pOutBuf
[
i
]
=
int
(
pInBuf
[
i
]
*
32768
);
}
return
0
;
}
/**
* 获取增益
* @param nChannel
* @param nSampleRate
* @param pData
* @param nLength
* @param gain
* @return
*/
int
ebur128_whole
(
int
nChannel
,
int
nSampleRate
,
short
*
pData
,
const
int
nLength
,
double
&
gated_loudness
,
double
&
gain
)
{
printf
(
"ebur128_init start .. %d
\n
"
,
nLength
);
ebur128_state
*
st
=
NULL
;
st
=
ebur128_init
(
nChannel
,
nSampleRate
,
EBUR128_MODE_I
);
if
(
NULL
==
st
)
{
return
-
1
;
}
int
nPos
=
0
;
int
nTmpLength
=
0
;
int
nRet
;
printf
(
"process start ..
\n
"
);
while
(
nPos
<
nLength
)
{
nTmpLength
=
PROC_LEN
;
if
(
nLength
-
nPos
<
PROC_LEN
)
{
nTmpLength
=
nLength
-
nPos
;
}
nRet
=
ebur128_add_frames_short
(
st
,
pData
+
nPos
,
nTmpLength
/
nChannel
);
if
(
nRet
!=
0
)
{
return
-
2
;
}
nPos
+=
nTmpLength
;
}
printf
(
"process ok..
\n
"
);
gated_loudness
=
-
1
;
ebur128_loudness_global
(
st
,
&
gated_loudness
);
float
db
=
(
DEFAULT_BASELINE_DB
-
gated_loudness
)
/
20.f
;
gain
=
pow
(
10
,
db
);
printf
(
"gated_loudness = %f db = %f gain = %f
\n
"
,
gated_loudness
,
db
,
gain
);
ebur128_destroy
(
&
st
);
return
0
;
}
/**
* 混合音频和伴奏
* @param pVocalIn
* @param pAccIn
* @param nLength
* @param gainVocal
* @param gainAcc
* @param pOutBuf
* @return
*/
int
mix
(
float
*
pVocalIn
,
float
*
pAccIn
,
int
nLength
,
double
gainVocal
,
double
gainAcc
,
float
*
pOutBuf
,
int
nSampleRate
,
int
nChannel
,
int
nDelay
)
{
CAudioMixer
*
cAudioMixer
=
new
CAudioMixer
();
cAudioMixer
->
init
(
nSampleRate
,
nChannel
);
cAudioMixer
->
set_acc_delay
(
nDelay
);
cAudioMixer
->
set_vocal_volume
(
int
(
gainVocal
*
50
));
cAudioMixer
->
set_acc_volume
(
int
(
gainAcc
*
50
));
int
nPos
=
0
;
int
nStep
=
1024
;
float
*
fTmp
=
new
float
[
nStep
];
cAudioMixer
->
reset
();
nPos
=
0
;
nStep
=
1024
;
int
cnt
=
0
;
while
(
nPos
<
nLength
)
{
if
(
nLength
-
nPos
<
nStep
)
{
nStep
=
nLength
-
nPos
;
}
cnt
++
;
cAudioMixer
->
process
(
pVocalIn
+
nPos
,
pAccIn
+
nPos
,
pOutBuf
+
nPos
,
nStep
);
nPos
+=
nStep
;
}
delete
cAudioMixer
;
delete
[]
fTmp
;
return
0
;
}
int
denoise_webrtc
(
short
*
pInBuf
,
int
nLength
,
int
nChannel
,
int
nSampleRate
)
{
CWebrtcDenoise
cWebrtcDenoise
;
cWebrtcDenoise
.
init
(
nSampleRate
,
nChannel
);
float
*
pTmp
=
new
float
[
nLength
];
for
(
int
i
=
0
;
i
<
nLength
;
i
++
)
{
pTmp
[
i
]
=
pInBuf
[
i
]
*
1.0
/
32768
;
}
cWebrtcDenoise
.
set_level
(
kHigh
);
int
nStep
=
512
*
nChannel
;
for
(
int
i
=
0
;
i
<
nStep
;
i
++
)
{
pTmp
[
i
]
=
pTmp
[
i
]
*
i
*
1.0
/
nStep
;
}
for
(
int
i
=
0
,
cnt
=
0
;
i
<
nLength
;
i
+=
nStep
,
cnt
++
)
{
if
(
nLength
-
i
<
nStep
)
continue
;
cWebrtcDenoise
.
process
(
pTmp
+
i
,
nStep
);
}
for
(
int
i
=
0
;
i
<
nLength
;
i
++
)
{
pInBuf
[
i
]
=
short
(
pTmp
[
i
]
*
32768
);
}
delete
[]
pTmp
;
return
0
;
}
double
calc_power_rate
(
float
*
in_data
,
int32_t
in_len
,
float
*
ref_data
,
int32_t
ref_len
)
{
double
in_power
=
0
;
double
ref_power
=
0
;
int32_t
min_len
=
in_len
>
ref_len
?
ref_len
:
in_len
;
for
(
int
i
=
0
;
i
<
min_len
;
i
++
)
{
in_power
+=
(
in_data
[
i
])
*
(
in_data
[
i
]);
ref_power
+=
(
ref_data
[
i
])
*
(
ref_data
[
i
]);
}
return
ref_power
/
in_power
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
4
)
{
printf
(
"input error! example: ./main vocal_path acc_path mix_path
\n
"
);
return
-
1
;
}
std
::
string
sVocal
=
argv
[
1
];
std
::
string
sAcc
=
argv
[
2
];
std
::
string
sMix
=
argv
[
3
];
// 读取人声
CWaveFile
*
oWaveFile
=
new
CWaveFile
(
sVocal
.
c_str
(),
false
);
float
*
pfVocalBuf
=
new
float
[
oWaveFile
->
GetTotalFrames
()
*
oWaveFile
->
GetChannels
()];
oWaveFile
->
ReadFrameAsfloat
(
pfVocalBuf
,
oWaveFile
->
GetTotalFrames
());
//读取伴奏
CWaveFile
*
oWaveFile1
=
new
CWaveFile
(
sAcc
.
c_str
(),
false
);
float
*
pfAccBuf
=
new
float
[
oWaveFile1
->
GetTotalFrames
()
*
oWaveFile1
->
GetChannels
()];
oWaveFile1
->
ReadFrameAsfloat
(
pfAccBuf
,
oWaveFile1
->
GetTotalFrames
());
if
(
oWaveFile
->
GetChannels
()
!=
oWaveFile1
->
GetChannels
())
{
printf
(
"channel not equal!
\n
"
);
return
-
1
;
}
// 混合音频和伴奏
printf
(
"mix wav:%s and acc:%s!
\n
"
,
sVocal
.
c_str
(),
sAcc
.
c_str
());
int
nOutLen
=
oWaveFile
->
GetTotalFrames
()
<
oWaveFile1
->
GetTotalFrames
()
?
oWaveFile
->
GetTotalFrames
()
:
oWaveFile1
->
GetTotalFrames
();
nOutLen
=
nOutLen
*
oWaveFile
->
GetChannels
();
float
*
pOutBuf
=
new
float
[
nOutLen
];
mix
(
pfVocalBuf
,
pfAccBuf
,
nOutLen
,
1.0
,
1.0
,
pOutBuf
,
oWaveFile
->
GetSampleRate
(),
oWaveFile
->
GetChannels
(),
0
);
//写入文件
printf
(
"write2file nLength:%d path:%s!
\n
"
,
nOutLen
,
sMix
.
c_str
());
CWaveFile
*
oWaveFile2
=
new
CWaveFile
(
sMix
.
c_str
(),
true
);
oWaveFile2
->
SetSampleFormat
(
SF_IEEE_FLOAT
);
oWaveFile2
->
SetSampleRate
(
oWaveFile
->
GetSampleRate
());
oWaveFile2
->
SetChannels
(
oWaveFile
->
GetChannels
());
oWaveFile2
->
SetupDone
();
oWaveFile2
->
WriteFrame
(
pOutBuf
,
nOutLen
/
oWaveFile
->
GetChannels
());
delete
oWaveFile
;
delete
oWaveFile1
;
delete
oWaveFile2
;
delete
[]
pfVocalBuf
;
delete
[]
pfAccBuf
;
delete
[]
pOutBuf
;
return
0
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Nov 24, 21:23 (23 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1326547
Default Alt Text
simple_mixer.cpp (6 KB)
Attached To
R350 av_svc
Event Timeline
Log In to Comment