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;
}
Ejemplo n.º 5
0
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;
}