Skip to content

Commit 36de2c6

Browse files
author
Clement Champetier
committed
Add AudioTransform: convert samples
* AudioTransform: does the same process as ColorTransform, but applied to audio. * AudioDesc: add a function to get a FrameDesc. * AudioRewrapper: use AudioTransform.
1 parent 3a719d0 commit 36de2c6

File tree

6 files changed

+156
-22
lines changed

6 files changed

+156
-22
lines changed

app/SConscript

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ audioRewrapper = env.Program(
6969
'avformat',
7070
'avcodec',
7171
'swscale',
72+
'swresample',
7273
]
7374
)
7475

app/audioRewrapper/audioRewrapper.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22
#include <iomanip>
33

44
#include <AvTranscoder/InputFile.hpp>
5+
#include <AvTranscoder/OutputFile.hpp>
6+
57
#include <AvTranscoder/AvInputStream.hpp>
68
#include <AvTranscoder/InputStreamAudio.hpp>
79
#include <AvTranscoder/OutputStreamAudio.hpp>
810

9-
#include <AvTranscoder/OutputFile.hpp>
11+
#include <AvTranscoder/AudioTransform.hpp>
12+
13+
1014

1115
void rewrapAudio( const char* inputfilename, const char* outputFilename )
1216
{
@@ -52,56 +56,65 @@ void transcodeAudio( const char* inputfilename, const char* outputFilename )
5256
InputFile inputFile( inputfilename );
5357
inputFile.analyse();
5458

59+
OutputFile outputFile( outputFilename );
60+
outputFile.setup();
61+
5562
// init audio decoders
5663
InputStreamAudio inputStreamAudio( inputFile.getStream( 0 ) );
5764
inputFile.getStream( 0 ).setBufferred( true );
58-
59-
OutputFile outputFile( outputFilename );
60-
outputFile.setup();
61-
outputFile.addAudioStream( inputFile.getStream( 0 ).getAudioDesc() );
62-
outputFile.beginWrap();
6365

66+
// init audio encoders
6467
OutputStreamAudio outputStreamAudio;
6568
AudioDesc& audioDesc = outputStreamAudio.getAudioDesc();
66-
audioDesc.setAudioCodec( "pcm_s16le" );
69+
audioDesc.setAudioCodec( "pcm_s24le" );
6770
audioDesc.setAudioParameters(
6871
inputFile.getStream( 0 ).getAudioDesc().getSampleRate(),
6972
inputFile.getStream( 0 ).getAudioDesc().getChannels(),
70-
inputFile.getStream( 0 ).getAudioDesc().getSampleFormat()
73+
AV_SAMPLE_FMT_S32//,inputFile.getStream( 0 ).getAudioDesc().getSampleFormat()
7174
);
7275

73-
DataStream codedFrame;
74-
7576
if( ! outputStreamAudio.setup( ) )
7677
{
7778
std::cout << "error during initialising audio output stream" << std::endl;
7879
exit( -1 );
7980
}
8081

81-
// Transcoding
82-
std::cout << "start transcoding" << std::endl;
82+
outputFile.addAudioStream( audioDesc );
83+
outputFile.beginWrap();
84+
85+
// init convert
86+
AudioTransform audioTransform;
87+
88+
DataStream codedFrame;
8389

90+
// start transcoding process
91+
std::cout << "start transcoding" << std::endl;
92+
93+
AudioFrame audioFrameSource( inputFile.getStream( 0 ).getAudioDesc().getFrameDesc() );
94+
AudioFrame audioFrameToEncode( audioDesc.getFrameDesc() );
95+
8496
size_t frame = 0;
85-
AudioFrameDesc audioFrameDesc;
86-
87-
AudioFrame audioFrame( audioFrameDesc );
88-
89-
while( inputStreamAudio.readNextFrame( audioFrame ) )
97+
while( inputStreamAudio.readNextFrame( audioFrameSource ) )
9098
{
91-
std::cout << "\rprocess frame " << (int)frame - 1 << std::endl << std::flush;
99+
std::cout << "\rprocess frame " << (int)frame - 1 << std::flush;
92100

93-
// convert
94-
95-
outputStreamAudio.encodeFrame( audioFrame, codedFrame );
101+
audioTransform.convert( audioFrameSource, audioFrameToEncode );
96102

103+
outputStreamAudio.encodeFrame( audioFrameToEncode, codedFrame );
104+
97105
outputFile.wrap( codedFrame, 0 );
98106

99107
++frame;
108+
// if(frame == 10*48100)
109+
// break;
100110
}
101111
std::cout << std::endl;
102112

103113
outputStreamAudio.encodeFrame( codedFrame );
104-
114+
outputFile.wrap( codedFrame, 0 );
115+
116+
// end of transcoding process
117+
105118
outputFile.endWrap();
106119
}
107120

