Skip to content

Commit 86cf113

Browse files
committed
feat: 16K 对齐
1 parent 5c2a5a9 commit 86cf113

5 files changed

Lines changed: 151 additions & 41 deletions

File tree

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ android {
1111
applicationId = "me.yun.silk.app"
1212
minSdk = 26
1313
targetSdk = 34
14-
versionCode = 1
15-
versionName = "1.0.0"
14+
versionCode = 3
15+
versionName = "1.0.3"
1616
}
1717

1818
buildTypes {

silk-codec/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ android {
1010
defaultConfig {
1111
minSdk = 26
1212
ndk {
13-
abiFilters.addAll(listOf("arm64-v8a"))
13+
abiFilters.addAll(listOf("arm64-v8a", "armeabi-v7a"))
1414
}
1515
}
1616

@@ -43,7 +43,7 @@ publishing {
4343
create<MavenPublication>("release") {
4444
groupId = "com.github.YunJavaPro"
4545
artifactId = "silk-codec"
46-
version = "1.0.2"
46+
version = "1.0.3"
4747
afterEvaluate {
4848
from(components["release"])
4949
}

silk-codec/src/main/java/me/yun/silk/SilkCodec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public class SilkCodec {
66
public static final long MAX_DURATION_MS = 60_000L;
77

88
static {
9-
System.loadLibrary("silk");
9+
System.loadLibrary("silk_codec");
1010
}
1111

1212
/**

silk-codec/src/main/jni/Android.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
LOCAL_PATH := $(call my-dir)
22

33
include $(CLEAR_VARS)
4-
LOCAL_MODULE := silk
4+
LOCAL_MODULE := silk_codec
55

66
LOCAL_C_INCLUDES := \
77
$(LOCAL_PATH)/silk/interface \

silk-codec/src/main/jni/silk_codec.cpp

Lines changed: 145 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdio.h>
1111
#include <stdlib.h>
1212
#include <string.h>
13+
#include <malloc.h>
1314

1415
/* ==================== Silk SDK 接口 ==================== */
1516
#include "silk/interface/SKP_Silk_SDK_API.h"
@@ -133,6 +134,36 @@
133134
*/
134135
#define SILK_USE_IN_BAND_FEC 0
135136

137+
/* ==================== 16KB 内存对齐 ==================== */
138+
/**
139+
* 16KB 对齐常量
140+
* 用于 ARM 缓存行优化和 SIMD 指令对齐需求
141+
*/
142+
#define ALIGN_16K (16 * 1024)
143+
144+
/**
145+
* 16KB 对齐的内存分配
146+
* 使用 posix_memalign 确保 16KB 对齐
147+
*
148+
* @param size 需要分配的字节数
149+
* @return 对齐后的内存指针,失败返回 NULL
150+
*/
151+
static void* aligned_malloc_16k(size_t size) {
152+
void* ptr = NULL;
153+
if (posix_memalign(&ptr, ALIGN_16K, size) != 0) {
154+
return NULL;
155+
}
156+
return ptr;
157+
}
158+
159+
/**
160+
* 释放对齐内存
161+
* 与 aligned_malloc_16k 配合使用
162+
*/
163+
static void aligned_free_16k(void* ptr) {
164+
free(ptr);
165+
}
166+
136167
/* ==================== 微信 Silk 文件头 ==================== */
137168
static const unsigned char WECHAT_SILK_HEADER[] = {0x02, '#', '!', 'S', 'I',
138169
'L', 'K', '_', 'V', '3'};
@@ -456,12 +487,19 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_mp3ToSilk(
456487
encCtrl.useDTX = SILK_USE_DTX;
457488
encCtrl.useInBandFEC = SILK_USE_IN_BAND_FEC;
458489

459-
/* PCM 缓冲区 */
490+
/* PCM 缓冲区 - 16KB 对齐 */
460491
#define READ_FRAMES 1152
461-
short *pcm_buffer = (short *)malloc(frameSize * 10 * sizeof(short));
492+
short *pcm_buffer = (short *)aligned_malloc_16k(frameSize * 10 * sizeof(short));
462493
int pcm_buffer_len = 0;
463494
drmp3_int16 mp3_pcm[READ_FRAMES * 2];
464495

496+
if (!pcm_buffer) {
497+
drmp3_uninit(&mp3);
498+
env->ReleaseStringUTFChars(mp3Path, in_p);
499+
env->ReleaseStringUTFChars(silkPath, out_p);
500+
return -303;
501+
}
502+
465503
/* 编码循环 */
466504
while (1) {
467505
int frames_read = drmp3_read_pcm_frames_s16(&mp3, READ_FRAMES, mp3_pcm);
@@ -505,7 +543,7 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_mp3ToSilk(
505543
fwrite(SILK_TERMINATOR, 1, SILK_TERMINATOR_LEN, fout);
506544

507545
/* 资源释放 */
508-
free(pcm_buffer);
546+
aligned_free_16k(pcm_buffer);
509547
free(psEnc);
510548
drmp3_uninit(&mp3);
511549
fclose(fout);
@@ -566,9 +604,20 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_wavToSilk(
566604
encCtrl.useDTX = SILK_USE_DTX;
567605
encCtrl.useInBandFEC = SILK_USE_IN_BAND_FEC;
568606

569-
/* PCM 缓冲区 */
570-
short *readBuf = (short *)malloc(frameSize * wav_channels * sizeof(short));
571-
short *monoBuf = (short *)malloc(frameSize * sizeof(short));
607+
/* PCM 缓冲区 - 16KB 对齐 */
608+
short *readBuf = (short *)aligned_malloc_16k(frameSize * wav_channels * sizeof(short));
609+
short *monoBuf = (short *)aligned_malloc_16k(frameSize * sizeof(short));
610+
611+
if (!readBuf || !monoBuf) {
612+
if (readBuf) aligned_free_16k(readBuf);
613+
if (monoBuf) aligned_free_16k(monoBuf);
614+
drwav_uninit(&wav);
615+
fclose(fout);
616+
free(psEnc);
617+
env->ReleaseStringUTFChars(wavPath, in_p);
618+
env->ReleaseStringUTFChars(silkPath, out_p);
619+
return -502;
620+
}
572621

573622
/* 编码循环 */
574623
while (drwav_read_pcm_frames_s16(&wav, frameSize, readBuf) ==
@@ -599,8 +648,8 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_wavToSilk(
599648
fwrite(SILK_TERMINATOR, 1, SILK_TERMINATOR_LEN, fout);
600649

601650
/* 资源释放 */
602-
free(readBuf);
603-
free(monoBuf);
651+
aligned_free_16k(readBuf);
652+
aligned_free_16k(monoBuf);
604653
free(psEnc);
605654
drwav_uninit(&wav);
606655
fclose(fout);
@@ -661,9 +710,20 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_flacToSilk(
661710
encCtrl.useDTX = SILK_USE_DTX;
662711
encCtrl.useInBandFEC = SILK_USE_IN_BAND_FEC;
663712

664-
/* PCM 缓冲区 */
665-
short *readBuf = (short *)malloc(frameSize * flac_channels * sizeof(short));
666-
short *monoBuf = (short *)malloc(frameSize * sizeof(short));
713+
/* PCM 缓冲区 - 16KB 对齐 */
714+
short *readBuf = (short *)aligned_malloc_16k(frameSize * flac_channels * sizeof(short));
715+
short *monoBuf = (short *)aligned_malloc_16k(frameSize * sizeof(short));
716+
717+
if (!readBuf || !monoBuf) {
718+
if (readBuf) aligned_free_16k(readBuf);
719+
if (monoBuf) aligned_free_16k(monoBuf);
720+
drflac_close(pFlac);
721+
fclose(fout);
722+
free(psEnc);
723+
env->ReleaseStringUTFChars(flacPath, in_p);
724+
env->ReleaseStringUTFChars(silkPath, out_p);
725+
return -602;
726+
}
667727

668728
/* 编码循环 */
669729
while (drflac_read_pcm_frames_s16(pFlac, frameSize, readBuf) ==
@@ -694,8 +754,8 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_flacToSilk(
694754
fwrite(SILK_TERMINATOR, 1, SILK_TERMINATOR_LEN, fout);
695755

696756
/* 资源释放 */
697-
free(readBuf);
698-
free(monoBuf);
757+
aligned_free_16k(readBuf);
758+
aligned_free_16k(monoBuf);
699759
free(psEnc);
700760
drflac_close(pFlac);
701761
fclose(fout);
@@ -761,12 +821,23 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_oggToSilk(
761821
encCtrl.useDTX = SILK_USE_DTX;
762822
encCtrl.useInBandFEC = SILK_USE_IN_BAND_FEC;
763823

764-
/* PCM 缓冲区 */
824+
/* PCM 缓冲区 - 16KB 对齐 */
765825
#define OGG_READ_FRAMES 4096
766-
short *readBuf = (short *)malloc(OGG_READ_FRAMES * ogg_channels * sizeof(short));
767-
short *pcmBuffer = (short *)malloc(frameSize * 2 * sizeof(short));
826+
short *readBuf = (short *)aligned_malloc_16k(OGG_READ_FRAMES * ogg_channels * sizeof(short));
827+
short *pcmBuffer = (short *)aligned_malloc_16k(frameSize * 2 * sizeof(short));
768828
int pcmBufferLen = 0;
769829

830+
if (!readBuf || !pcmBuffer) {
831+
if (readBuf) aligned_free_16k(readBuf);
832+
if (pcmBuffer) aligned_free_16k(pcmBuffer);
833+
free(psEnc);
834+
stb_vorbis_close(v);
835+
fclose(fout);
836+
env->ReleaseStringUTFChars(oggPath, in_p);
837+
env->ReleaseStringUTFChars(silkPath, out_p);
838+
return -402;
839+
}
840+
770841
/* 编码循环 */
771842
while (1) {
772843
int n = stb_vorbis_get_samples_short_interleaved(v, ogg_channels, readBuf, OGG_READ_FRAMES * ogg_channels);
@@ -804,8 +875,8 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_oggToSilk(
804875
fwrite(SILK_TERMINATOR, 1, SILK_TERMINATOR_LEN, fout);
805876

806877
/* 资源释放 */
807-
free(readBuf);
808-
free(pcmBuffer);
878+
aligned_free_16k(readBuf);
879+
aligned_free_16k(pcmBuffer);
809880
free(psEnc);
810881
stb_vorbis_close(v);
811882
fclose(fout);
@@ -899,12 +970,23 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_pcmToSilk(
899970
encCtrl.useDTX = SILK_USE_DTX;
900971
encCtrl.useInBandFEC = SILK_USE_IN_BAND_FEC;
901972

902-
/* PCM 缓冲区 */
973+
/* PCM 缓冲区 - 16KB 对齐 */
903974
#define PCM_READ_FRAMES 4096
904-
short *readBuf = (short *)malloc(PCM_READ_FRAMES * channels * sizeof(short));
905-
short *pcmBuffer = (short *)malloc(frameSize * 10 * sizeof(short));
975+
short *readBuf = (short *)aligned_malloc_16k(PCM_READ_FRAMES * channels * sizeof(short));
976+
short *pcmBuffer = (short *)aligned_malloc_16k(frameSize * 10 * sizeof(short));
906977
int pcmBufferLen = 0;
907978

979+
if (!readBuf || !pcmBuffer) {
980+
if (readBuf) aligned_free_16k(readBuf);
981+
if (pcmBuffer) aligned_free_16k(pcmBuffer);
982+
free(psEnc);
983+
fclose(fin);
984+
fclose(fout);
985+
env->ReleaseStringUTFChars(pcmPath, in_p);
986+
env->ReleaseStringUTFChars(silkPath, out_p);
987+
return -703;
988+
}
989+
908990
/* 编码循环 */
909991
while (1) {
910992
int n = fread(readBuf, sizeof(short) * channels, PCM_READ_FRAMES, fin);
@@ -946,8 +1028,8 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_pcmToSilk(
9461028
fwrite(SILK_TERMINATOR, 1, SILK_TERMINATOR_LEN, fout);
9471029

9481030
/* 资源释放 */
949-
free(readBuf);
950-
free(pcmBuffer);
1031+
aligned_free_16k(readBuf);
1032+
aligned_free_16k(pcmBuffer);
9511033
free(psEnc);
9521034
fclose(fin);
9531035
fclose(fout);
@@ -1301,9 +1383,19 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_wavToPcm(
13011383
int wav_channels = wav.channels;
13021384
int frame_size = 4096;
13031385

1304-
/* PCM 缓冲区 */
1305-
short *read_buf = (short *)malloc(frame_size * wav_channels * sizeof(short));
1306-
short *mono_buf = (short *)malloc(frame_size * sizeof(short));
1386+
/* PCM 缓冲区 - 16KB 对齐 */
1387+
short *read_buf = (short *)aligned_malloc_16k(frame_size * wav_channels * sizeof(short));
1388+
short *mono_buf = (short *)aligned_malloc_16k(frame_size * sizeof(short));
1389+
1390+
if (!read_buf || !mono_buf) {
1391+
if (read_buf) aligned_free_16k(read_buf);
1392+
if (mono_buf) aligned_free_16k(mono_buf);
1393+
drwav_uninit(&wav);
1394+
fclose(fout);
1395+
env->ReleaseStringUTFChars(wavPath, in_p);
1396+
env->ReleaseStringUTFChars(pcmPath, out_p);
1397+
return -502;
1398+
}
13071399

13081400
/* 解码循环 */
13091401
while (drwav_read_pcm_frames_s16(&wav, frame_size, read_buf) == (drwav_uint64)frame_size) {
@@ -1318,8 +1410,8 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_wavToPcm(
13181410
}
13191411

13201412
/* 资源释放 */
1321-
free(read_buf);
1322-
free(mono_buf);
1413+
aligned_free_16k(read_buf);
1414+
aligned_free_16k(mono_buf);
13231415
drwav_uninit(&wav);
13241416
fclose(fout);
13251417

@@ -1357,9 +1449,19 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_flacToPcm(
13571449
int flac_channels = pFlac->channels;
13581450
int frame_size = 4096;
13591451

1360-
/* PCM 缓冲区 */
1361-
short *read_buf = (short *)malloc(frame_size * flac_channels * sizeof(short));
1362-
short *mono_buf = (short *)malloc(frame_size * sizeof(short));
1452+
/* PCM 缓冲区 - 16KB 对齐 */
1453+
short *read_buf = (short *)aligned_malloc_16k(frame_size * flac_channels * sizeof(short));
1454+
short *mono_buf = (short *)aligned_malloc_16k(frame_size * sizeof(short));
1455+
1456+
if (!read_buf || !mono_buf) {
1457+
if (read_buf) aligned_free_16k(read_buf);
1458+
if (mono_buf) aligned_free_16k(mono_buf);
1459+
drflac_close(pFlac);
1460+
fclose(fout);
1461+
env->ReleaseStringUTFChars(flacPath, in_p);
1462+
env->ReleaseStringUTFChars(pcmPath, out_p);
1463+
return -602;
1464+
}
13631465

13641466
/* 解码循环 */
13651467
while (drflac_read_pcm_frames_s16(pFlac, frame_size, read_buf) == (drflac_uint64)frame_size) {
@@ -1374,8 +1476,8 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_flacToPcm(
13741476
}
13751477

13761478
/* 资源释放 */
1377-
free(read_buf);
1378-
free(mono_buf);
1479+
aligned_free_16k(read_buf);
1480+
aligned_free_16k(mono_buf);
13791481
drflac_close(pFlac);
13801482
fclose(fout);
13811483

@@ -1412,7 +1514,15 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_oggToPcm(
14121514

14131515
/* 音频参数 */
14141516
int frame_size = 4096;
1415-
short *pcm_buf = (short *)malloc(frame_size * sizeof(short));
1517+
short *pcm_buf = (short *)aligned_malloc_16k(frame_size * sizeof(short));
1518+
1519+
if (!pcm_buf) {
1520+
stb_vorbis_close(v);
1521+
fclose(fout);
1522+
env->ReleaseStringUTFChars(oggPath, in_p);
1523+
env->ReleaseStringUTFChars(pcmPath, out_p);
1524+
return -402;
1525+
}
14161526

14171527
/* 解码循环 */
14181528
while (1) {
@@ -1422,7 +1532,7 @@ JNIEXPORT jint JNICALL Java_me_yun_silk_SilkCodec_oggToPcm(
14221532
}
14231533

14241534
/* 资源释放 */
1425-
free(pcm_buf);
1535+
aligned_free_16k(pcm_buf);
14261536
stb_vorbis_close(v);
14271537
fclose(fout);
14281538

0 commit comments

Comments
 (0)