Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ lmdb: third_party/lmdb
.PHONY: libvpx
libvpx: third_party/libvpx

.PHONY: flac
flac: third_party/flac

.PHONY: cacert
cacert: third_party/cacert.pem

Expand All @@ -100,7 +103,19 @@ third_party_dir:

.PHONY: third_party
third_party: third_party_dir libvpx openssl opus samplerate portaudio lmdb \
cacert
flac cacert


third_party/flac:
$(HIDE)cd third_party && \
wget ${FLAC_MIRROR}/flac-${FLAC_VERSION}.tar.xz && \
tar -xvf flac-${FLAC_VERSION}.tar.xz && \
mv flac-${FLAC_VERSION} flac && cd flac && \
$(_ARCH_CONFIGURE) \
--disable-ogg --enable-static --disable-cpplibs && \
make -j4 && \
cp src/libFLAC/.libs/libFLAC.a ../lib/ && \
cp -a include/FLAC ../include

third_party/libvpx:
$(HIDE)cd third_party && \
Expand Down
9 changes: 9 additions & 0 deletions cmake/FindFLAC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FIND_PATH(FLAC_INCLUDE_DIR FLAC/metadata.h HINTS include)

FIND_LIBRARY(FLAC_LIBRARIES NAMES FLAC HINTS lib)

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLAC DEFAULT_MSG FLAC_LIBRARIES FLAC_INCLUDE_DIR)

# show the FLAC_INCLUDE_DIR and FLAC_LIBRARIES variables only in the advanced view
MARK_AS_ADVANCED(FLAC_INCLUDE_DIR FLAC_LIBRARIES)
5 changes: 4 additions & 1 deletion libsl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
project(sl LANGUAGES C)

find_package(LMDB REQUIRED)
find_package(FLAC REQUIRED)

##############################################################################
#
Expand All @@ -22,10 +23,12 @@ set(SRCS
src/audio.c
src/conf.c
src/db.c
src/flac.c
src/http/client.c
src/http/server.c
src/main.c
src/meters.c
src/record.c
src/tracks.c
src/ws.c
)
Expand Down Expand Up @@ -83,7 +86,7 @@ LIST(APPEND COMPILED_RESOURCES ${OUTPUT_FILE})
#
# Main target object
#
set(LINKLIBS baresip re ${LMDB_LIBRARIES} ${OPENH264_LIBRARIES} stdc++)
set(LINKLIBS baresip re ${FLAC_LIBRARIES} ${LMDB_LIBRARIES} stdc++)

if(WIN32)
list(APPEND LINKLIBS winmm setupapi)
Expand Down
42 changes: 41 additions & 1 deletion libsl/include/studiolink.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,15 @@ void sl_ws_dummyh(const struct websock_hdr *hdr, struct mbuf *mb, void *arg);
/******************************************************************************
* tracks.c
*/
struct sl_track;
/* Local audio device track */
struct sl_local {
struct slaudio *slaudio;
};

/* Remote audio call track */
struct sl_remote {
struct call *call;
};
enum sl_track_type { SL_TRACK_REMOTE, SL_TRACK_LOCAL };
enum sl_track_status {
SL_TRACK_INVALID = -1,
Expand All @@ -160,6 +168,20 @@ enum sl_track_status {
SL_TRACK_REMOTE_CALLING = 6,
SL_TRACK_REMOTE_INCOMING = 7,
};
struct sl_track {
struct le le;
uint16_t id;
enum sl_track_type type;
char name[64];
char error[128];
enum sl_track_status status;
bool muted;
union
{
struct sl_local local;
struct sl_remote remote;
} u;
};
int sl_tracks_init(void);
int sl_tracks_close(void);
const struct list *sl_tracks(void);
Expand Down Expand Up @@ -220,6 +242,24 @@ int sl_account_close(void);
struct ua *sl_account_ua(void);


/******************************************************************************
* record.c
*/
uint64_t sl_record_msecs(void);
void sl_record_toggle(void);
int sl_record_start(void);
void sl_record(struct auframe *af);
int sl_record_close(void);


/******************************************************************************
* flac.c
*/
struct flac;
int sl_flac_init(struct flac **flacp, struct auframe *af, char *file);
int sl_flac_record(struct flac *flac, struct auframe *af, uint64_t offset);


#ifdef __cplusplus
}
#endif
Expand Down
17 changes: 13 additions & 4 deletions libsl/src/audio.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdlib.h>
#include <studiolink.h>

