Skip to content

Commit 1346f4b

Browse files
committed
Auto push on 2024-05-05 10:49:14
1 parent c9c1480 commit 1346f4b

File tree

9 files changed

+947
-0
lines changed

9 files changed

+947
-0
lines changed

samples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ if(OS STREQUAL "linux")
3737
add_subdirectory(${OS}/demux_mp4_file)
3838

3939
add_subdirectory(${OS}/enc_aac_adts_file)
40+
add_subdirectory(${OS}/enc_mp3_file)
41+
4042
add_subdirectory(${OS}/enc_avc_file)
4143
add_subdirectory(${OS}/enc_preset_file)
4244

samples/linux/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ Encode WAV file to AAC file in Audio Data Transport Stream (ADTS) format.
8686

8787
See [enc_aac_adts_file](./enc_aac_adts_file) for details.
8888

89+
### MP3
90+
91+
> MPEG-1 Layer 3 Audio
92+
93+
#### enc_mp3_file
94+
95+
Encode WAV file to MP3 file.
96+
97+
See [enc_mp3_file](./enc_mp3_file) for details.
98+
8999
### AVC / H.264
90100

91101
> Advanced Video Coding
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
project(enc_mp3_file)
4+
set (target enc_mp3_file)
5+
6+
add_executable(${target})
7+
8+
# Operating System
9+
string(TOLOWER ${CMAKE_SYSTEM_NAME} OS)
10+
11+
# output
12+
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../../bin/${PLATFORM})
13+
14+
# debug definitions
15+
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
16+
target_compile_definitions(${target} PUBLIC _DEBUG)
17+
endif()
18+
19+
# release definitions
20+
if (CMAKE_BUILD_TYPE STREQUAL "Release")
21+
target_compile_definitions(${target} PUBLIC NDEBUG)
22+
endif()
23+
24+
# Linux
25+
if(OS STREQUAL "linux")
26+
# common compile options
27+
target_compile_options(${target} PRIVATE -std=c++17 -MMD -MP -MF)
28+
29+
# x64 compile options
30+
if (PLATFORM STREQUAL "x64")
31+
target_compile_options(${target} PRIVATE -m64 -fPIC)
32+
endif()
33+
34+
# x86 compile options
35+
if (PLATFORM STREQUAL "x86")
36+
target_compile_options(${target} PRIVATE -m32)
37+
endif()
38+
39+
# debug compile options
40+
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
41+
target_compile_options(${target} PRIVATE -g)
42+
endif()
43+
44+
# release compile options
45+
if (CMAKE_BUILD_TYPE STREQUAL "Release")
46+
target_compile_options(${target} PRIVATE -O2 -s)
47+
endif()
48+
endif()
49+
50+
51+
# include dirs
52+
target_include_directories(${target}
53+
PUBLIC
54+
../../../sdk/include
55+
)
56+
57+
# sources
58+
file(GLOB source "./*.cpp")
59+
60+
61+
target_sources(${target}
62+
PRIVATE
63+
${source}
64+
)
65+
66+
# lib dirs
67+
target_link_directories(${target}
68+
PRIVATE
69+
# avblocks
70+
${PROJECT_SOURCE_DIR}/../../../sdk/lib/${PLATFORM}
71+
)
72+
73+
# libs
74+
if(OS STREQUAL "linux")
75+
target_link_libraries(
76+
${target}
77+
78+
# primo-avblocks
79+
libAVBlocks64.so
80+
81+
# os
82+
# pthread
83+
# rt
84+
)
85+
endif()

