uint32_t hdmi_out_get_sample_rate(const struct audio_stream *stream) { hdmi_out_t *out = (hdmi_out_t*)stream; struct pcm_config *config = &out->config; TRACEM("stream=%p returning %d", stream, config->rate); return config->rate; }
static int hdmi_adev_set_parameters(audio_hw_device_t *dev, const char *kv_pairs) { TRACEM("dev=%p kv_pairss='%s'", dev, kv_pairs); struct str_parms *params; char *str; char value[HDMI_MAX_CHANNELS]; int ret, x, val, numMatch = 0; struct hdmi_device_t *adev = (struct hdmi_device_t *)dev; params = str_parms_create_str(kv_pairs); //Handle maximum of 8 channels ret = str_parms_get_str(params, "channel_map", value, HDMI_MAX_CHANNELS); if (ret >= 0) { val = strtol(value, NULL, 10); for(x = 0; x < HDMI_MAX_CHANNELS; x++) { adev->map[x] = (val & (0xF << x*4)) >> x*4; if (adev->map[x] == cea_channel_map[x]) numMatch += 1; } if (numMatch >= 5) adev->CEAMap = true; else adev->CEAMap = false; }
static int hdmi_out_open_pcm(hdmi_out_t *out) { int card = hdmi_out_find_card(); int dev = HDMI_PCM_DEV; int ret; TRACEM("out=%p", out); /* out->up must be 0 (down) */ if (out->up) { ALOGE("Trying to open a PCM that's already up. " "This will probably deadlock... so aborting"); return 0; } out->pcm = pcm_open(card, dev, PCM_OUT, &out->config); if(out->pcm && pcm_is_ready(out->pcm)) { out->up = 1; ret = 0; } else { ALOGE("cannot open HDMI pcm card %d dev %d error: %s", card, dev, pcm_get_error(out->pcm)); pcm_close(out->pcm); out->pcm = 0; out->up = 0; ret = 1; } return ret; }
/* returns milliseconds */ uint32_t hdmi_out_get_latency(const struct audio_stream_out *stream) { uint32_t latency; hdmi_out_t *out = (hdmi_out_t*)stream; struct pcm_config *config = &out->config; TRACEM("stream=%p", stream); return (1000 * config->period_size * config->period_count) / config->rate; }
local void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { nodeptr *np, *ap, q; int actsafe; matrix trQM; if (Update(p)) { // new forces needed in node? np = nptr; // start new active list actsafe = actmax - NSUB; // leave room for NSUB more for (ap = aptr; ap < nptr; ap++) { // loop over active nodes if (Type(*ap) == CELL) { // is this node a cell? if (accept(*ap, psize, pmid)) { // does it pass the test? if (Mass(*ap) > 0.0) { // and contribute to field? Mass(cptr) = Mass(*ap); // copy to interaction list SETV(Pos(cptr), Pos(*ap)); #if defined(SOFTCORR) TRACEM(Trace(cptr), Quad(*ap)); // save trace in copy SETMI(trQM); MULMS(trQM, trQM, Trace(cptr)/3); SUBM(Quad(cptr), Quad(*ap), trQM); // store traceless moment #else SETM(Quad(cptr), Quad(*ap)); // copy traceless moment #endif cptr++; // and bump cell array ptr } } else { // this cell fails the test if (np - active >= actsafe) // make sure list has room fatal("%s.walktree: active list overflow\n", getprog()); for (q = More(*ap); q != Next(*ap); q = Next(q)) // loop over all subcells *np++= q; // put them on active list } } else // else this node is a body if (*ap != p && Mass(*ap) > 0.0) { // not self-interaction? --bptr; // bump body array ptr Mass(bptr) = Mass(*ap); // and copy data to array SETV(Pos(bptr), Pos(*ap)); } } acttot = MAX(acttot, np - active); // keep track of max active if (np != nptr) { // if new actives were added walksub(nptr, np, cptr, bptr, p, psize, pmid); // then visit next level } else { // else no actives left if (Type(p) != BODY) // make sure we got a body fatal("%s.walktree: recursion terminated with cell\n" " p = 0x%x psize = %.8f Mass(p) = %g\n" " pmid = (%.8f,%.8f,%.8f)\n Pos(p) = (%.8f,%.8f,%.8f)\n", getprog(), (int) p, psize, Mass(p), pmid[0], pmid[1], pmid[2], Pos(p)[0], Pos(p)[1], Pos(p)[2]); gravsum((bodyptr) p, cptr, bptr); // sum force on this body } } }
/* Returns bytes for ONE PERIOD */ size_t hdmi_out_get_buffer_size(const struct audio_stream *stream) { hdmi_out_t *out = (hdmi_out_t*)stream; struct pcm_config *config = &out->config; size_t ans; ans = audio_stream_frame_size((struct audio_stream*)stream) * config->period_size; TRACEM("stream=%p returning %u", stream, ans); return ans; }
int hdmi_out_standby(struct audio_stream *stream) { hdmi_out_t *out = (hdmi_out_t*)stream; TRACEM("stream=%p", stream); if (out->up && out->pcm) { out->up = 0; pcm_close(out->pcm); out->pcm = 0; } return 0; }
ssize_t hdmi_out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { hdmi_out_t *out = (hdmi_out_t*)stream; struct hdmi_device_t *adev = (struct hdmi_device_t *)out->dev; ssize_t ret; TRACEM("stream=%p buffer=%p bytes=%d", stream, buffer, bytes); if (!out->up) { if(hdmi_out_open_pcm(out)) { ret = -ENOSYS; goto exit; } } if (out->config.channels > 2 && !adev->CEAMap){ channel_remap(stream, buffer, bytes); ret = pcm_write(out->pcm, out->buffcpy, bytes); } else { ret = pcm_write(out->pcm, buffer, bytes); } exit: if (ret != 0) { ALOGE("Error writing to HDMI pcm: %s", pcm_get_error(out->pcm)); hdmi_out_standby((struct audio_stream*)stream); unsigned int usecs = bytes * 1000000 / audio_stream_frame_size((struct audio_stream*)stream) / hdmi_out_get_sample_rate((struct audio_stream*)stream); if (usecs >= 1000000L) { usecs = 999999L; } usleep(usecs); } return bytes; }
char * hdmi_out_get_parameters(const struct audio_stream *stream, const char *keys) { struct str_parms *query = str_parms_create_str(keys); char *str; char value[256]; struct str_parms *reply = str_parms_create(); int status; hdmi_audio_caps_t caps; TRACEM("stream=%p keys='%s'", stream, keys); if (hdmi_query_audio_caps(HDMI_EDID_PATH, &caps)) { ALOGE("Unable to get the HDMI audio capabilities"); str = calloc(1, 1); goto end; } status = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value)); if (status >= 0) { unsigned sa = caps.speaker_alloc; bool first = true; /* STEREO is intentionally skipped. This code is only * executed for the 'DIRECT' interface, and we don't * want stereo on a DIRECT thread. */ value[0] = '\0'; if (SUPPORTS_ARR(sa, MASK_CEA_QUAD)) { if (!first) { strcat(value, "|"); } first = false; strcat(value, "AUDIO_CHANNEL_OUT_QUAD"); } if (SUPPORTS_ARR(sa, MASK_CEA_SURROUND)) { if (!first) { strcat(value, "|"); } first = false; strcat(value, "AUDIO_CHANNEL_OUT_SURROUND"); } if (SUPPORTS_ARR(sa, MASK_CEA_5POINT1)) { if (!first) { strcat(value, "|"); } first = false; strcat(value, "AUDIO_CHANNEL_OUT_5POINT1"); } if (SUPPORTS_ARR(sa, MASK_CEA_7POINT1)) { if (!first) { strcat(value, "|"); } first = false; strcat(value, "AUDIO_CHANNEL_OUT_7POINT1"); } str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value); str = strdup(str_parms_to_str(reply)); } else { str = strdup(keys); } ALOGV("%s() reply: '%s'", __func__, str); end: str_parms_destroy(query); str_parms_destroy(reply); return str; }
int hdmi_out_set_parameters(struct audio_stream *stream, const char *kv_pairs) { TRACEM("stream=%p kv_pairs='%s'", stream, kv_pairs); return 0; }
audio_devices_t hdmi_out_get_device(const struct audio_stream *stream) { TRACEM("stream=%p", stream); return AUDIO_DEVICE_OUT_AUX_DIGITAL; }
audio_format_t hdmi_out_get_format(const struct audio_stream *stream) { hdmi_out_t *out = (hdmi_out_t*)stream; TRACEM("stream=%p returning %x", stream, out->android_config.format); return out->android_config.format; }
audio_channel_mask_t hdmi_out_get_channels(const struct audio_stream *stream) { hdmi_out_t *out = (hdmi_out_t*)stream; TRACEM("stream=%p returning %x", stream, out->android_config.channel_mask); return out->android_config.channel_mask; }