Skip to content

Commit 5e336af

Browse files
committed
+ .mp3 encoder
1 parent 42eb946 commit 5e336af

File tree

35 files changed

+693
-28
lines changed

35 files changed

+693
-28
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ Contents:
3131
## Features
3232

3333
* Play audio: `.mp3`, `.ogg`(Vorbis/Opus), `.mp4`/`.mov`(AAC/ALAC/MP3), `.mkv`/`.webm`(AAC/ALAC/MP3/Vorbis/Opus/PCM), `.caf`(AAC/ALAC/PCM), `.avi`(AAC/MP3/PCM), `.ts`(AAC/MP3), `.aac`, `.mpc`; `.flac`, `.ape`, `.wv`, `.wav`.
34-
* Record audio: `.m4a`(AAC), `.aac`(AAC-LC), `.ogg`(Vorbis), `.opus`; `.flac`, `.wav`
34+
* Record audio: `.m4a`(AAC), `.aac`(AAC-LC), `.mp3`, `.ogg`(Vorbis), `.opus`; `.flac`, `.wav`
3535
* Convert audio
3636
* Broadcast audio over HTTP
3737
* List/search file meta tags; edit file tags, write ReplayGain tags (`.mp3`, `.ogg/.opus`, `.flac`)
3838
* List available audio devices
3939
* Input: file, directory, ICY/HLS/HTTP/HTTPS URL, console (stdin), playlists: `.m3u`, `.pls`, `.cue`
4040
* Command Line Interface for Desktop OS
4141
* Terminal/Console UI for interaction at runtime
42-
* GUI for Windows, Linux, Android
42+
* GUI for Windows, Linux, Android: manage your playlists and audio files
4343
* Instant startup time: very short initial delay until the audio starts playing (e.g. Linux/PulseAudio: TUI: `~25ms`, GUI: `~50ms`)
4444
* Fast (small footprint, low overhead): keeps your CPU, memory & disk I/O at absolute minimum; spends 99% of time inside codec algorithms
4545

