void vsyslog(int priority, const char *message, va_list ap) { msgheader(); fputs("syslog(", stderr); print_priority(priority); fputs(", ", stderr); vfprintf(stderr, message, ap); fputs(")\n", stderr); }
static void cbf(int event, void* user, void *info) { if(event != AudioTrack::EVENT_MORE_DATA) { if(event == AudioTrack::EVENT_UNDERRUN) __android_log_print(ANDROID_LOG_ERROR,"liblossless","callback: EVENT_UNDERRUN"); return; } msm_ctx *ctx = (msm_ctx *) user; AudioTrack::Buffer *buff = (AudioTrack::Buffer *) info; unsigned char *c = (unsigned char *) buff->raw; unsigned int k; if(!buff->size) { __android_log_print(ANDROID_LOG_ERROR,"liblossless","callback: audiotrack requested zero bytes"); return; } pthread_mutex_lock(&ctx->cbmutex); if(ctx->cbstart < 0) { // we have been stopped from libmediacb_stop pthread_mutex_unlock(&ctx->cbmutex); return; } k = ctx->cbbuf_size - get_free_bytes(ctx); // k == bytes available for output if(k < buff->size) { __android_log_print(ANDROID_LOG_INFO,"liblossless", "callback: decoder lags, audiotrack requested too much (%d, avail %d)",buff->size, k); buff->size = k; // update if we write less if(k == 0) { pthread_cond_signal(&ctx->cbdone); pthread_mutex_unlock(&ctx->cbmutex); return; } } k = ctx->cbbuf_size - ctx->cbstart; if(k > buff->size) { memcpy(c,ctx->cbbuf+ctx->cbstart,buff->size); ctx->cbstart += buff->size; } else if(k < buff->size) { memcpy(c,ctx->cbbuf+ctx->cbstart,k); memcpy(c+k,ctx->cbbuf,buff->size-k); ctx->cbstart = buff->size-k; } else { memcpy(c,ctx->cbbuf+ctx->cbstart,buff->size); ctx->cbstart = 0; } pthread_cond_signal(&ctx->cbcond); pthread_mutex_unlock(&ctx->cbmutex); static int s = 0; if(!s) { // setpriority(0,0,-19); print_priority(__FUNCTION__); s = 1; } }
ssize_t libmediacb_write(msm_ctx *ctx, const void *buf, size_t cnt) { __android_log_print(ANDROID_LOG_INFO,"liblossless","WE REACHED WRITE"); int k; int count = (int)cnt; if(!ctx || !ctx->track || count > ctx->cbbuf_size || ctx->cbstart < 0) return -1; pthread_mutex_lock(&ctx->cbmutex); k = get_free_bytes(ctx); while(k <= count && ctx->cbstart >=0) { // prohibit k==count to prevent from cbstart==cbend after write // __android_log_print(ANDROID_LOG_INFO,"liblossless","libmediacb_write: decoder is ahead, waiting for callback"); pthread_cond_wait(&ctx->cbcond,&ctx->cbmutex); k = get_free_bytes(ctx); } if(ctx->cbstart < 0) { // we have been stopped from libmediacb_stop pthread_mutex_unlock(&ctx->cbmutex); return -1; } k = ctx->cbbuf_size - ctx->cbend; if(k > count) { memcpy(ctx->cbbuf+ctx->cbend,buf,count); ctx->cbend += count; } else if(k < count) { memcpy(ctx->cbbuf+ctx->cbend,buf,k); memcpy(ctx->cbbuf,(unsigned char *)buf+k,count-k); ctx->cbend = count-k; } else { memcpy(ctx->cbbuf+ctx->cbend,buf,count); ctx->cbend = 0; } pthread_mutex_unlock(&ctx->cbmutex); static int s(0); if(!s) { print_priority(__FUNCTION__); s = 1; } return count; }
int libmediacb_start(msm_ctx *ctx, int channels, int samplerate) { __android_log_print(ANDROID_LOG_INFO,"liblossless","libmedia_ START REEEEACHED REACHEDDDDDD1"); status_t status; int chans; if(!ctx) return LIBLOSSLESS_ERR_NOCTX; __android_log_print(ANDROID_LOG_INFO,"liblossless","libmediacb_start ctx=%p chans=%d rate=%d afd=%d atrack=%p", ctx, channels, samplerate,ctx->afd,ctx->track); AudioTrack* atrack = (AudioTrack *) ctx->track; if(atrack && ctx->samplerate == samplerate && ctx->channels == channels) { __android_log_print(ANDROID_LOG_INFO,"liblossless","same audio track parameters, restarting"); atrack->stop(); atrack->flush(); ctx->cbstart = 0; ctx->cbend = 0; atrack->start(); return 0; } if(!ctx->cbbuf) { ctx->cbbuf = (unsigned char *) malloc(DEFAULT_CB_BUFSZ); if(!ctx->cbbuf) return LIBLOSSLESS_ERR_NOMEM; ctx->cbbuf_size = DEFAULT_CB_BUFSZ; } ctx->cbstart = 0; ctx->cbend = 0; if(!atrack) { atrack = new AudioTrack(); if(!atrack) { __android_log_print(ANDROID_LOG_ERROR,"liblossless","could not create AudioTrack!"); return LIBLOSSLESS_ERR_INIT; } __android_log_print(ANDROID_LOG_INFO,"liblossless","AudioTrack created at %p. Now trying to setup (buffsz %d)", atrack, DEFAULT_ATRACK_CONF_BUFSZ); if(!sdk_version) { char c[PROP_VALUE_MAX]; if(__system_property_get("ro.build.version.sdk",c) > 0) sscanf(c,"%d",&sdk_version); else sdk_version = 8; __android_log_print(ANDROID_LOG_INFO,"liblossless","got sdk_version %d", sdk_version); } if(sdk_version > 13) chans = (channels == 2) ? 3 : 1; else if(sdk_version > 6) chans = (channels == 2) ? 12 : 4; else chans = channels; #ifdef BUILD_JB status = atrack->set(_MUSIC, samplerate, FMTBPS, chans, DEFAULT_ATRACK_CONF_BUFSZ/(2*channels),AUDIO_OUTPUT_FLAG_NONE,cbf,ctx); #else status = atrack->set(_MUSIC, samplerate, FMTBPS, chans, DEFAULT_ATRACK_CONF_BUFSZ/(2*channels),0,cbf,ctx); #endif if(status != NO_ERROR) { __android_log_print(ANDROID_LOG_INFO,"liblossless","AudioTrack setup failed"); delete atrack; return LIBLOSSLESS_ERR_INIT; } ctx->track = atrack; } else { atrack->stop(); atrack->flush(); ctx->cbstart = 0; ctx->cbend = 0; __android_log_print(ANDROID_LOG_INFO,"liblossless","trying to reconfigure old AudioTrack"); status = atrack->setSampleRate(samplerate); if(status != NO_ERROR) { __android_log_print(ANDROID_LOG_INFO,"liblossless","could not set AudioTrack sample rate"); return LIBLOSSLESS_ERR_INIT; } } __android_log_print(ANDROID_LOG_INFO,"liblossless","AudioTrack setup OK, starting audio!"); ctx->conf_size = DEFAULT_CONF_BUFSZ; atrack->start(); __android_log_print(ANDROID_LOG_INFO,"liblossless","playback started!"); atrack->setPositionUpdatePeriod(0); atrack->setMarkerPosition(0); static int s(0); if(!s) { print_priority(__FUNCTION__); s = 1; } return 0; }