src/AvTranscoder/AudioTransform.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "AudioTransform.hpp"
2+
#include "DatasStructures/AudioFrame.hpp"
3+
#include "common.hpp"
4+
5+
extern "C" {
6+
#ifndef __STDC_CONSTANT_MACROS
7+
#define __STDC_CONSTANT_MACROS
8+
#endif
9+
#include <libavcodec/avcodec.h>
10+
#include <libavutil/opt.h>
11+
#include <libswresample/swresample.h>
12+
#if LIBAVCODEC_VERSION_MAJOR > 54
13+
#include <libavutil/frame.h>
14+
#endif
15+
}
16+
17+
#include <stdexcept>
18+
19+
namespace avtranscoder
20+
{
21+
22+
AudioTransform::AudioTransform()
23+
: m_audioConvertContext( NULL )
24+
, m_isInit ( false )
25+
{
26+
}
27+
28+
bool AudioTransform::init( const AudioFrame& src, const AudioFrame& dst )
29+
{
30+
m_audioConvertContext = swr_alloc();
31+
32+
if( !m_audioConvertContext )
33+
{
34+
throw std::runtime_error( "unable to create audio convert context" );
35+
}
36+
37+
av_opt_set_int(m_audioConvertContext, "in_channel_layout", av_get_default_channel_layout( src.desc().getChannels() ), 0);
38+
av_opt_set_int(m_audioConvertContext, "out_channel_layout", av_get_default_channel_layout( dst.desc().getChannels() ), 0);
39+
40+
av_opt_set_int(m_audioConvertContext, "in_sample_rate", src.desc().getSampleRate(), 0);
41+
av_opt_set_int(m_audioConvertContext, "out_sample_rate", dst.desc().getSampleRate(), 0);
42+
43+
av_opt_set_int(m_audioConvertContext, "in_sample_fmt", src.desc().getSampleFormat(), 0);
44+
av_opt_set_int(m_audioConvertContext, "out_sample_fmt", dst.desc().getSampleFormat(), 0);
45+
46+
if( swr_init( m_audioConvertContext ) < 0 )
47+
{
48+
swr_free( &m_audioConvertContext );
49+
throw std::runtime_error( "unable to open audio convert context" );
50+
}
51+
52+
return true;
53+
}
54+
55+
void AudioTransform::convert( const AudioFrame& src, AudioFrame& dst )
56+
{
57+
if( ! m_isInit )
58+
{
59+
m_isInit = init( src, dst );
60+
m_isInit = true;
61+
}
62+
63+
if( dst.getSize() != src.getSize() )
64+
dst.getBuffer().resize( src.getSize(), 0 );
65+
66+
const unsigned char* srcData = src.getPtr();
67+
unsigned char* dstData = dst.getPtr();
68+
69+
swr_convert( m_audioConvertContext, &dstData, dst.getSize(), &srcData, src.getSize() );
70+
71+
dst.setNbSamples( src.getNbSamples() );
72+
}
73+
74+
}

src/AvTranscoder/AudioTransform.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef _AV_TRANSCODER_AUDIO_TRANSFORM_HPP
2+
#define _AV_TRANSCODER_AUDIO_TRANSFORM_HPP
3+
4+
#include "common.hpp"
5+
6+
class SwrContext;
7+
8+
namespace avtranscoder
9+
{
10+
11+
class AudioFrame;
12+
13+
class AvExport AudioTransform
14+
{
15+
public:
16+
AudioTransform();
17+
18+
void convert( const AudioFrame& src, AudioFrame& dst );
19+
20+
private:
21+
bool init( const AudioFrame& src, const AudioFrame& dst );
22+
23+
SwrContext* m_audioConvertContext;
24+
25+
bool m_isInit;
26+
};
27+
28+
}
29+
30+
#endif

src/AvTranscoder/DatasStructures/AudioDesc.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "AudioDesc.hpp"
2+
#include "AudioFrame.hpp"
23

34
extern "C" {
45
#ifndef __STDC_CONSTANT_MACROS
@@ -209,5 +210,16 @@ const AVSampleFormat AudioDesc::getSampleFormat() const
209210
return m_codecContext->sample_fmt;
210211
}
211212

213+
AudioFrameDesc AudioDesc::getFrameDesc() const
214+
{
215+
AudioFrameDesc audioFrameDesc;
216+
217+
audioFrameDesc.setChannels( m_codecContext->channels );
218+
audioFrameDesc.setSampleRate( m_codecContext->sample_rate );
219+
audioFrameDesc.setSampleFormat( m_codecContext->sample_fmt );
220+
221+
return audioFrameDesc;
222+
}
223+
212224

213225
}

src/AvTranscoder/DatasStructures/AudioDesc.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ extern "C" {
1818
namespace avtranscoder
1919
{
2020

21+
class AudioFrameDesc;
22+
2123
class AvExport AudioDesc
2224
{
2325
public:
@@ -48,6 +50,8 @@ class AvExport AudioDesc
4850
AVCodecContext* getCodecContext() const { return m_codecContext; }
4951
#endif
5052

53+
AudioFrameDesc getFrameDesc() const;
54+
5155
private:
5256
void initCodecContext( );
5357

0 commit comments

Comments
 (0)