enum { PTIME = 20, SRATE = 48000, CH = 2 };
Expand All @@ -24,7 +25,7 @@ struct amix {
struct auplay_st *play;
struct aumix_source *aumix_src;
char *device;
uint16_t speaker_id;
struct sl_track *track; /* remote track */
};

struct ausrc_st {
Expand Down Expand Up @@ -208,7 +209,7 @@ static void mix_readh(struct auframe *af, void *arg)
return;

amix->play->wh(af, amix->play->arg);
af->id = amix->speaker_id;
af->id = amix->track->id;

#if 0
re_atomic_rlx_set(&amix->play->level,
Expand Down Expand Up @@ -241,7 +242,9 @@ static int amix_alloc(struct amix **amixp, const char *device)
goto out;
}

struct pl *id = pl_alloc_str(device);
amix->track = sl_track_by_id(atoi(device));

struct pl *id = pl_alloc_str(amix->track->name);
if (!id) {
err = ENOMEM;
goto out;
Expand Down Expand Up @@ -456,7 +459,9 @@ static void driver_read_handler(struct auframe *af, void *arg)
auconv_from_s16(AUFMT_FLOAT, sampv, af->sampv, af->sampc);
sl_meter_process(0, sampv, af->sampc / CH);

aumix_source_put(a->mix_src, af->sampv, af->sampc);
af->id = 1;

aumix_source_put_auframe(a->mix_src, af);
}


Expand Down Expand Up @@ -689,6 +694,10 @@ int sl_audio_init(void)
}

err = aumix_alloc(&aumix, SRATE, CH, PTIME);
if (err)
return err;

aumix_recordh(aumix, sl_record);

return err;
}
Expand Down
167 changes: 167 additions & 0 deletions libsl/src/flac.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#ifdef WIN32
#define FLAC__NO_DLL
#endif
#include <FLAC/metadata.h>
#include <FLAC/stream_encoder.h>
#include <string.h>

#include <re.h>
#include <rem.h>
#include <baresip.h>
#include <studiolink.h>

struct flac {
FLAC__StreamEncoder *enc;
FLAC__StreamMetadata *m[2];
FLAC__int32 *pcm;
};


static void flac_destruct(void *arg)
{
struct flac *flac = arg;

mem_deref(flac->pcm);
FLAC__stream_encoder_finish(flac->enc);
FLAC__stream_encoder_delete(flac->enc);
FLAC__metadata_object_delete(flac->m[0]);
FLAC__metadata_object_delete(flac->m[1]);
}


