summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <PromyLOPh@lavabit.com>2009-02-01 13:35:50 +0100
committerLars-Dominik Braun <PromyLOPh@lavabit.com>2009-02-01 13:35:50 +0100
commitc9e23f4e29f08fc53b2306311fa70b1cf4b78b0c (patch)
treecc0f87e31f8528d5eca1b2882449a7071d3cb92e
parent516bc854369243b2f1ba4f1c019aca06cbbd736e (diff)
downloadpianobar-windows-c9e23f4e29f08fc53b2306311fa70b1cf4b78b0c.tar.gz
pianobar-windows-c9e23f4e29f08fc53b2306311fa70b1cf4b78b0c.tar.bz2
pianobar-windows-c9e23f4e29f08fc53b2306311fa70b1cf4b78b0c.zip
mp3 playback support
Now libfaad and/or libmad are used for playback. There's currently no remaining time displayed for mp3 playback.
-rw-r--r--INSTALL24
-rw-r--r--libpiano/src/CMakeLists.txt2
-rw-r--r--libwardrobe/src/CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt28
-rw-r--r--src/FindMad.cmake35
-rw-r--r--src/config.h.in10
-rw-r--r--src/main.c5
-rw-r--r--src/player.c224
-rw-r--r--src/player.h45
-rw-r--r--src/settings.c15
-rw-r--r--src/settings.h3
-rw-r--r--src/ui_act.c14
12 files changed, 333 insertions, 74 deletions
diff --git a/INSTALL b/INSTALL
index b7a6ae5..151ff6e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,32 +6,18 @@ Dependencies
Versions may vary :) Just get the newest one:
-pianobar
-++++++++
-
cmake
libao http://www.xiph.org/ao/
-libcurl http://curl.haxx.se/
+libcurl with SSL http://curl.haxx.se/
libfaad2 http://www.audiocoding.com/downloads.html
+AND/OR libmad http://www.underbit.com/products/mad/
+libxml2 http://xmlsoft.org/
pthreads
readline
UTF-8 console/locale!
-libpiano
-++++++++
-
-cmake
-libcurl with SSL http://curl.haxx.se/
-libxml2 http://xmlsoft.org/
-
-libwardrobe
-+++++++++++
-
-cmake
-libcurl http://curl.haxx.se/
-
-Build
------
+Building
+--------
cmake .
make
diff --git a/libpiano/src/CMakeLists.txt b/libpiano/src/CMakeLists.txt
index b3d49a2..9525101 100644
--- a/libpiano/src/CMakeLists.txt
+++ b/libpiano/src/CMakeLists.txt
@@ -1,3 +1,5 @@
+set (CMAKE_C_FLAGS -Wall)
+
find_package (LibXml2 REQUIRED)
find_package (CURL REQUIRED)
diff --git a/libwardrobe/src/CMakeLists.txt b/libwardrobe/src/CMakeLists.txt
index 960f4ca..6d7c835 100644
--- a/libwardrobe/src/CMakeLists.txt
+++ b/libwardrobe/src/CMakeLists.txt
@@ -1,3 +1,5 @@
+set (CMAKE_C_FLAGS -Wall)
+
find_package (CURL REQUIRED)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0274af0..c7f6998 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,20 +1,38 @@
set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+set (CMAKE_C_FLAGS -Wall)
+
find_package (LibXml2 REQUIRED)
find_package (CURL REQUIRED)
-find_package (Faad REQUIRED)
find_package (Readline REQUIRED)
find_package (LibAo REQUIRED)
-find_package (Threads REQUIRED)
-find_library (LIBM m)
+# find threading implementation
+find_package (Threads REQUIRED)
if (NOT CMAKE_USE_PTHREADS_INIT)
message (FATAL_ERROR "pthread is currently required")
endif (NOT CMAKE_USE_PTHREADS_INIT)
+# check for libm
+find_library (LIBM m)
if (NOT LIBM)
message (FATAL_ERROR "libm is required")
endif (NOT LIBM)
+# check for audio decoding library
+find_package (Faad)
+find_package (Mad)
+if (NOT FAAD_FOUND AND NOT MAD_FOUND)
+ message (FATAL_ERROR "libmad and/or libfaad are required.")
+endif (NOT FAAD_FOUND AND NOT MAD_FOUND)
+if (FAAD_FOUND)
+ message (STATUS "Found libfaad, enabling aac decoding")
+ set (ENABLE_FAAD 1)
+endif (FAAD_FOUND)
+if (MAD_FOUND)
+ message (STATUS "Found libmad, enabling mp3 decoding")
+ set (ENABLE_MAD 1)
+endif (MAD_FOUND)
+
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
@@ -23,12 +41,12 @@ include_directories (
${pianobar_SOURCE_DIR}/libwardrobe/src
${LIBXML2_INCLUDE_DIR}
${CURL_INCLUDE_DIRS} ${READLINE_INCLUDE_DIR} ${FAAD_INCLUDE_DIRS}
- ${LIBAO_INCLUDE_DIRS})
+ ${LIBAO_INCLUDE_DIRS} ${MAD_INCLUDE_DIRS})
add_executable (pianobar main.c terminal.c settings.c player.c ui.c ui_act.c)
target_link_libraries (pianobar piano wardrobe ${CURL_LIBRARIES}
${LIBXML2_LIBRARIES} ${READLINE_LIBRARY} ${FAAD_LIBRARY} ${LIBAO_LIBRARY}
- ${CMAKE_THREAD_LIBS_INIT} ${LIBM})
+ ${CMAKE_THREAD_LIBS_INIT} ${MAD_LIBRARIES} ${LIBM})
install (TARGETS pianobar RUNTIME DESTINATION bin)
install (FILES pianobar.1 DESTINATION share/man/man1)
diff --git a/src/FindMad.cmake b/src/FindMad.cmake
new file mode 100644
index 0000000..f05f469
--- /dev/null
+++ b/src/FindMad.cmake
@@ -0,0 +1,35 @@
+# MAD_INCLUDE_DIRS - where to find curl/curl.h, etc.
+# MAD_LIBRARIES - List of libraries when using curl.
+# MAD_FOUND - True if curl found.
+
+# Look for the header file.
+FIND_PATH(MAD_INCLUDE_DIR NAMES mad.h)
+MARK_AS_ADVANCED(MAD_INCLUDE_DIR)
+
+# Look for the library.
+FIND_LIBRARY(MAD_LIBRARY NAMES mad)
+MARK_AS_ADVANCED(MAD_LIBRARY)
+
+# Copy the results to the output variables.
+IF(MAD_INCLUDE_DIR AND MAD_LIBRARY)
+ SET(MAD_FOUND 1)
+ SET(MAD_LIBRARIES ${MAD_LIBRARY})
+ SET(MAD_INCLUDE_DIRS ${MAD_INCLUDE_DIR})
+ELSE(MAD_INCLUDE_DIR AND MAD_LIBRARY)
+ SET(MAD_FOUND 0)
+ SET(MAD_LIBRARIES)
+ SET(MAD_INCLUDE_DIRS)
+ENDIF(MAD_INCLUDE_DIR AND MAD_LIBRARY)
+
+# Report the results.
+IF(NOT MAD_FOUND)
+ SET(MAD_DIR_MESSAGE
+ "libmad was not found. Make sure MAD_LIBRARY and MAD_INCLUDE_DIR are set.")
+ IF(NOT MAD_FIND_QUIETLY)
+ MESSAGE(STATUS "${MAD_DIR_MESSAGE}")
+ ELSE(NOT MAD_FIND_QUIETLY)
+ IF(MAD_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "${MAD_DIR_MESSAGE}")
+ ENDIF(MAD_FIND_REQUIRED)
+ ENDIF(NOT MAD_FIND_QUIETLY)
+ENDIF(NOT MAD_FOUND)
diff --git a/src/config.h.in b/src/config.h.in
index 60600a7..a75a43f 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -1 +1,11 @@
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+/* package name */
#define PACKAGE "${PACKAGE}"
+
+/* used libraries */
+#cmakedefine ENABLE_FAAD
+#cmakedefine ENABLE_MAD
+
+#endif /* _CONFIG_H */
diff --git a/src/main.c b/src/main.c
index b44330a..33ece10 100644
--- a/src/main.c
+++ b/src/main.c
@@ -52,7 +52,7 @@ inline float BarSamplesToSeconds (float samplerate, float channels,
int main (int argc, char **argv) {
PianoHandle_t ph;
- struct aacPlayer player;
+ static struct audioPlayer player;
BarSettings_t settings;
PianoSong_t *curSong = NULL;
PianoStation_t *curStation = NULL;
@@ -165,7 +165,7 @@ int main (int argc, char **argv) {
BarUiMsg ("Receiving new playlist... ");
PianoDestroyPlaylist (&ph);
if (BarUiPrintPianoStatus (PianoGetPlaylist (&ph,
- curStation->id, PIANO_AF_AACPLUS)) !=
+ curStation->id, settings.audioFormat)) !=
PIANO_RET_OK) {
curStation = NULL;
} else {
@@ -198,6 +198,7 @@ int main (int argc, char **argv) {
memset (&player, 0, sizeof (player));
player.url = strdup (curSong->audioUrl);
player.gain = curSong->fileGain;
+ player.audioFormat = curSong->audioFormat;
/* start player */
pthread_create (&playerThread, NULL, BarPlayerThread,
diff --git a/src/player.c b/src/player.c
index 94c7969..da4f60a 100644
--- a/src/player.c
+++ b/src/player.c
@@ -43,32 +43,56 @@ THE SOFTWARE.
return 0; \
}
+/* pandora uses float values with 2 digits precision. Scale them by 100 to get
+ * a "nice" integer */
+#define RG_SCALE_FACTOR 100
+
/* compute replaygain scale factor
* algo taken from here: http://www.dsprelated.com/showmessage/29246/1.php
* mpd does the same
* @param apply this gain
* @return this * yourvalue = newgain value
*/
-inline float computeReplayGainScale (float applyGain) {
- return pow (10.0, applyGain / 20.0);
+inline unsigned int computeReplayGainScale (float applyGain) {
+ return pow (10.0, applyGain / 20.0) * RG_SCALE_FACTOR;
+}
+
+/* apply replaygain to signed short value
+ * @param value
+ * @param replaygain scale (calculated by computeReplayGainScale)
+ * @return scaled value
+ */
+inline signed short int applyReplayGain (signed short int value,
+ unsigned int scale) {
+ int tmpReplayBuf = value * scale;
+ /* avoid clipping */
+ if (tmpReplayBuf > INT16_MAX*RG_SCALE_FACTOR) {
+ return INT16_MAX;
+ } else if (tmpReplayBuf < INT16_MIN*RG_SCALE_FACTOR) {
+ return INT16_MIN;
+ } else {
+ return tmpReplayBuf / RG_SCALE_FACTOR;
+ }
}
-/* our heart: plays streamed music
+#ifdef ENABLE_FAAD
+
+/* play aac stream
* @param streamed data
* @param block size
* @param received blocks
* @param extra data (player data)
* @return received bytes or less on error
*/
-size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
+size_t BarPlayerAACCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
char *data = ptr;
- struct aacPlayer *player = stream;
+ struct audioPlayer *player = stream;
QUIT_PAUSE_CHECK;
/* fill buffer */
if (player->bufferFilled + size*nmemb > sizeof (player->buffer)) {
- printf ("Buffer overflow!\n");
+ printf (PACKAGE ": Buffer overflow!\n");
return 0;
}
memcpy (player->buffer+player->bufferFilled, data, size*nmemb);
@@ -79,14 +103,13 @@ size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
if (player->mode == PLAYER_RECV_DATA) {
short int *aacDecoded;
NeAACDecFrameInfo frameInfo;
- int tmpReplayBuf;
size_t i;
while ((player->bufferFilled - player->bufferRead) >
player->sampleSize[player->sampleSizeCurr]) {
/* decode frame */
aacDecoded = NeAACDecDecode(player->aacHandle, &frameInfo,
- (unsigned char *) player->buffer + player->bufferRead,
+ player->buffer + player->bufferRead,
player->sampleSize[player->sampleSizeCurr]);
if (frameInfo.error != 0) {
printf (PACKAGE ": Decoding error: %s\n\n",
@@ -94,19 +117,11 @@ size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
break;
}
for (i = 0; i < frameInfo.samples; i++) {
- tmpReplayBuf = (float) aacDecoded[i] * player->scale;
- /* avoid clipping */
- if (tmpReplayBuf > INT16_MAX) {
- aacDecoded[i] = INT16_MAX;
- } else if (tmpReplayBuf < INT16_MIN) {
- aacDecoded[i] = INT16_MIN;
- } else {
- aacDecoded[i] = tmpReplayBuf;
- }
+ aacDecoded[i] = applyReplayGain (aacDecoded[i], player->scale);
}
/* ao_play needs bytes: 1 sample = 16 bits = 2 bytes */
ao_play (player->audioOutDevice, (char *) aacDecoded,
- frameInfo.samples * 16 / 8);
+ frameInfo.samples * 2);
player->bufferRead += frameInfo.bytesconsumed;
player->sampleSizeCurr++;
/* going through this loop can take up to a few seconds =>
@@ -136,15 +151,14 @@ size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
/* +1+4 needs to be replaced by <something>! */
player->bufferRead += 1+4;
- char err = NeAACDecInit2 (player->aacHandle,
- (unsigned char *) player->buffer +
+ char err = NeAACDecInit2 (player->aacHandle, player->buffer +
player->bufferRead, 5, &player->samplerate,
&player->channels);
player->bufferRead += 5;
if (err != 0) {
- printf ("Error while initializing audio decoder"
+ printf (PACKAGE ": Error while initializing audio decoder"
"(%i)\n", err);
- return 1;
+ return 0;
}
audioOutDriver = ao_default_driver_id();
format.bits = 16;
@@ -218,38 +232,162 @@ size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
/* move remaining bytes to buffer beginning */
memmove (player->buffer, player->buffer + player->bufferRead,
(player->bufferFilled - player->bufferRead));
- player->bufferFilled = (player->bufferFilled - player->bufferRead);
+ player->bufferFilled -= player->bufferRead;
return size*nmemb;
}
+#endif /* ENABLE_FAAD */
+
+#ifdef ENABLE_MAD
+
+/* convert mad's internal fixed point format to short int
+ * @param mad fixed
+ * @return short int
+ */
+inline signed short int BarPlayerMadToShort (mad_fixed_t fixed) {
+ /* Clipping */
+ if (fixed >= MAD_F_ONE) {
+ return SHRT_MAX;
+ } else if (fixed <= -MAD_F_ONE) {
+ return -SHRT_MAX;
+ }
+
+ /* Conversion */
+ return (signed short int) (fixed >> (MAD_F_FRACBITS - 15));
+}
+
+size_t BarPlayerMp3CurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
+ char *data = ptr;
+ struct audioPlayer *player = stream;
+ size_t i;
+
+ QUIT_PAUSE_CHECK;
+
+ /* fill buffer */
+ if (player->bufferFilled + size*nmemb > sizeof (player->buffer)) {
+ printf (PACKAGE ": Buffer overflow!\n");
+ return 0;
+ }
+ memcpy (player->buffer+player->bufferFilled, data, size*nmemb);
+ player->bufferFilled += size*nmemb;
+ player->bufferRead = 0;
+ player->bytesReceived += size*nmemb;
+
+ mad_stream_buffer (&player->mp3Stream, player->buffer,
+ player->bufferFilled);
+ player->mp3Stream.error = 0;
+ do {
+ /* channels * max samples found in mad.h */
+ signed short int madDecoded[2*1152], *madPtr = madDecoded;
+
+ if (mad_frame_decode (&player->mp3Frame, &player->mp3Stream) != 0) {
+ if (player->mp3Stream.error != MAD_ERROR_BUFLEN) {
+ printf (PACKAGE ": mp3 decoding error: %s.\n",
+ mad_stream_errorstr (&player->mp3Stream));
+ return 0;
+ } else {
+ /* rebuffering required => exit loop */
+ break;
+ }
+ }
+ mad_timer_add (&player->mp3Timer, player->mp3Frame.header.duration);
+ mad_synth_frame (&player->mp3Synth, &player->mp3Frame);
+ for (i = 0; i < player->mp3Synth.pcm.length; i++) {
+ /* left channel */
+ *(madPtr++) = applyReplayGain (BarPlayerMadToShort (
+ player->mp3Synth.pcm.samples[0][i]), player->scale);
+
+ /* right channel */
+ *(madPtr++) = applyReplayGain (BarPlayerMadToShort (
+ player->mp3Synth.pcm.samples[1][i]), player->scale);
+ }
+ if (player->mode < PLAYER_AUDIO_INITIALIZED) {
+ ao_sample_format format;
+ int audioOutDriver;
+
+ player->channels = player->mp3Synth.pcm.channels;
+ player->samplerate = player->mp3Synth.pcm.samplerate;
+ audioOutDriver = ao_default_driver_id();
+ format.bits = 16;
+ format.channels = player->channels;
+ format.rate = player->samplerate;
+ format.byte_format = AO_FMT_LITTLE;
+ player->audioOutDevice = ao_open_live (audioOutDriver,
+ &format, NULL);
+ player->mode = PLAYER_AUDIO_INITIALIZED;
+ }
+ /* samples * length * channels */
+ ao_play (player->audioOutDevice, (char *) madDecoded,
+ player->mp3Synth.pcm.length * 2 * 2);
+
+ QUIT_PAUSE_CHECK;
+ } while (player->mp3Stream.error != MAD_ERROR_BUFLEN);
+
+ player->bufferRead += player->mp3Stream.next_frame - player->buffer;
+
+ /* move remaining bytes to buffer beginning */
+ memmove (player->buffer, player->buffer + player->bufferRead,
+ (player->bufferFilled - player->bufferRead));
+ player->bufferFilled -= player->bufferRead;
+
+ return size*nmemb;
+}
+#endif /* ENABLE_MAD */
/* player thread; for every song a new thread is started
* @param aacPlayer structure
* @return NULL NULL NULL ...
*/
void *BarPlayerThread (void *data) {
- struct aacPlayer *player = data;
+ struct audioPlayer *player = data;
+ #ifdef ENABLE_FAAD
NeAACDecConfigurationPtr conf;
+ #endif
CURLcode curlRet = 0;
/* init handles */
pthread_mutex_init (&player->pauseMutex, NULL);
player->audioFd = curl_easy_init ();
- player->aacHandle = NeAACDecOpen();
+
+ switch (player->audioFormat) {
+ #ifdef ENABLE_FAAD
+ case PIANO_AF_AACPLUS:
+ player->aacHandle = NeAACDecOpen();
+ /* set aac conf */
+ conf = NeAACDecGetCurrentConfiguration(player->aacHandle);
+ conf->outputFormat = FAAD_FMT_16BIT;
+ conf->downMatrix = 1;
+ NeAACDecSetConfiguration(player->aacHandle, conf);
+
+ curl_easy_setopt (player->audioFd, CURLOPT_WRITEFUNCTION,
+ BarPlayerAACCurlCb);
+ break;
+ #endif /* ENABLE_FAAD */
+
+ #ifdef ENABLE_MAD
+ case PIANO_AF_MP3:
+ mad_stream_init (&player->mp3Stream);
+ mad_frame_init (&player->mp3Frame);
+ mad_synth_init (&player->mp3Synth);
+ mad_timer_reset (&player->mp3Timer);
+
+ curl_easy_setopt (player->audioFd, CURLOPT_WRITEFUNCTION,
+ BarPlayerMp3CurlCb);
+ break;
+ #endif /* ENABLE_MAD */
+
+ default:
+ printf (PACKAGE ": Unsupported audio format!\n");
+ return NULL;
+ break;
+ }
/* init replaygain */
player->scale = computeReplayGainScale (player->gain);
- /* set aac conf */
- conf = NeAACDecGetCurrentConfiguration(player->aacHandle);
- conf->outputFormat = FAAD_FMT_16BIT;
- conf->downMatrix = 1;
- NeAACDecSetConfiguration(player->aacHandle, conf);
-
/* init curl */
curl_easy_setopt (player->audioFd, CURLOPT_URL, player->url);
- curl_easy_setopt (player->audioFd, CURLOPT_WRITEFUNCTION, BarPlayerCurlCb);
curl_easy_setopt (player->audioFd, CURLOPT_WRITEDATA, (void *) player);
curl_easy_setopt (player->audioFd, CURLOPT_USERAGENT, PACKAGE);
curl_easy_setopt (player->audioFd, CURLOPT_CONNECTTIMEOUT, 60);
@@ -269,12 +407,32 @@ void *BarPlayerThread (void *data) {
curlRet = curl_easy_perform (player->audioFd);
} while (curlRet == CURLE_PARTIAL_FILE);
- NeAACDecClose(player->aacHandle);
+ switch (player->audioFormat) {
+ #ifdef ENABLE_FAAD
+ case PIANO_AF_AACPLUS:
+ NeAACDecClose(player->aacHandle);
+ break;
+ #endif /* ENABLE_FAAD */
+
+ #ifdef ENABLE_MAD
+ case PIANO_AF_MP3:
+ mad_synth_finish (&player->mp3Synth);
+ mad_frame_finish (&player->mp3Frame);
+ mad_stream_finish (&player->mp3Stream);
+ break;
+ #endif /* ENABLE_MAD */
+
+ default:
+ /* this should never happen: thread is aborted above */
+ break;
+ }
ao_close(player->audioOutDevice);
curl_easy_cleanup (player->audioFd);
+ #ifdef ENABLE_FAAD
if (player->sampleSize != NULL) {
free (player->sampleSize);
}
+ #endif /* ENABLE_FAAD */
pthread_mutex_destroy (&player->pauseMutex);
player->mode = PLAYER_FINISHED_PLAYBACK;
diff --git a/src/player.h b/src/player.h
index 7756d0a..eab03a9 100644
--- a/src/player.h
+++ b/src/player.h
@@ -24,37 +24,68 @@ THE SOFTWARE.
#ifndef _PLAYER_H
#define _PLAYER_H
+#include "config.h"
+
#include <curl/curl.h>
+
+#ifdef ENABLE_FAAD
#include <neaacdec.h>
+#endif
+
+#ifdef ENABLE_MAD
+#include <mad.h>
+#endif
+
#include <ao/ao.h>
#include <pthread.h>
+#include <piano.h>
-struct aacPlayer {
+struct audioPlayer {
/* buffer; should be large enough */
- char buffer[CURL_MAX_WRITE_SIZE*2];
+ unsigned char buffer[CURL_MAX_WRITE_SIZE*2];
size_t bufferFilled;
size_t bufferRead;
+ size_t bytesReceived;
+
enum {PLAYER_FREED = 0, PLAYER_INITIALIZED, PLAYER_FOUND_ESDS,
PLAYER_AUDIO_INITIALIZED, PLAYER_FOUND_STSZ,
PLAYER_SAMPLESIZE_INITIALIZED, PLAYER_RECV_DATA,
PLAYER_FINISHED_PLAYBACK} mode;
- size_t bytesReceived;
- /* stsz atom: sample sizes */
- unsigned int *sampleSize;
+
+ PianoAudioFormat_t audioFormat;
+
size_t sampleSizeN;
size_t sampleSizeCurr;
+
/* aac */
+ #ifdef ENABLE_FAAD
NeAACDecHandle aacHandle;
+ /* stsz atom: sample sizes */
+ unsigned int *sampleSize;
+ #endif
+
+ /* mp3 */
+ #ifdef ENABLE_MAD
+ struct mad_stream mp3Stream;
+ struct mad_frame mp3Frame;
+ struct mad_synth mp3Synth;
+ mad_timer_t mp3Timer;
+ #endif
+
unsigned long samplerate;
unsigned char channels;
+
float gain;
- float scale;
+ unsigned int scale;
+
/* audio out */
ao_device *audioOutDevice;
+
+ CURL *audioFd;
char *url;
+
char doQuit;
pthread_mutex_t pauseMutex;
- CURL *audioFd;
};
void *BarPlayerThread (void *data);
diff --git a/src/settings.c b/src/settings.c
index 2e5dab6..e3e811a 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -154,6 +154,15 @@ void BarSettingsRead (BarSettings_t *settings) {
"act_stationselectquickmix", NULL},
};
+ /* apply defaults */
+ #ifdef ENABLE_FAAD
+ settings->audioFormat = PIANO_AF_AACPLUS;
+ #else
+ #ifdef ENABLE_MAD
+ settings->audioFormat = PIANO_AF_MP3;
+ #endif
+ #endif
+
BarGetXdgConfigDir (PACKAGE "/config", configfile, sizeof (configfile));
if ((configfd = fopen (configfile, "r")) == NULL) {
/* use default keyboard shortcuts */
@@ -212,6 +221,12 @@ void BarSettingsRead (BarSettings_t *settings) {
break;
}
}
+ } else if (strcmp ("audio_format", key) == 0) {
+ if (strcmp (val, "aacplus") == 0) {
+ settings->audioFormat = PIANO_AF_AACPLUS;
+ } else if (strcmp (val, "mp3") == 0) {
+ settings->audioFormat = PIANO_AF_MP3;
+ }
}
}
diff --git a/src/settings.h b/src/settings.h
index ed71530..a1afea1 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -29,7 +29,7 @@ THE SOFTWARE.
#include "player.h"
-#define BAR_KS_ARGS PianoHandle_t *ph, struct aacPlayer *player, \
+#define BAR_KS_ARGS PianoHandle_t *ph, struct audioPlayer *player, \
struct BarSettings *settings, PianoSong_t **curSong, \
PianoStation_t **curStation, char *doQuit
@@ -50,6 +50,7 @@ struct BarSettings {
char *configKey;
struct BarKeyShortcut *next;
} *keys;
+ PianoAudioFormat_t audioFormat;
};
typedef struct BarSettings BarSettings_t;
diff --git a/src/ui_act.c b/src/ui_act.c
index 5c28672..2ecc9c2 100644
--- a/src/ui_act.c
+++ b/src/ui_act.c
@@ -44,7 +44,7 @@ THE SOFTWARE.
/* helper to _really_ skip a song (unlock mutex, quit player)
* @param player handle
*/
-inline void BarUiDoSkipSong (struct aacPlayer *player) {
+inline void BarUiDoSkipSong (struct audioPlayer *player) {
player->doQuit = 1;
pthread_mutex_unlock (&player->pauseMutex);
}
@@ -178,6 +178,7 @@ void BarUiActSongInfo (BAR_KS_ARGS) {
printf ("Song infos:\n"
"album:\t%s\n"
"artist:\t%s\n"
+ "audioFormat:\t%i\n"
"audioUrl:\t%s\n"
"fileGain:\t%f\n"
"focusTraitId:\t%s\n"
@@ -188,12 +189,11 @@ void BarUiActSongInfo (BAR_KS_ARGS) {
"stationId:\t%s\n"
"title:\t%s\n"
"userSeed:\t%s\n",
- (*curSong)->album, (*curSong)->artist, (*curSong)->audioUrl,
- (*curSong)->fileGain, (*curSong)->focusTraitId,
- (*curSong)->identity, (*curSong)->matchingSeed,
- (*curSong)->musicId, (*curSong)->rating,
- (*curSong)->stationId, (*curSong)->title,
- (*curSong)->userSeed);
+ (*curSong)->album, (*curSong)->artist, (*curSong)->audioFormat,
+ (*curSong)->audioUrl, (*curSong)->fileGain,
+ (*curSong)->focusTraitId, (*curSong)->identity,
+ (*curSong)->matchingSeed, (*curSong)->musicId, (*curSong)->rating,
+ (*curSong)->stationId, (*curSong)->title, (*curSong)->userSeed);
}
/* rate current song