Switch to C99 types (retaining compat with old compilers)
Seeing the "mpd_" prefix _everywhere_ is mind-numbing as the mind needs to retrain itself to skip over the first 4 tokens of a type to get to its meaning. So avoid having extra characters on my terminal to make it easier to follow code at 2:30 am in the morning. Please report any new issues you may come across on Free toolchains. I realize how difficult it can be to build/maintain cross-compiling toolchains and I have no intention of forcing people to upgrade their toolchains to build mpd. Tested with gcc 2.95.4 and and gcc 4.3.1 on x86-32.
This commit is contained in:
parent
a4019f7d21
commit
0352766dca
@ -44,7 +44,7 @@ enum ad_state {
|
|||||||
and enable in playAudio() routine */
|
and enable in playAudio() routine */
|
||||||
static enum ad_state *audioDeviceStates;
|
static enum ad_state *audioDeviceStates;
|
||||||
|
|
||||||
static mpd_uint8 audioOpened;
|
static uint8_t audioOpened;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct audio_format format;
|
struct audio_format format;
|
||||||
@ -150,7 +150,7 @@ int parseAudioConfig(struct audio_format *audioFormat, char *conf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
audioFormat->bits = (mpd_sint8)strtol(test + 1, &test, 10);
|
audioFormat->bits = (int8_t)strtol(test + 1, &test, 10);
|
||||||
|
|
||||||
if (*test != ':') {
|
if (*test != ':') {
|
||||||
ERROR("error parsing audio output format: %s\n", conf);
|
ERROR("error parsing audio output format: %s\n", conf);
|
||||||
@ -166,7 +166,7 @@ int parseAudioConfig(struct audio_format *audioFormat, char *conf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
audioFormat->channels = (mpd_sint8)strtol(test + 1, &test, 10);
|
audioFormat->channels = (int8_t)strtol(test + 1, &test, 10);
|
||||||
|
|
||||||
if (*test != '\0') {
|
if (*test != '\0') {
|
||||||
ERROR("error parsing audio output format: %s\n", conf);
|
ERROR("error parsing audio output format: %s\n", conf);
|
||||||
|
@ -214,7 +214,7 @@ configure_hw:
|
|||||||
snd_strerror(-err));
|
snd_strerror(-err));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
audioFormat->channels = (mpd_sint8)channels;
|
audioFormat->channels = (int8_t)channels;
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
|
err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
|
||||||
&sampleRate, NULL);
|
&sampleRate, NULL);
|
||||||
|
@ -482,9 +482,9 @@ static int oss_openDevice(void *data,
|
|||||||
int ret;
|
int ret;
|
||||||
OssData *od = data;
|
OssData *od = data;
|
||||||
|
|
||||||
od->channels = (mpd_sint8)audioFormat->channels;
|
od->channels = (int8_t)audioFormat->channels;
|
||||||
od->sampleRate = audioFormat->sampleRate;
|
od->sampleRate = audioFormat->sampleRate;
|
||||||
od->bits = (mpd_sint8)audioFormat->bits;
|
od->bits = (int8_t)audioFormat->bits;
|
||||||
|
|
||||||
if ((ret = oss_open(od)) < 0)
|
if ((ret = oss_open(od)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -32,13 +32,13 @@ static iconv_t char_conv_iconv;
|
|||||||
|
|
||||||
static char *char_conv_to;
|
static char *char_conv_to;
|
||||||
static char *char_conv_from;
|
static char *char_conv_from;
|
||||||
static mpd_sint8 char_conv_same;
|
static int8_t char_conv_same;
|
||||||
static mpd_sint8 char_conv_use_iconv;
|
static int8_t char_conv_use_iconv;
|
||||||
|
|
||||||
/* 1 is to use latin1ToUtf8
|
/* 1 is to use latin1ToUtf8
|
||||||
0 is not to use latin1/utf8 converter
|
0 is not to use latin1/utf8 converter
|
||||||
-1 is to use utf8ToLatin1*/
|
-1 is to use utf8ToLatin1*/
|
||||||
static mpd_sint8 char_conv_latin1ToUtf8;
|
static int8_t char_conv_latin1ToUtf8;
|
||||||
|
|
||||||
#define BUFFER_SIZE MPD_PATH_MAX
|
#define BUFFER_SIZE MPD_PATH_MAX
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "storedPlaylist.h"
|
#include "storedPlaylist.h"
|
||||||
|
|
||||||
typedef struct _ListCommandItem {
|
typedef struct _ListCommandItem {
|
||||||
mpd_sint8 tagType;
|
int8_t tagType;
|
||||||
int numConditionals;
|
int numConditionals;
|
||||||
LocateTagItem *conditionals;
|
LocateTagItem *conditionals;
|
||||||
} ListCommandItem;
|
} ListCommandItem;
|
||||||
|
@ -316,7 +316,7 @@ static int aac_stream_decode(struct decoder * mpd_decoder,
|
|||||||
unsigned int sampleCount;
|
unsigned int sampleCount;
|
||||||
char *sampleBuffer;
|
char *sampleBuffer;
|
||||||
size_t sampleBufferLen;
|
size_t sampleBufferLen;
|
||||||
mpd_uint16 bitRate = 0;
|
uint16_t bitRate = 0;
|
||||||
AacBuffer b;
|
AacBuffer b;
|
||||||
int initialized = 0;
|
int initialized = 0;
|
||||||
|
|
||||||
@ -453,7 +453,7 @@ static int aac_decode(struct decoder * mpd_decoder, char *path)
|
|||||||
/*float * seekTable;
|
/*float * seekTable;
|
||||||
long seekTableEnd = -1;
|
long seekTableEnd = -1;
|
||||||
int seekPositionFound = 0; */
|
int seekPositionFound = 0; */
|
||||||
mpd_uint16 bitRate = 0;
|
uint16_t bitRate = 0;
|
||||||
AacBuffer b;
|
AacBuffer b;
|
||||||
InputStream inStream;
|
InputStream inStream;
|
||||||
int initialized = 0;
|
int initialized = 0;
|
||||||
|
@ -65,7 +65,7 @@ static unsigned long prng(unsigned long state)
|
|||||||
return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
|
return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mpd_sint16 audio_linear_dither(unsigned int bits, mad_fixed_t sample,
|
static int16_t audio_linear_dither(unsigned int bits, mad_fixed_t sample,
|
||||||
struct audio_dither *dither)
|
struct audio_dither *dither)
|
||||||
{
|
{
|
||||||
unsigned int scalebits;
|
unsigned int scalebits;
|
||||||
@ -107,15 +107,15 @@ static mpd_sint16 audio_linear_dither(unsigned int bits, mad_fixed_t sample,
|
|||||||
|
|
||||||
dither->error[0] = sample - output;
|
dither->error[0] = sample - output;
|
||||||
|
|
||||||
return (mpd_sint16)(output >> scalebits);
|
return (int16_t)(output >> scalebits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned dither_buffer(mpd_sint16 *dest0, const struct mad_synth *synth,
|
static unsigned dither_buffer(int16_t *dest0, const struct mad_synth *synth,
|
||||||
struct audio_dither *dither,
|
struct audio_dither *dither,
|
||||||
unsigned int start, unsigned int end,
|
unsigned int start, unsigned int end,
|
||||||
unsigned int num_channels)
|
unsigned int num_channels)
|
||||||
{
|
{
|
||||||
mpd_sint16 *dest = dest0;
|
int16_t *dest = dest0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = start; i < end; ++i) {
|
for (i = start; i < end; ++i) {
|
||||||
@ -153,7 +153,7 @@ typedef struct _mp3DecodeData {
|
|||||||
struct mad_synth synth;
|
struct mad_synth synth;
|
||||||
mad_timer_t timer;
|
mad_timer_t timer;
|
||||||
unsigned char readBuffer[READ_BUFFER_SIZE];
|
unsigned char readBuffer[READ_BUFFER_SIZE];
|
||||||
mpd_sint16 outputBuffer[MP3_DATA_OUTPUT_BUFFER_SIZE];
|
int16_t outputBuffer[MP3_DATA_OUTPUT_BUFFER_SIZE];
|
||||||
float totalTime;
|
float totalTime;
|
||||||
float elapsedTime;
|
float elapsedTime;
|
||||||
enum muteframe muteFrame;
|
enum muteframe muteFrame;
|
||||||
|
@ -104,7 +104,7 @@ static int mp4_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
long seekTableEnd = -1;
|
long seekTableEnd = -1;
|
||||||
int seekPositionFound = 0;
|
int seekPositionFound = 0;
|
||||||
long offset;
|
long offset;
|
||||||
mpd_uint16 bitRate = 0;
|
uint16_t bitRate = 0;
|
||||||
int seeking = 0;
|
int seeking = 0;
|
||||||
double seek_where = 0;
|
double seek_where = 0;
|
||||||
int initialized = 0;
|
int initialized = 0;
|
||||||
|
@ -127,7 +127,7 @@ static int strstrSearchTag(Song * song, enum tag_type type, char *str)
|
|||||||
int i;
|
int i;
|
||||||
char *duplicate;
|
char *duplicate;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
mpd_sint8 visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
|
int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
|
||||||
|
|
||||||
if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
|
if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
|
||||||
char path_max_tmp[MPD_PATH_MAX];
|
char path_max_tmp[MPD_PATH_MAX];
|
||||||
@ -184,7 +184,7 @@ int strstrSearchTags(Song * song, int numItems, LocateTagItem * items)
|
|||||||
static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str)
|
static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
mpd_sint8 visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
|
int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
|
||||||
|
|
||||||
if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
|
if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
|
||||||
char path_max_tmp[MPD_PATH_MAX];
|
char path_max_tmp[MPD_PATH_MAX];
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
/* struct used for search, find, list queries */
|
/* struct used for search, find, list queries */
|
||||||
typedef struct _LocateTagItem {
|
typedef struct _LocateTagItem {
|
||||||
mpd_sint8 tagType;
|
int8_t tagType;
|
||||||
/* what we are looking for */
|
/* what we are looking for */
|
||||||
char *needle;
|
char *needle;
|
||||||
} LocateTagItem;
|
} LocateTagItem;
|
||||||
|
151
src/metadata_pipe.c
Normal file
151
src/metadata_pipe.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/* the Music Player Daemon (MPD)
|
||||||
|
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
|
||||||
|
* This project's homepage is: http://www.musicpd.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metadata_pipe.h"
|
||||||
|
#include "ringbuf.h"
|
||||||
|
#include "decode.h"
|
||||||
|
#include "os_compat.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "outputBuffer.h"
|
||||||
|
#include "gcc.h"
|
||||||
|
|
||||||
|
static struct ringbuf *mp;
|
||||||
|
|
||||||
|
/* Each one of these is a packet inside the metadata pipe */
|
||||||
|
struct tag_container {
|
||||||
|
float metadata_time;
|
||||||
|
uint8_t seq; /* ob.seq_decoder at time of metadata_pipe_send() */
|
||||||
|
struct mpd_tag *tag; /* our payload */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have two readers even though ringbuf was designed for one (locklessly),
|
||||||
|
* so we will use a lock to allow readers to safely read. Writing is only
|
||||||
|
* done from one thread, so it will never block or clobber.
|
||||||
|
*/
|
||||||
|
static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static struct mpd_tag *current_tag; /* requires read_lock for both r/w access */
|
||||||
|
|
||||||
|
static void metadata_pipe_finish(void)
|
||||||
|
{
|
||||||
|
ringbuf_free(mp);
|
||||||
|
if (current_tag)
|
||||||
|
tag_free(current_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_metadata_pipe(void)
|
||||||
|
{
|
||||||
|
mp = ringbuf_create(sizeof(struct tag_container) * 16);
|
||||||
|
atexit(metadata_pipe_finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
void metadata_pipe_send(struct mpd_tag *tag, float metadata_time)
|
||||||
|
{
|
||||||
|
struct tag_container tc;
|
||||||
|
size_t written;
|
||||||
|
|
||||||
|
assert(pthread_equal(pthread_self(), dc.thread));
|
||||||
|
|
||||||
|
if (mpd_unlikely(ringbuf_write_space(mp)
|
||||||
|
< sizeof(struct tag_container))) {
|
||||||
|
DEBUG("metadata_pipe: insufficient buffer space, dropping\n");
|
||||||
|
tag_free(tag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.tag = tag;
|
||||||
|
tc.metadata_time = metadata_time;
|
||||||
|
tc.seq = ob_get_decoder_sequence();
|
||||||
|
written = ringbuf_write(mp, &tc, sizeof(struct tag_container));
|
||||||
|
assert(written == sizeof(struct tag_container));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mpd_tag * metadata_pipe_recv(void)
|
||||||
|
{
|
||||||
|
struct tag_container tc;
|
||||||
|
size_t r;
|
||||||
|
static const size_t uint8_t_max = 255; /* XXX CLEANUP */
|
||||||
|
uint8_t expect_seq = ob_get_player_sequence();
|
||||||
|
unsigned long current_time = ob_get_elapsed_time();
|
||||||
|
struct mpd_tag *tag = NULL;
|
||||||
|
|
||||||
|
if (pthread_mutex_trylock(&read_lock) == EBUSY)
|
||||||
|
return NULL;
|
||||||
|
retry:
|
||||||
|
if (!(r = ringbuf_peek(mp, &tc, sizeof(struct tag_container))))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
assert(r == sizeof(struct tag_container));
|
||||||
|
assert(tc.tag);
|
||||||
|
if (expect_seq == tc.seq) {
|
||||||
|
if (current_time < tc.metadata_time)
|
||||||
|
goto out; /* not ready for tag yet */
|
||||||
|
if (tag_equal(tc.tag, current_tag)) {
|
||||||
|
tag_free(tc.tag);
|
||||||
|
ringbuf_read_advance(mp, sizeof(struct tag_container));
|
||||||
|
goto out; /* nothing changed, don't bother */
|
||||||
|
}
|
||||||
|
tag = tag_dup(tc.tag);
|
||||||
|
if (current_tag)
|
||||||
|
tag_free(current_tag);
|
||||||
|
current_tag = tc.tag;
|
||||||
|
ringbuf_read_advance(mp, sizeof(struct tag_container));
|
||||||
|
} else if (expect_seq > tc.seq ||
|
||||||
|
(!expect_seq && tc.seq == uint8_t_max)) {
|
||||||
|
DEBUG("metadata_pipe: reader is ahead of writer\n");
|
||||||
|
tag_free(tc.tag);
|
||||||
|
ringbuf_read_advance(mp, sizeof(struct tag_container));
|
||||||
|
goto retry; /* read and skip packets */
|
||||||
|
} /* else not ready for tag yet */
|
||||||
|
out:
|
||||||
|
pthread_mutex_unlock(&read_lock);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mpd_tag *metadata_pipe_current(void)
|
||||||
|
{
|
||||||
|
struct mpd_tag *tag;
|
||||||
|
|
||||||
|
assert(! pthread_equal(pthread_self(), dc.thread));
|
||||||
|
if (pthread_mutex_trylock(&read_lock) == EBUSY)
|
||||||
|
return NULL;
|
||||||
|
tag = current_tag ? tag_dup(current_tag) : NULL;
|
||||||
|
pthread_mutex_unlock(&read_lock);
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void metadata_pipe_clear(void)
|
||||||
|
{
|
||||||
|
struct tag_container tc;
|
||||||
|
size_t r;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&read_lock);
|
||||||
|
|
||||||
|
while ((r = ringbuf_read(mp, &tc, sizeof(struct tag_container)))) {
|
||||||
|
assert(r == sizeof(struct tag_container));
|
||||||
|
tag_free(tc.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_tag) {
|
||||||
|
tag_free(current_tag);
|
||||||
|
current_tag = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&read_lock);
|
||||||
|
}
|
@ -31,14 +31,7 @@
|
|||||||
* 2) optional features in core (libsamplerate, avahi, ...)
|
* 2) optional features in core (libsamplerate, avahi, ...)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_STDINT_H)
|
#include "mpd_types.h"
|
||||||
#include <stdint.h>
|
|
||||||
#elif defined(HAVE_INTTYPES_H)
|
|
||||||
#include <inttypes.h>
|
|
||||||
#elif defined(HAVE_SYS_INTTYPES_H)
|
|
||||||
#include <sys/inttypes.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#define _XOPEN_SOURCE 600 /* for posix_fadvise, won't hurt if not available */
|
#define _XOPEN_SOURCE 600 /* for posix_fadvise, won't hurt if not available */
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
88
src/outputBuffer_accessors.h
Normal file
88
src/outputBuffer_accessors.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* the Music Player Daemon (MPD)
|
||||||
|
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
|
||||||
|
* This project's homepage is: http://www.musicpd.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some of the most boring code in the world that I didn't want cluttering
|
||||||
|
* up outputBuffer.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned long ob_get_elapsed_time(void)
|
||||||
|
{
|
||||||
|
return (unsigned long)(ob.elapsed_time + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ob_get_total_time(void)
|
||||||
|
{
|
||||||
|
return (unsigned long)(ob.total_time + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ob_get_bit_rate(void)
|
||||||
|
{
|
||||||
|
return (unsigned int)ob.bit_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ob_get_channels(void)
|
||||||
|
{
|
||||||
|
return (unsigned int)ob.audio_format.channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ob_get_sample_rate(void)
|
||||||
|
{
|
||||||
|
return (unsigned int)ob.audio_format.sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ob_get_bits(void)
|
||||||
|
{
|
||||||
|
return (unsigned int)ob.audio_format.bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ob_set_sw_volume(int volume)
|
||||||
|
{
|
||||||
|
ob.sw_vol = (volume > 1000) ? 1000 : (volume < 0 ? 0 : volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ob_set_xfade(float xfade_sec)
|
||||||
|
{
|
||||||
|
ob.xfade_time = (xfade_sec < 0) ? 0 : xfade_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ob_get_xfade(void)
|
||||||
|
{
|
||||||
|
return ob.xfade_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ob_state ob_get_state(void)
|
||||||
|
{
|
||||||
|
return ob.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioFormat *ob_audio_format(void)
|
||||||
|
{
|
||||||
|
return &ob.audio_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ob_get_decoder_sequence(void)
|
||||||
|
{
|
||||||
|
return ob.seq_decoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ob_get_player_sequence(void)
|
||||||
|
{
|
||||||
|
return ob.seq_player;
|
||||||
|
}
|
||||||
|
|
133
src/outputBuffer_ob_send.h
Normal file
133
src/outputBuffer_ob_send.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* This file only contains ob_send() and private functions
|
||||||
|
* needed to implement ob_send()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is one of two places where dc.thread can block,
|
||||||
|
* the other is readFromInputStream
|
||||||
|
*/
|
||||||
|
static enum dc_action await_buffer_space(void)
|
||||||
|
{
|
||||||
|
assert(pthread_equal(pthread_self(), dc.thread));
|
||||||
|
/* DEBUG("Waiting for buffer space\n"); */
|
||||||
|
assert(dc.state != DC_STATE_STOP);
|
||||||
|
|
||||||
|
dc_halt();
|
||||||
|
/* DEBUG("done waiting for buffer space\n"); */
|
||||||
|
return dc.action;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will modify its input */
|
||||||
|
static void do_audio_conversion(void **data, size_t *len)
|
||||||
|
{
|
||||||
|
size_t newlen;
|
||||||
|
|
||||||
|
assert(pthread_equal(pthread_self(), dc.thread));
|
||||||
|
newlen = pcm_sizeOfConvBuffer(&dc.audio_format, *len, &ob.audio_format);
|
||||||
|
if (newlen > ob.conv_buf_len) {
|
||||||
|
ob.conv_buf = xrealloc(ob.conv_buf, newlen);
|
||||||
|
ob.conv_buf_len = newlen;
|
||||||
|
}
|
||||||
|
*len = pcm_convertAudioFormat(&dc.audio_format, *data, *len,
|
||||||
|
&ob.audio_format, ob.conv_buf,
|
||||||
|
&ob.conv_state);
|
||||||
|
*data = ob.conv_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ensure_audio_format_sanity(void **data, size_t *len)
|
||||||
|
{
|
||||||
|
static uint8_t seq_last;
|
||||||
|
|
||||||
|
assert(pthread_equal(pthread_self(), dc.thread));
|
||||||
|
if (mpd_unlikely(seq_last != ob.seq_decoder)) {
|
||||||
|
seq_last = ob.seq_decoder;
|
||||||
|
if (cmpAudioFormat(&dc.audio_format, &ob.audio_format))
|
||||||
|
getOutputAudioFormat(&dc.audio_format,
|
||||||
|
&ob.audio_format);
|
||||||
|
}
|
||||||
|
if (cmpAudioFormat(&ob.audio_format, &dc.audio_format))
|
||||||
|
do_audio_conversion(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_playback(void)
|
||||||
|
{
|
||||||
|
assert(pthread_equal(pthread_self(), dc.thread));
|
||||||
|
if (mpd_unlikely(ob.state == OB_STATE_STOP &&
|
||||||
|
player_errno == PLAYER_ERROR_NONE)) {
|
||||||
|
ob_trigger_action(OB_ACTION_PLAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum dc_action
|
||||||
|
ob_send(void *data, size_t len,
|
||||||
|
float decode_time, uint16_t bit_rate, ReplayGainInfo * rgi)
|
||||||
|
{
|
||||||
|
struct rbvec vec[2];
|
||||||
|
struct ob_chunk *c;
|
||||||
|
size_t idx;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
assert(pthread_equal(pthread_self(), dc.thread));
|
||||||
|
|
||||||
|
ensure_audio_format_sanity(&data, &len);
|
||||||
|
|
||||||
|
if (rgi && (replayGainState != REPLAYGAIN_OFF))
|
||||||
|
doReplayGain(rgi, data, len, &ob.audio_format);
|
||||||
|
else if (normalizationEnabled)
|
||||||
|
normalizeData(data, len, &ob.audio_format);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* full buffer, loop check in case of spurious wakeups */
|
||||||
|
while (!ringbuf_get_write_vector(ob.index, vec)) {
|
||||||
|
enum dc_action rv = await_buffer_space();
|
||||||
|
if (rv != DC_ACTION_NONE)
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(vec); i++) {
|
||||||
|
for (j = 0; j < vec[i].len; j++) {
|
||||||
|
size_t c_len;
|
||||||
|
idx = vec[i].base - ob.index->buf + j;
|
||||||
|
c = &(ob.chunks[idx]);
|
||||||
|
|
||||||
|
if (!c->len) { /* populate empty chunk */
|
||||||
|
c->seq = ob.seq_decoder;
|
||||||
|
c->time = decode_time;
|
||||||
|
c->bit_rate = bit_rate;
|
||||||
|
c_len = len > CHUNK_SIZE ? CHUNK_SIZE
|
||||||
|
: len;
|
||||||
|
c->len = (uint16_t)c_len;
|
||||||
|
memcpy(c->data, data, c_len);
|
||||||
|
} else { /* partially filled chunk */
|
||||||
|
size_t max = CHUNK_SIZE - c->len;
|
||||||
|
assert(c->seq == ob.seq_decoder);
|
||||||
|
c_len = len > max ? max : len;
|
||||||
|
assert(c_len <= CHUNK_SIZE);
|
||||||
|
memcpy(c->data + c->len, data, c_len);
|
||||||
|
c->len += c_len;
|
||||||
|
assert(c->len <= CHUNK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* feed ob.thread ASAP, otherwise ob.thread
|
||||||
|
* will just play silence
|
||||||
|
*/
|
||||||
|
if (c->len == CHUNK_SIZE)
|
||||||
|
ringbuf_write_advance(ob.index, 1);
|
||||||
|
|
||||||
|
assert(len >= c_len);
|
||||||
|
len -= c_len;
|
||||||
|
if (!len) {
|
||||||
|
start_playback();
|
||||||
|
return dc.action;
|
||||||
|
}
|
||||||
|
data = (unsigned char *)data + c_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(__FILE__ && __LINE__ && "We should never get here" && 0);
|
||||||
|
return DC_ACTION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -35,8 +35,8 @@ pcm_dither(void)
|
|||||||
* Check if the value is within the range of the provided bit size,
|
* Check if the value is within the range of the provided bit size,
|
||||||
* and caps it if necessary.
|
* and caps it if necessary.
|
||||||
*/
|
*/
|
||||||
static mpd_sint32
|
static int32_t
|
||||||
pcm_range(mpd_sint32 sample, unsigned bits)
|
pcm_range(int32_t sample, unsigned bits)
|
||||||
{
|
{
|
||||||
if (mpd_unlikely(sample < (-1 << (bits - 1))))
|
if (mpd_unlikely(sample < (-1 << (bits - 1))))
|
||||||
return -1 << (bits - 1);
|
return -1 << (bits - 1);
|
||||||
@ -49,9 +49,9 @@ void pcm_volumeChange(char *buffer, int bufferSize,
|
|||||||
const struct audio_format *format,
|
const struct audio_format *format,
|
||||||
int volume)
|
int volume)
|
||||||
{
|
{
|
||||||
mpd_sint32 temp32;
|
int32_t temp32;
|
||||||
mpd_sint8 *buffer8 = (mpd_sint8 *) buffer;
|
int8_t *buffer8 = (int8_t *) buffer;
|
||||||
mpd_sint16 *buffer16 = (mpd_sint16 *) buffer;
|
int16_t *buffer16 = (int16_t *) buffer;
|
||||||
|
|
||||||
if (volume >= 1000)
|
if (volume >= 1000)
|
||||||
return;
|
return;
|
||||||
@ -96,11 +96,11 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1,
|
|||||||
size_t bufferSize2, int vol1, int vol2,
|
size_t bufferSize2, int vol1, int vol2,
|
||||||
const struct audio_format *format)
|
const struct audio_format *format)
|
||||||
{
|
{
|
||||||
mpd_sint32 temp32;
|
int32_t temp32;
|
||||||
mpd_sint8 *buffer8_1 = (mpd_sint8 *) buffer1;
|
int8_t *buffer8_1 = (int8_t *) buffer1;
|
||||||
const mpd_sint8 *buffer8_2 = (const mpd_sint8 *) buffer2;
|
const int8_t *buffer8_2 = (const int8_t *) buffer2;
|
||||||
mpd_sint16 *buffer16_1 = (mpd_sint16 *) buffer1;
|
int16_t *buffer16_1 = (int16_t *) buffer1;
|
||||||
const mpd_sint16 *buffer16_2 = (const mpd_sint16 *) buffer2;
|
const int16_t *buffer16_2 = (const int16_t *) buffer2;
|
||||||
|
|
||||||
switch (format->bits) {
|
switch (format->bits) {
|
||||||
case 16:
|
case 16:
|
||||||
@ -195,9 +195,9 @@ out:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBSAMPLERATE
|
#ifdef HAVE_LIBSAMPLERATE
|
||||||
static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
|
static size_t pcm_convertSampleRate(int8_t channels, uint32_t inSampleRate,
|
||||||
const char *inBuffer, size_t inSize,
|
const char *inBuffer, size_t inSize,
|
||||||
mpd_uint32 outSampleRate, char *outBuffer,
|
uint32_t outSampleRate, char *outBuffer,
|
||||||
size_t outSize, ConvState *convState)
|
size_t outSize, ConvState *convState)
|
||||||
{
|
{
|
||||||
static int convalgo = -1;
|
static int convalgo = -1;
|
||||||
@ -271,19 +271,19 @@ static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
|
|||||||
}
|
}
|
||||||
#else /* !HAVE_LIBSAMPLERATE */
|
#else /* !HAVE_LIBSAMPLERATE */
|
||||||
/* resampling code blatantly ripped from ESD */
|
/* resampling code blatantly ripped from ESD */
|
||||||
static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
|
static size_t pcm_convertSampleRate(int8_t channels, uint32_t inSampleRate,
|
||||||
const char *inBuffer,
|
const char *inBuffer,
|
||||||
mpd_unused size_t inSize,
|
mpd_unused size_t inSize,
|
||||||
mpd_uint32 outSampleRate, char *outBuffer,
|
uint32_t outSampleRate, char *outBuffer,
|
||||||
size_t outSize,
|
size_t outSize,
|
||||||
mpd_unused ConvState *convState)
|
mpd_unused ConvState *convState)
|
||||||
{
|
{
|
||||||
mpd_uint32 rd_dat = 0;
|
uint32_t rd_dat = 0;
|
||||||
mpd_uint32 wr_dat = 0;
|
uint32_t wr_dat = 0;
|
||||||
mpd_sint16 *in = (mpd_sint16 *)inBuffer;
|
int16_t *in = (int16_t *)inBuffer;
|
||||||
mpd_sint16 *out = (mpd_sint16 *)outBuffer;
|
int16_t *out = (int16_t *)outBuffer;
|
||||||
mpd_uint32 nlen = outSize / 2;
|
uint32_t nlen = outSize / 2;
|
||||||
mpd_sint16 lsample, rsample;
|
int16_t lsample, rsample;
|
||||||
|
|
||||||
switch (channels) {
|
switch (channels) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -313,14 +313,14 @@ static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
|
|||||||
}
|
}
|
||||||
#endif /* !HAVE_LIBSAMPLERATE */
|
#endif /* !HAVE_LIBSAMPLERATE */
|
||||||
|
|
||||||
static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer,
|
static char *pcm_convertChannels(int8_t channels, const char *inBuffer,
|
||||||
size_t inSize, size_t *outSize)
|
size_t inSize, size_t *outSize)
|
||||||
{
|
{
|
||||||
static char *buf;
|
static char *buf;
|
||||||
static size_t len;
|
static size_t len;
|
||||||
char *outBuffer = NULL;
|
char *outBuffer = NULL;
|
||||||
const mpd_sint16 *in;
|
const int16_t *in;
|
||||||
mpd_sint16 *out;
|
int16_t *out;
|
||||||
int inSamples, i;
|
int inSamples, i;
|
||||||
|
|
||||||
switch (channels) {
|
switch (channels) {
|
||||||
@ -334,8 +334,8 @@ static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer,
|
|||||||
outBuffer = buf;
|
outBuffer = buf;
|
||||||
|
|
||||||
inSamples = inSize >> 1;
|
inSamples = inSize >> 1;
|
||||||
in = (const mpd_sint16 *)inBuffer;
|
in = (const int16_t *)inBuffer;
|
||||||
out = (mpd_sint16 *)outBuffer;
|
out = (int16_t *)outBuffer;
|
||||||
for (i = 0; i < inSamples; i++) {
|
for (i = 0; i < inSamples; i++) {
|
||||||
*out++ = *in;
|
*out++ = *in;
|
||||||
*out++ = *in++;
|
*out++ = *in++;
|
||||||
@ -352,8 +352,8 @@ static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer,
|
|||||||
outBuffer = buf;
|
outBuffer = buf;
|
||||||
|
|
||||||
inSamples = inSize >> 2;
|
inSamples = inSize >> 2;
|
||||||
in = (const mpd_sint16 *)inBuffer;
|
in = (const int16_t *)inBuffer;
|
||||||
out = (mpd_sint16 *)outBuffer;
|
out = (int16_t *)outBuffer;
|
||||||
for (i = 0; i < inSamples; i++) {
|
for (i = 0; i < inSamples; i++) {
|
||||||
*out = (*in++) / 2;
|
*out = (*in++) / 2;
|
||||||
*out++ += (*in++) / 2;
|
*out++ += (*in++) / 2;
|
||||||
@ -367,14 +367,14 @@ static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer,
|
|||||||
return outBuffer;
|
return outBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *pcm_convertTo16bit(mpd_sint8 bits, const char *inBuffer,
|
static const char *pcm_convertTo16bit(int8_t bits, const char *inBuffer,
|
||||||
size_t inSize, size_t *outSize)
|
size_t inSize, size_t *outSize)
|
||||||
{
|
{
|
||||||
static char *buf;
|
static char *buf;
|
||||||
static size_t len;
|
static size_t len;
|
||||||
char *outBuffer = NULL;
|
char *outBuffer = NULL;
|
||||||
const mpd_sint8 *in;
|
const int8_t *in;
|
||||||
mpd_sint16 *out;
|
int16_t *out;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
switch (bits) {
|
switch (bits) {
|
||||||
@ -386,8 +386,8 @@ static const char *pcm_convertTo16bit(mpd_sint8 bits, const char *inBuffer,
|
|||||||
}
|
}
|
||||||
outBuffer = buf;
|
outBuffer = buf;
|
||||||
|
|
||||||
in = (const mpd_sint8 *)inBuffer;
|
in = (const int8_t *)inBuffer;
|
||||||
out = (mpd_sint16 *)outBuffer;
|
out = (int16_t *)outBuffer;
|
||||||
for (i = 0; i < inSize; i++)
|
for (i = 0; i < inSize; i++)
|
||||||
*out++ = (*in++) << 8;
|
*out++ = (*in++) << 8;
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ typedef struct _ConvState {
|
|||||||
SRC_DATA data;
|
SRC_DATA data;
|
||||||
size_t dataInSize;
|
size_t dataInSize;
|
||||||
size_t dataOutSize;
|
size_t dataOutSize;
|
||||||
mpd_sint8 lastChannels;
|
int8_t lastChannels;
|
||||||
mpd_uint32 lastInSampleRate;
|
uint32_t lastInSampleRate;
|
||||||
mpd_uint32 lastOutSampleRate;
|
uint32_t lastOutSampleRate;
|
||||||
#endif
|
#endif
|
||||||
/* Strict C99 doesn't allow empty structs */
|
/* Strict C99 doesn't allow empty structs */
|
||||||
int error;
|
int error;
|
||||||
|
@ -108,9 +108,9 @@ void freeReplayGainInfo(ReplayGainInfo * info)
|
|||||||
void doReplayGain(ReplayGainInfo * info, char *buffer, int bufferSize,
|
void doReplayGain(ReplayGainInfo * info, char *buffer, int bufferSize,
|
||||||
const struct audio_format *format)
|
const struct audio_format *format)
|
||||||
{
|
{
|
||||||
mpd_sint16 *buffer16;
|
int16_t *buffer16;
|
||||||
mpd_sint8 *buffer8;
|
int8_t *buffer8;
|
||||||
mpd_sint32 temp32;
|
int32_t temp32;
|
||||||
float scale;
|
float scale;
|
||||||
|
|
||||||
if (replayGainState == REPLAYGAIN_OFF || !info)
|
if (replayGainState == REPLAYGAIN_OFF || !info)
|
||||||
@ -136,8 +136,8 @@ void doReplayGain(ReplayGainInfo * info, char *buffer, int bufferSize,
|
|||||||
if (info->scale <= 1.01 && info->scale >= 0.99)
|
if (info->scale <= 1.01 && info->scale >= 0.99)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
buffer16 = (mpd_sint16 *) buffer;
|
buffer16 = (int16_t *) buffer;
|
||||||
buffer8 = (mpd_sint8 *) buffer;
|
buffer8 = (int8_t *) buffer;
|
||||||
|
|
||||||
scale = info->scale;
|
scale = info->scale;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ const char *mpdTagItemKeys[TAG_NUM_OF_ITEM_TYPES] = {
|
|||||||
"Disc"
|
"Disc"
|
||||||
};
|
};
|
||||||
|
|
||||||
mpd_sint8 ignoreTagItems[TAG_NUM_OF_ITEM_TYPES];
|
int8_t ignoreTagItems[TAG_NUM_OF_ITEM_TYPES];
|
||||||
|
|
||||||
static size_t items_size(const struct tag *tag)
|
static size_t items_size(const struct tag *tag)
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ struct tag_item {
|
|||||||
struct tag {
|
struct tag {
|
||||||
int time;
|
int time;
|
||||||
struct tag_item **items;
|
struct tag_item **items;
|
||||||
mpd_uint8 numOfItems;
|
uint8_t numOfItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag *tag_ape_load(const char *file);
|
struct tag *tag_ape_load(const char *file);
|
||||||
|
@ -19,6 +19,6 @@
|
|||||||
#ifndef TAG_INTERNAL_H
|
#ifndef TAG_INTERNAL_H
|
||||||
#define TAG_INTERNAL_H
|
#define TAG_INTERNAL_H
|
||||||
|
|
||||||
extern mpd_sint8 ignoreTagItems[TAG_NUM_OF_ITEM_TYPES];
|
extern int8_t ignoreTagItems[TAG_NUM_OF_ITEM_TYPES];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user