int sl_flac_init(struct flac **flacp, struct auframe *af, char *file)
{

struct flac *flac;
FLAC__bool ret;
FLAC__StreamEncoderInitStatus init;
FLAC__StreamMetadata_VorbisComment_Entry entry;


if (!flacp || !af || !file)
return EINVAL;

flac = mem_zalloc(sizeof(struct flac), flac_destruct);
if (!flac)
return ENOMEM;

flac->pcm = mem_zalloc(af->sampc * sizeof(FLAC__int32), NULL);


flac->enc = FLAC__stream_encoder_new();
if (!flac->enc)
return ENOMEM;

ret = FLAC__stream_encoder_set_verify(flac->enc, true);
ret &= FLAC__stream_encoder_set_compression_level(flac->enc, 5);
ret &= FLAC__stream_encoder_set_channels(flac->enc, af->ch);
ret &= FLAC__stream_encoder_set_bits_per_sample(flac->enc, 16);
ret &= FLAC__stream_encoder_set_sample_rate(flac->enc, af->srate);
ret &= FLAC__stream_encoder_set_total_samples_estimate(flac->enc, 0);

if (!ret) {
warning("record: FLAC__stream_encoder_set\n");
return EINVAL;
}

/* METADATA */
flac->m[0] =
FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
flac->m[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);

ret = FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(
&entry, "ENCODED_BY", "STUDIO LINK MIX");

ret &= FLAC__metadata_object_vorbiscomment_append_comment(
flac->m[0], entry, /*copy=*/false);

if (!ret) {
warning("record: FLAC METADATA ERROR: out of memory or tag "
"error\n");
return ENOMEM;
}

flac->m[1]->length = 1234; /* padding length */

ret = FLAC__stream_encoder_set_metadata(flac->enc, flac->m, 2);

if (!ret) {
warning("record: FLAC__stream_encoder_set_metadata\n");
return ENOMEM;
}

init = FLAC__stream_encoder_init_file(flac->enc, file, NULL, NULL);

if (init != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
warning("record: FLAC ERROR: initializing encoder: %s\n",
FLAC__StreamEncoderInitStatusString[init]);
return ENOMEM;
}

*flacp = flac;

return 0;
}


int sl_flac_record(struct flac *flac, struct auframe *af, uint64_t offset)
{
FLAC__StreamEncoderState state;
FLAC__bool ret;

if (!flac || !af || !af->ch)
return EINVAL;

if (offset > 24 * 3600 * 1000) {
warning("flac_record: ignoring high >24h offset (%llu)\n",
offset);
offset = 0;
}

if (offset < 40 /*ms*/)
offset = 0;

if (offset) {
info("flac_record: offset %llu id %u\n", offset, af->id);
memset(flac->pcm, 0, af->sampc * sizeof(FLAC__int32));
uint64_t offsampc = af->srate * af->ch * offset / 1000;

while (offsampc) {
ret = FLAC__stream_encoder_process_interleaved(
flac->enc, flac->pcm,
(uint32_t)af->sampc / af->ch);
if (!ret)
goto err;

if (offsampc >= af->sampc)
offsampc -= af->sampc;
else {
ret = FLAC__stream_encoder_process_interleaved(
flac->enc, flac->pcm,
(uint32_t)offsampc / af->ch);
if (!ret)
goto err;
offsampc = 0;
}
}
}

int16_t *sampv = (int16_t *)af->sampv;

for (size_t i = 0; i < af->sampc; i++) {
flac->pcm[i] = sampv[i];
}

ret = FLAC__stream_encoder_process_interleaved(
flac->enc, flac->pcm, (uint32_t)af->sampc / af->ch);
if (ret)
return 0;


err:
state = FLAC__stream_encoder_get_state(flac->enc);
warning("record: FLAC ENCODE ERROR: %s\n",
FLAC__StreamEncoderStateString[state]);

return EPROTO;
}
10 changes: 10 additions & 0 deletions libsl/src/http/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,16 @@ static void http_req_handler(struct http_conn *conn,
}


if (0 == pl_strcasecmp(&msg->path, "/api/v1/record") &&
0 == pl_strcasecmp(&msg->met, "POST")) {

sl_record_toggle();
http_sreply(conn, 200, "OK", "text/html", "", 0);

goto out;
}


#ifndef RELEASE
/* Default return OPTIONS - needed on dev for preflight CORS Check
* @TODO: add release test */
Expand Down
2 changes: 1 addition & 1 deletion libsl/src/meters.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static void write_ws(void)
p[0] = '\0';

/* Record time */
re_snprintf(one_peak, sizeof(one_peak), "0 0 ");
re_snprintf(one_peak, sizeof(one_peak), "%llu ", sl_record_msecs());
strcat((char *)p, one_peak);

for (i = 0; i < MAX_METERS; i++) {
Expand Down
Loading
Loading