aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Braendli <matthias.braendli@u-blox.com>2015-06-18 14:00:00 +0200
committerMatthias Braendli <matthias.braendli@u-blox.com>2015-06-18 14:00:00 +0200
commit1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea (patch)
treea6db52c86c018d5f587bd1de5858e32f27b51f15
parent1e2a3730e9833f4bac850f89e552f023b7eec3f1 (diff)
downloadtoolame-dab-1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea.tar.gz
toolame-dab-1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea.tar.bz2
toolame-dab-1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea.zip
Add write ICY text into file
-rw-r--r--toolame.c16
-rw-r--r--toolame.h2
-rw-r--r--vlc_input.c91
-rw-r--r--vlc_input.h5
4 files changed, 108 insertions, 6 deletions
diff --git a/toolame.c b/toolame.c
index 68440d8..aecc661 100644
--- a/toolame.c
+++ b/toolame.c
@@ -136,6 +136,7 @@ int main (int argc, char **argv)
int peak_right = 0;
char* mot_file = NULL;
+ char* icy_file = NULL;
/* Used to keep the SNR values for the fast/quick psy models */
static FLOAT smrdef[2][32];
@@ -176,7 +177,7 @@ int main (int argc, char **argv)
short_usage ();
else
parse_args (argc, argv, &frame, &model, &num_samples, original_file_name,
- encoded_file_name, &mot_file);
+ encoded_file_name, &mot_file, &icy_file);
print_config (&frame, &model, original_file_name, encoded_file_name);
uint8_t* xpad_data = NULL;
@@ -513,6 +514,10 @@ int main (int argc, char **argv)
putbits (&bs, 0, 16); // FPAD is all-zero
}
+ if (glopts.input_select == INPUT_SELECT_VLC) {
+ vlc_in_write_icy();
+ }
+
frameBits = sstell (&bs) - sentBits;
@@ -662,6 +667,7 @@ void usage (void)
fprintf (stdout, "\t-g swap channels of input file\n");
fprintf (stdout, "\t-j use jack input\n");
fprintf (stdout, "\t-V use libvlc input\n");
+ fprintf (stdout, "\t-W file when using libvlc input, write the ICY-Text to file\n");
fprintf (stdout, "\t-L enable audio level display\n");
fprintf (stdout, "Output\n");
fprintf (stdout, "\t-m mode channel mode : s/d/j/m (dflt %4c)\n",
@@ -759,7 +765,7 @@ void short_usage (void)
void parse_args (int argc, char **argv, frame_info * frame, int *psy,
unsigned long *num_samples, char inPath[MAX_NAME_SIZE],
- char outPath[MAX_NAME_SIZE], char **mot_file)
+ char outPath[MAX_NAME_SIZE], char **mot_file, char **icy_file)
{
FLOAT srate;
int brate;
@@ -963,6 +969,10 @@ void parse_args (int argc, char **argv, frame_info * frame, int *psy,
case 'V':
glopts.input_select = INPUT_SELECT_VLC;
break;
+ case 'W':
+ argUsed = 1;
+ *icy_file = arg;
+ break;
case 'l':
argUsed = 1;
glopts.athlevel = atof(arg);
@@ -1055,7 +1065,7 @@ void parse_args (int argc, char **argv, frame_info * frame, int *psy,
}
*num_samples = MAX_U_32_NUM;
int channels = (header->mode == MPG_MD_MONO) ? 1 : 2;
- if (vlc_in_prepare(glopts.verbosity, samplerate, inPath, channels) != 0) {
+ if (vlc_in_prepare(glopts.verbosity, samplerate, inPath, channels, *icy_file) != 0) {
fprintf(stderr, "VLC initialisation failed\n");
exit(1);
}
diff --git a/toolame.h b/toolame.h
index cb5fd26..4289ab5 100644
--- a/toolame.h
+++ b/toolame.h
@@ -6,7 +6,7 @@ void short_usage (void);
void obtain_parameters (frame_info *, int *, unsigned long *,
char[MAX_NAME_SIZE], char[MAX_NAME_SIZE]);
void parse_args (int, char **, frame_info *, int *, unsigned long *,
- char[MAX_NAME_SIZE], char[MAX_NAME_SIZE], char**);
+ char[MAX_NAME_SIZE], char[MAX_NAME_SIZE], char**, char**);
void print_config (frame_info *, int *,
char[MAX_NAME_SIZE], char[MAX_NAME_SIZE]);
void usage (void);
diff --git a/vlc_input.c b/vlc_input.c
index 8d96652..c3e1c4f 100644
--- a/vlc_input.c
+++ b/vlc_input.c
@@ -1,5 +1,7 @@
#include <stdlib.h>
+#include <errno.h>
#include <pthread.h>
+#include <semaphore.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
@@ -18,6 +20,23 @@ unsigned int vlc_channels;
struct vlc_buffer *head_buffer;
+// now playing information can get written to
+// a file. This writing happens in a separate thread
+#define NOWPLAYING_LEN 512
+char vlc_nowplaying[NOWPLAYING_LEN];
+int vlc_nowplaying_running;
+pthread_t vlc_nowplaying_thread;
+const char* vlc_nowplaying_filename;
+
+struct icywriter_task_data {
+ char text[NOWPLAYING_LEN];
+ int success;
+ sem_t sem;
+};
+
+struct icywriter_task_data icy_task_data;
+
+
pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER;
struct vlc_buffer* vlc_buffer_new()
@@ -135,10 +154,15 @@ int vlc_in_prepare(
unsigned verbosity,
unsigned int rate,
const char* uri,
- unsigned channels)
+ unsigned channels,
+ const char* icy_write_file
+ )
{
fprintf(stderr, "Initialising VLC...\n");
+ vlc_nowplaying_running = 0;
+ vlc_nowplaying_filename = icy_write_file;
+
long long int handleStream_address;
long long int prepareRender_address;
@@ -286,11 +310,76 @@ ssize_t vlc_in_read(void *buf, size_t len)
st == libvlc_Playing) ) {
return -1;
}
+
+ char* nowplaying_sz = libvlc_media_get_meta(media, libvlc_meta_NowPlaying);
+ if (nowplaying_sz) {
+ snprintf(vlc_nowplaying, NOWPLAYING_LEN, "%s", nowplaying_sz);
+ free(nowplaying_sz);
+ }
}
abort();
}
+// This task is run in a separate thread
+void* vlc_in_write_icy_task(void* arg)
+{
+ struct icywriter_task_data* data = arg;
+
+ FILE* fd = fopen(vlc_nowplaying_filename, "wb");
+ if (fd) {
+ int ret = fputs(data->text, fd);
+ fclose(fd);
+
+ if (ret >= 0) {
+ data->success = 1;
+ }
+ }
+ else {
+ data->success = 0;
+ }
+
+ sem_post(&data->sem);
+}
+
+void vlc_in_write_icy(void)
+{
+ if (vlc_nowplaying_filename == NULL) {
+ return;
+ }
+ else if (vlc_nowplaying_running == 0) {
+ memcpy(icy_task_data.text, vlc_nowplaying, NOWPLAYING_LEN);
+ icy_task_data.success = 0;
+
+ int ret = sem_init(&icy_task_data.sem, 0, 0);
+ if (ret == 0) {
+ ret = pthread_create(&vlc_nowplaying_thread, NULL, vlc_in_write_icy_task, &icy_task_data);
+ }
+ else {
+ fprintf(stderr, "ICY Text writer: semaphore init failed: %s\n", strerror(errno));
+ }
+
+ if (ret == 0) {
+ vlc_nowplaying_running = 1;
+ }
+ else {
+ fprintf(stderr, "ICY Text writer: thread start failed: %s\n", strerror(ret));
+ }
+ }
+ else {
+ int ret = sem_trywait(&icy_task_data.sem);
+ if (ret == -1 && errno == EAGAIN) {
+ return;
+ }
+ else if (ret == 0) {
+ ret = pthread_join(vlc_nowplaying_thread, NULL);
+ vlc_nowplaying_running = 0;
+ }
+
+ return ret;
+ }
+}
+
/* VLC up to version 2.1.0 used a different callback function signature.
* VLC 2.2.0 uses size_t
diff --git a/vlc_input.h b/vlc_input.h
index fbdd705..fa5d82b 100644
--- a/vlc_input.h
+++ b/vlc_input.h
@@ -17,10 +17,13 @@ int vlc_in_prepare(
unsigned verbosity,
unsigned int rate,
const char* uri,
- unsigned channels);
+ unsigned channels,
+ const char* icy_write_file);
// Read len audio bytes into buf
ssize_t vlc_in_read(void *buf, size_t len);
+void vlc_in_write_icy(void);
+
#endif