samples/linux/enc_mp3_file/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## enc_mp3_file
2+
3+
How to encode WAV file to MP3 file.
4+
5+
### Command Line
6+
7+
```sh
8+
enc_mp3_file --input <wav file> --output <mp3 file>
9+
```
10+
11+
### Examples
12+
13+
List options:
14+
15+
```sh
16+
./bin/x64/enc_mp3_file --help
17+
Usage: enc_mp3_file --input <wav file> --output <mp3 file>
18+
-h, --help
19+
-i, --input input WAV file
20+
-o, --output output MP3 file
21+
```
22+
23+
Encode the input file `./assets/aud/equinox-48KHz.wav` into output file `./output/enc_mp3_file/equinox-48KHz.mp3`:
24+
25+
```sh
26+
mkdir -p ./output/enc_mp3_file
27+
28+
./bin/x64/enc_mp3_file \
29+
--input ./assets/aud/equinox-48KHz.wav \
30+
--output ./output/enc_mp3_file/equinox-48KHz.mp3
31+
```
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <primo/avblocks/avb.h>
2+
3+
#include <primo/platform/reference++.h>
4+
#include <primo/platform/error_facility.h>
5+
#include <primo/platform/ustring.h>
6+
7+
#include "util.h"
8+
#include "options.h"
9+
10+
#include <cstdio>
11+
#include <iostream>
12+
#include <iomanip>
13+
#include <fstream>
14+
#include <string>
15+
16+
#include <memory.h>
17+
18+
using namespace primo::codecs;
19+
using namespace primo::avblocks;
20+
using namespace std;
21+
22+
primo::ref<MediaSocket> createOutputSocket(Options& opt)
23+
{
24+
auto socket = primo::make_ref(Library::createMediaSocket());
25+
socket->setFile(primo::ustring(opt.outputFile));
26+
socket->setStreamType(StreamType::MPEG_Audio);
27+
socket->setStreamSubType(StreamSubType::MPEG_Audio_Layer3);
28+
29+
auto pin = primo::make_ref(Library::createMediaPin());
30+
socket->pins()->add(pin.get());
31+
32+
auto asi = primo::make_ref(Library::createAudioStreamInfo());
33+
pin->setStreamInfo(asi.get());
34+
35+
asi->setStreamType(StreamType::MPEG_Audio);
36+
asi->setStreamSubType(StreamSubType::MPEG_Audio_Layer3);
37+
38+
// Change the encoding bitrate with the following line. The default bitrate is 128000. You can set it to 192000, 256000, etc.
39+
// asi->setBitrate(192000);
40+
41+
// Change the sampling rate and the number of the channels, e.g. Mono, 44.1 Khz
42+
// asi->setChannels(1);
43+
// asi->setSampleRate(44100);
44+
45+
// Change the stereo mode, e.g. Joint Stereo
46+
// pin->params()->addInt(Param::Encoder::Audio::MPEG1::StereoMode, StereoMode::Joint);
47+
48+
return socket;
49+
}
50+
51+
bool encode(Options& opt)
52+
{
53+
// create input socket
54+
primo::ref<MediaSocket> inSocket (Library::createMediaSocket());
55+
inSocket->setFile(primo::ustring(opt.inputFile));
56+
57+
// create output socket
58+
auto outSocket = createOutputSocket(opt);
59+
60+
// create transcoder
61+
auto transcoder = primo::make_ref(Library::createTranscoder());
62+
transcoder->setAllowDemoMode(true);
63+
transcoder->inputs()->add(inSocket.get());
64+
transcoder->outputs()->add(outSocket.get());
65+
66+
// transcoder will fail if output exists (by design)
67+
deleteFile(primo::ustring(opt.outputFile));
68+
69+
if (!transcoder->open())
70+
{
71+
printError("Transcoder open", transcoder->error());
72+
return false;
73+
}
74+
75+
if (!transcoder->run())
76+
{
77+
printError("Transcoder run", transcoder->error());
78+
return false;
79+
}
80+
81+
transcoder->close();
82+
83+
return true;
84+
}
85+
86+
int main(int argc, char* argv[])
87+
{
88+
Options opt;
89+
90+
switch(prepareOptions(opt, argc, argv))
91+
{
92+
case Command: return 0;
93+
case Error: return 1;
94+
case Parsed: break;
95+
}
96+
97+
Library::initialize();
98+
99+
bool result = encode(opt);
100+
101+
Library::shutdown();
102+
103+
return result ? 0 : 1;
104+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#include <primo/avblocks/avb.h>
2+
#include <primo/platform/error_facility.h>
3+
4+
#include "program_options.h"
5+
#include "util.h"
6+
#include "options.h"
7+
8+
#include <string>
9+
#include <iostream>
10+
#include <iomanip>
11+
#include <sstream>
12+
#include <filesystem>
13+
14+
namespace fs = std::filesystem;
15+
16+
using namespace std;
17+
using namespace primo::program_options;
18+
19+
void setDefaultOptions(Options& opt)
20+
{
21+
opt.inputFile = getExeDir() + "/../../assets/aud/equinox-48KHz.wav";
22+
23+
fs::path output(getExeDir() + "/../../output/enc_mp3_file");
24+
fs::create_directories(output);
25+
26+
ostringstream s;
27+
s << output.c_str() << "/equinox-48KHz.mp3";
28+
opt.outputFile = s.str();
29+
30+
}
31+
32+
void help(OptionsConfig<char>& optcfg)
33+
{
34+
cout << "enc_mp3_file --input <wav file> --output <amp3 file>" << endl;
35+
doHelp(cout, optcfg);
36+
}
37+
38+
bool validateOptions(Options& opt)
39+
{
40+
if(opt.inputFile.empty())
41+
{
42+
cout << "Input file needed" << endl;
43+
return false;
44+
}
45+
else
46+
{
47+
cout << "Input file: " << opt.inputFile << endl;
48+
}
49+
50+
if(opt.outputFile.empty())
51+
{
52+
cout << "Output file needed" << endl;
53+
return false;
54+
}
55+
else
56+
{
57+
cout << "Output file: " << opt.outputFile << endl;
58+
}
59+
60+
return true;
61+
}
62+
63+
ErrorCodes prepareOptions(Options &opt, int argc, char* argv[])
64+
{
65+
if (argc < 2)
66+
{
67+
setDefaultOptions(opt);
68+
cout << "Using defaults:\n";
69+
cout << " --input " << opt.inputFile;
70+
cout << " --output " << opt.outputFile;
71+
cout << endl;
72+
return Parsed;
73+
}
74+
75+
primo::program_options::OptionsConfig<char> optcfg;
76+
optcfg.addOptions()
77+
(("help,h"), opt.help, (""))
78+
(("input,i"), opt.inputFile, string(), ("input WAV file"))
79+
(("output,o"), opt.outputFile, string(), ("output MP3 file"));
80+
81+
try
82+
{
83+
primo::program_options::scanArgv(optcfg, argc, argv);
84+
}
85+
catch (primo::program_options::ParseFailure<char> &ex)
86+
{
87+
cout << ex.message() << endl;
88+
help(optcfg);
89+
return Error;
90+
}
91+
92+
if (opt.help)
93+
{
94+
help(optcfg);
95+
return Command;
96+
}
97+
98+
if (!validateOptions(opt))
99+
{
100+
help(optcfg);
101+
return Error;
102+
}
103+
104+
return Parsed;
105+
}

samples/linux/enc_mp3_file/options.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
enum ErrorCodes
4+
{
5+
Parsed = 0,
6+
Error,
7+
Command,
8+
};
9+
10+
struct Options
11+
{
12+
Options(): help(false){}
13+
14+
std::string inputFile;
15+
std::string outputFile;
16+
17+
bool help;
18+
};
19+
20+
ErrorCodes prepareOptions(Options &opt, int argc, char* argv[]);

0 commit comments

Comments
 (0)