@@ -366,6 +366,7 @@ phiola uses modified versions of these third party libraries:
366366
[libebur128](https://github.com/jiixyj/libebur128),
367367
libMAC,
368368
[libmpg123](https://mpg123.de),
369+
libmp3lame,
369370
libmpc,
370371
[libopus](https://github.com/xiph/opus),
371372
[libvorbis](https://github.com/xiph/vorbis),

alib3/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ LIBS := \
1010
fdk-aac \
1111
FLAC \
1212
EBUR128 \
13+
mp3lame \
1314
mpg123 \
1415
opus \
1516
soxr \
@@ -47,6 +48,10 @@ libMAC-phi.$(SO):
4748
$(MAKE) -f $(ALIB3)/MAC/Makefile
4849
MAC: libMAC-phi.$(SO)
4950

51+
libmp3lame-phi.$(SO):
52+
$(MAKE) -f $(ALIB3)/mp3lame/Makefile
53+
mp3lame: libmp3lame-phi.$(SO)
54+
5055
libmpg123-phi.$(SO):
5156
$(MAKE) -f $(ALIB3)/mpg123/Makefile
5257
mpg123: libmpg123-phi.$(SO)

alib3/mp3lame/Makefile

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# libmp3lame
2+
3+
include ../config.mk
4+
5+
VER := 3.100
6+
# https://sourceforge.net/projects/lame/files/lame/3.100/lame-3.100.tar.gz/download
7+
URL := https://github.com/stsaz/phiola/raw/alib3/alib3/mp3lame/lame-$(VER).tar.gz
8+
MD5SUM := 83e260acbe4389b54fe08e0bdbf7cddb
9+
PKG := $(ALIB3)/mp3lame/$(notdir $(URL))
10+
DIR := lame-$(VER)
11+
LIB := libmp3lame-phi.$(SO)
12+
13+
default: $(DIR)/config.h
14+
$(SUBMAKE) $(LIB)
15+
16+
# download
17+
$(PKG):
18+
$(CURL) -o $(PKG) $(URL)
19+
20+
# unpack
21+
$(DIR): $(PKG)
22+
echo "$(MD5SUM) *$(PKG)" | md5sum -c -
23+
$(UNTAR_GZ) $(PKG)
24+
touch $@
25+
26+
_=
27+
ifeq "$(CPU)" "arm64"
28+
CONFIGURE_FLAGS := --host=aarch64-linux-gnu
29+
endif
30+
ifeq "$(SYS)" "android"
31+
CONFIGURE_ENV := CC="$(C_DIR)/clang" CFLAGS="$(A_CFLAGS)"
32+
endif
33+
$(DIR)/config.h: | $(DIR)
34+
cd $(DIR) && $(CONFIGURE_ENV) ./configure --disable-decoder $(CONFIGURE_FLAGS)
35+
cat $@
36+
37+
# build
38+
CFLAGS += \
39+
-DHAVE_CONFIG_H \
40+
-I$(DIR) -I$(DIR)/include -I$(DIR)/libmp3lame \
41+
-ffast-math -funroll-loops
42+
43+
SRC := \
44+
$(DIR)/libmp3lame/bitstream.c \
45+
$(DIR)/libmp3lame/encoder.c \
46+
$(DIR)/libmp3lame/fft.c \
47+
$(DIR)/libmp3lame/gain_analysis.c \
48+
$(DIR)/libmp3lame/lame.c \
49+
$(DIR)/libmp3lame/newmdct.c \
50+
$(DIR)/libmp3lame/presets.c \
51+
$(DIR)/libmp3lame/psymodel.c \
52+
$(DIR)/libmp3lame/quantize.c \
53+
$(DIR)/libmp3lame/quantize_pvt.c \
54+
$(DIR)/libmp3lame/reservoir.c \
55+
$(DIR)/libmp3lame/set_get.c \
56+
$(DIR)/libmp3lame/tables.c \
57+
$(DIR)/libmp3lame/takehiro.c \
58+
$(DIR)/libmp3lame/util.c \
59+
$(DIR)/libmp3lame/vbrquantize.c \
60+
$(DIR)/libmp3lame/VbrTag.c \
61+
$(DIR)/libmp3lame/version.c
62+
63+
ifeq "$(CPU)" "amd64"
64+
SRC += $(DIR)/libmp3lame/vector/xmm_quantize_sub.c
65+
endif
66+
67+
OBJ := lame-phi.o $(SRC:.c=.o)
68+
69+
lame-phi.o: $(ALIB3)/mp3lame/lame-phi.c
70+
$(C) $(CFLAGS) $< -o $@
71+
72+
%.o: %.c
73+
$(C) $(CFLAGS) $< -o $@
74+
75+
$(DIR)/libmp3lame/vector/xmm_quantize_sub.o: $(DIR)/libmp3lame/vector/xmm_quantize_sub.c
76+
$(C) $(CFLAGS) -msse $< -o$@
77+
78+
$(LIB): $(OBJ)
79+
$(LINK) -shared $+ $(LINKFLAGS) -o $@
80+
81+
clean:
82+
$(RM) $(OBJ) $(DIR)

alib3/mp3lame/lame-phi.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/** libmp3lame interface
2+
2016, Simon Zolin */
3+
4+
#include "lame-phi.h"
5+
#include <lame.h>
6+
7+
enum {
8+
LAME_EMEM = 2,
9+
LAME_EINITPARAMS = 5,
10+
};
11+
12+
static const char *const errstr[] = {
13+
"mp3buf was too small", //-1
14+
"malloc() problem", //-2
15+
"", //-3
16+
"psycho acoustic problems", //-4
17+
18+
"lame_init_params() failed",
19+
};
20+
21+
const char* lame_errstr(int e)
22+
{
23+
e = -e - 1;
24+
if ((unsigned int)e >= sizeof(errstr) / sizeof(*errstr))
25+
return "unknown error";
26+
return errstr[e];
27+
}
28+
29+
30+
struct lame {
31+
lame_global_flags *lam;
32+
struct lame_params conf;
33+
};
34+
35+
static void logger(const char *format, va_list ap)
36+
{
37+
}
38+
39+
int lame_create(lame **plm, struct lame_params *conf)
40+
{
41+
lame *lm;
42+
43+
if (NULL == (lm = calloc(1, sizeof(lame))))
44+
return -LAME_EMEM;
45+
46+
if (NULL == (lm->lam = lame_init())) {
47+
free(lm);
48+
return -LAME_EMEM;
49+
}
50+
51+
lame_set_errorf(lm->lam, &logger);
52+
lame_set_debugf(lm->lam, &logger);
53+
lame_set_msgf(lm->lam, &logger);
54+
55+
lame_set_num_channels(lm->lam, conf->channels);
56+
lame_set_in_samplerate(lm->lam, conf->rate);
57+
lame_set_quality(lm->lam, 2);
58+
59+
if (conf->quality < 10) {
60+
lame_set_VBR(lm->lam, vbr_default);
61+
lame_set_VBR_q(lm->lam, conf->quality);
62+
} else {
63+
lame_set_preset(lm->lam, conf->quality);
64+
lame_set_VBR(lm->lam, vbr_off);
65+
}
66+
67+
if (-1 == lame_init_params(lm->lam)) {
68+
lame_free(lm);
69+
return -LAME_EINITPARAMS;
70+
}
71+
72+
lm->conf = *conf;
73+
*plm = lm;
74+
return 0;
75+
}
76+
77+
void lame_free(lame *lm)
78+
{
79+
if (!lm) return;
80+
lame_close(lm->lam);
81+
free(lm);
82+
}
83+
84+
int lame_encode(lame *lm, const void **pcm, unsigned int samples, char *buf, size_t cap)
85+
{
86+
int r = 0;
87+
88+
if (samples == 0) {
89+
return lame_encode_flush(lm->lam, (void*)buf, cap);
90+
}
91+
92+
if (lm->conf.interleaved) {
93+
//16:
94+
r = lame_encode_buffer_interleaved(lm->lam, (void*)pcm[0], samples, (void*)buf, cap);
95+
96+
} else {
97+
const void *ch2 = (lm->conf.channels == 1) ? NULL : pcm[1];
98+
99+
switch (lm->conf.format) {
100+
case 16:
101+
r = lame_encode_buffer(lm->lam, pcm[0], ch2, samples, (void*)buf, cap);
102+
break;
103+
104+
case 32: //float
105+
r = lame_encode_buffer_ieee_float(lm->lam, pcm[0], ch2, samples, (void*)buf, cap);
106+
break;
107+
}
108+
}
109+
110+
return r;
111+
}
112+
113+
int lame_lametag(lame *lm, char *buf, size_t cap)
114+
{
115+
return lame_get_lametag_frame(lm->lam, (void*)buf, cap);
116+
}
117+
118+
int id3tag_write_v1(lame_global_flags * gfp){}
119+
int id3tag_write_v2(lame_global_flags * gfp){}

alib3/mp3lame/lame-phi.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/** libmp3lame interface
2+
2016, Simon Zolin */
3+
4+
#include <stdlib.h>
5+
6+
#ifdef WIN32
7+
#define _EXPORT __declspec(dllexport)
8+
#else
9+
#define _EXPORT __attribute__((visibility("default")))
10+
#endif
11+
12+
typedef struct lame lame;
13+
14+
struct lame_params {
15+
unsigned format;
16+
unsigned interleaved;
17+
unsigned channels;
18+
unsigned rate;
19+
unsigned quality;
20+
};
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
_EXPORT const char* lame_errstr(int e);
27+
28+
/**
29+
Return 0 on success. */
30+
_EXPORT int lame_create(lame **lm, struct lame_params *conf);
31+
32+
_EXPORT void lame_free(lame *lm);
33+
34+
/**
35+
Return the number of bytes written;
36+
0 if more data is needed;
37+
<0 on error. */
38+
_EXPORT int lame_encode(lame *lm, const void **pcm, unsigned int samples, char *buf, size_t cap);
39+
40+
/** Get LAME-tag frame. */
41+
_EXPORT int lame_lametag(lame *lm, char *buf, size_t cap);
42+
43+
#ifdef __cplusplus
44+
}
45+
#endif
46+
47+
#undef _EXPORT

android/phiola/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
applicationId "com.github.stsaz.phiola"
99
minSdkVersion 16
1010
targetSdk 33
11-
versionCode 20607
12-
versionName '2.6-rc7'
11+
versionCode 20608
12+
versionName '2.6.8'
1313
}
1414

1515
buildFeatures {

android/phiola/src/main/java/com/github/stsaz/phiola/ConvertActivity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
9595

9696
b.sbOpusQ.setEnabled(!checked);
9797
b.eOpusQ.setEnabled(!checked);
98+
99+
b.eMp3Q.setEnabled(!checked);
98100
});
99101

100102
b.bStart.setOnClickListener((v) -> convert());
@@ -179,6 +181,8 @@ private void load() {
179181
b.sbOpusQ.setProgress(opus_q_progress(core.setts.conv_opus_quality));
180182
b.eOpusQ.setText(core.int_to_str(core.setts.conv_opus_quality));
181183

184+
b.eMp3Q.setText(core.int_to_str(core.setts.conv_mp3_quality));
185+
182186
b.swCopy.setChecked(core.setts.conv_copy);
183187

184188
b.swPreserveDate.setChecked(core.setts.conv_file_date_preserve);
@@ -211,6 +215,10 @@ private void save() {
211215
if (v != 0)
212216
core.setts.conv_opus_quality = v;
213217

218+
v = core.str_to_uint(b.eMp3Q.getText().toString(), -1);
219+
if (v >= 0)
220+
core.setts.conv_mp3_quality = v;
221+
214222
core.setts.conv_file_date_preserve = b.swPreserveDate.isChecked();
215223
core.setts.conv_new_add_list = b.swPlAdd.isChecked();
216224
}
@@ -250,6 +258,7 @@ private void convert() {
250258
p.sample_rate = core.str_to_uint(b.eSampleRate.getText().toString(), 0);
251259
p.aac_quality = core.setts.conv_aac_quality;
252260
p.opus_quality = core.setts.conv_opus_quality;
261+
p.mp3_quality = core.setts.conv_mp3_quality;
253262

254263
int iformat = b.spOutExt.getSelectedItemPosition();
255264
p.format = CoreSettings.conv_encoders[iformat];

android/phiola/src/main/java/com/github/stsaz/phiola/Phiola.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ interface PlayObserver {
5151
AF_AAC_HE2 = 2,
5252
AF_FLAC = 3,
5353
AF_OPUS = 4,
54-
AF_OPUS_VOICE = 5;
54+
AF_OPUS_VOICE = 5,
55+
AF_MP3 = 6;
5556

5657
static class ConvertParams {
5758
ConvertParams() {
@@ -79,6 +80,7 @@ static class ConvertParams {
7980
int sample_rate;
8081
int aac_quality;
8182
int opus_quality;
83+
int mp3_quality;
8284
long q_add_remove;
8385
int q_pos;
8486
String trash_dir_rel;

0 commit comments

Comments
 (0)