static const uint32_t * miniflow_get__(const struct miniflow *flow, unsigned int u32_ofs) { if (!(flow->map[u32_ofs / 32] & (1u << (u32_ofs % 32)))) { static const uint32_t zero = 0; return &zero; } else { const uint32_t *p = flow->values; BUILD_ASSERT(MINI_N_MAPS == 2); if (u32_ofs < 32) { p += popcount(flow->map[0] & ((1u << u32_ofs) - 1)); } else { p += popcount(flow->map[0]); p += popcount(flow->map[1] & ((1u << (u32_ofs - 32)) - 1)); } return p; } }
static size_t out_get_buffer_size(const struct audio_stream *stream) { const struct submix_stream_out *out = reinterpret_cast<const struct submix_stream_out *>(stream); const struct submix_config& config_out = out->dev->config; size_t buffer_size = config_out.period_size * popcount(config_out.channel_mask) * sizeof(int16_t); // only PCM 16bit //ALOGV("out_get_buffer_size() returns %u, period size=%u", // buffer_size, config_out.period_size); return buffer_size; }
static int miniflow_n_values(const struct miniflow *flow) { int n, i; n = 0; for (i = 0; i < MINI_N_MAPS; i++) { n += popcount(flow->map[i]); } return n; }
/*** CPU ***/ unsigned vlc_GetCPUCount (void) { #ifndef UNDER_CE DWORD_PTR process; DWORD_PTR system; if (GetProcessAffinityMask (GetCurrentProcess(), &process, &system)) return popcount (system); #endif return 1; }
t_hash calc_material_hash(struct t_board *board) { int material[16]; clear_array(material); for (t_chess_color color = WHITE; color <= BLACK; color++) { for (int piece = KNIGHT; piece <= PAWN; piece++) { material[PIECEINDEX(color, piece)] = popcount(board->pieces[color][piece]); } } return get_material_hash(material); }
uint BitRankW32Int::BuildRankSub(uint ini,uint bloques){ uint rank=0,aux; for(uint i=ini;i<ini+bloques;i++) { if (i < integers) { aux=data[i]; rank+=popcount(aux); } } return rank; //retorna el numero de 1's del intervalo }
size_t BitSequenceRG::BuildRankSub(size_t ini, size_t bloques) { uint rank=0,aux; for(uint i=ini;i<ini+bloques;i++) { if (i < integers) { aux=data[i]; rank+=popcount(aux); } } return rank; //retorna el numero de 1's del intervalo }
uint buildRankSub(bitRankW32Int * br, uint ini,uint bloques) { uint i; uint rank=0,aux; for(i=ini;i<ini+bloques;i++) { if (i <= br->integers) { aux=br->data[i]; rank+=popcount(aux); } } return rank; //retorna el numero de 1's del intervalo }
static void disable_hyperthread(void) { unsigned long share[MAX_BITMASK_LEN]; int cpu; int bitmask_idx = 0; int i=0, count=0; bitmask_idx = CPUELT(common -> num_procs); for(i=0; i< bitmask_idx; i++){ common -> avail[count++] = 0xFFFFFFFFFFFFFFFFUL; } if(CPUMASK(common -> num_procs) != 1){ common -> avail[count++] = CPUMASK(common -> num_procs) - 1; } common -> avail_count = count; /* if(common->num_procs > 64){ */ /* fprintf(stderr, "\nOpenBLAS Warning : The number of CPU/Cores(%d) is beyond the limit(64). Terminated.\n", common->num_procs); */ /* exit(1); */ /* }else if(common->num_procs == 64){ */ /* common -> avail = 0xFFFFFFFFFFFFFFFFUL; */ /* }else */ /* common -> avail = (1UL << common -> num_procs) - 1; */ #ifdef DEBUG fprintf(stderr, "\nAvail CPUs : "); for(i=0; i<count; i++) fprintf(stderr, "%04lx ", common -> avail[i]); fprintf(stderr, ".\n"); #endif for (cpu = 0; cpu < common -> num_procs; cpu ++) { get_share(cpu, 1, share); //When the shared cpu are in different element of share & avail array, this may be a bug. for (i = 0; i < count ; i++){ share[i] &= common->avail[i]; if (popcount(share[i]) > 1) { #ifdef DEBUG fprintf(stderr, "Detected Hyper Threading on CPU %4x; disabled CPU %04lx.\n", cpu, share[i] & ~(CPUMASK(cpu))); #endif common -> avail[i] &= ~((share[i] & ~ CPUMASK(cpu))); } } } }
static int adev_open_input_stream(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, struct audio_config *config, struct audio_stream_in **stream_in) { struct audio_device *adev = (struct audio_device *)dev; struct stream_in *in; int ret, buffer_size, frame_size; int channel_count = popcount(config->channel_mask); ALOGV("%s: enter", __func__); *stream_in = NULL; if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) return -EINVAL; in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); if (!in) return -ENOMEM; in->stream.common.get_sample_rate = in_get_sample_rate; in->stream.common.set_sample_rate = in_set_sample_rate; in->stream.common.get_buffer_size = in_get_buffer_size; in->stream.common.get_channels = in_get_channels; in->stream.common.get_format = in_get_format; in->stream.common.standby = in_standby; in->stream.common.set_parameters = in_set_parameters; in->stream.common.get_parameters = in_get_parameters; in->stream.read = in_read; in->stream.get_input_frames_lost = in_get_input_frames_lost; in->device = devices; in->source = AUDIO_SOURCE_DEFAULT; in->dev = adev; in->standby = true; in->channel_mask = config->channel_mask; /* Update config params with the requested sample rate and channels */ in->pcm_config = pcm_config_audio_capture; in->pcm_config.channels = channel_count; in->pcm_config.rate = config->sample_rate; frame_size = audio_stream_frame_size((struct audio_stream *)in); buffer_size = get_input_buffer_size(config->sample_rate, config->format, channel_count); in->pcm_config.period_size = buffer_size / frame_size; *stream_in = &in->stream; ALOGV("%s: exit", __func__); return 0; }
void BitSequenceRRR::build(const uint * bitseq, size_t len, uint sample_rate) { ones = 0; this->length = len; if(E==NULL) E = new table_offset(BLOCK_SIZE); E->use(); // Table C C_len = len/BLOCK_SIZE + (len%BLOCK_SIZE!=0); C_field_bits = bits(BLOCK_SIZE); C = new uint[uint_len(C_len,C_field_bits)]; for(uint i=0; i<uint_len(C_len,C_field_bits); i++) C[i] = 0; O_bits_len = 0; for(uint i=0; i<C_len; i++) { uint value = popcount(get_var_field(bitseq,i*BLOCK_SIZE,min((uint)len-1,(i+1)*BLOCK_SIZE-1))); assert(value<=BLOCK_SIZE); set_field(C,C_field_bits,i,value); ones += value; O_bits_len += E->get_log2binomial(BLOCK_SIZE,value); } // Table O O_len = uint_len(1,O_bits_len); O = new uint[O_len]; for(uint i=0; i<O_len; i++) O[i] = 0; uint O_pos = 0; for(uint i=0; i<C_len; i++) { uint value = (ushort)get_var_field(bitseq,i*BLOCK_SIZE,min((uint)len-1,(i+1)*BLOCK_SIZE-1)); set_var_field(O,O_pos,O_pos+E->get_log2binomial(BLOCK_SIZE,popcount(value))-1,E->compute_offset((ushort)value)); O_pos += E->get_log2binomial(BLOCK_SIZE,popcount(value)); } C_sampling = NULL; this->O_pos = NULL; create_sampling(sample_rate); }
ssize_t AudioStreamOutSink::negotiate(const NBAIO_Format offers[], size_t numOffers, NBAIO_Format counterOffers[], size_t& numCounterOffers) { if (mFormat == Format_Invalid) { mStreamBufferSizeBytes = mStream->common.get_buffer_size(&mStream->common); audio_format_t streamFormat = mStream->common.get_format(&mStream->common); if (streamFormat == AUDIO_FORMAT_PCM_16_BIT) { uint32_t sampleRate = mStream->common.get_sample_rate(&mStream->common); audio_channel_mask_t channelMask = (audio_channel_mask_t) mStream->common.get_channels(&mStream->common); mFormat = Format_from_SR_C(sampleRate, popcount(channelMask)); mBitShift = Format_frameBitShift(mFormat); } } return NBAIO_Sink::negotiate(offers, numOffers, counterOffers, numCounterOffers); }
int main(int argc, char** argv) { char data[] = "Hello World! Hello POPCOUNT!"; int len = strlen(data); if (argc >= 2) { len = atoi(argv[1]); } printf("len=%d\n", len); printf("popcount()=%d\n", popcount(data, len)); printf("popcount_sse4()=%d\n", popcount_sse4(data, len)); return 0; }
uint64_t BitArray::select(bit_t bit, uint64_t idx) const { uint64_t tidx = binarySearch(bit, idx, 0); uint64_t residue = std::min(rank_table_blocks * block_size * tidx, length); uint64_t c_rank = bit ? rank_table[tidx] : residue - rank_table[tidx]; for(uint64_t t=0;t<rank_table_blocks;++t){ uint64_t count = popcount(bit_blocks[tidx * rank_table_blocks + t]); count = bit ? count : (std::min(block_size+0, length - (tidx * rank_table_blocks + t) * block_size) - count); if(idx <= c_rank + count){ return selectInBlock(bit, idx, c_rank, tidx * rank_table_blocks + t); } else { c_rank += count; } } }
/* * Do the bit sets union and write the result in set1 */ inline void bitArrayInPlaceUnion (BitArray * set1, BitArray * set2) { register WORD *a, *b; register const unsigned short size = set1->length; register SIZET i; register int count = 0; // assert( set1 ); // assert( set2 ); a = set1->data; b = set2->data; for (i = 0; i < size; i++, a++, b++){ *a |= *b; count += popcount(*a);//__builtin_popcountll(*a); } set1->nelements = count; }
FMRadioSource::FMRadioSource() : mInitCheck(NO_INIT), mStarted(false), mSessionId(AudioSystem::newAudioSessionId()) { // get FM Radio RX input audio_in_acoustics_t flags = (audio_in_acoustics_t) (AUDIO_IN_ACOUSTICS_AGC_DISABLE | AUDIO_IN_ACOUSTICS_NS_DISABLE | AUDIO_IN_ACOUSTICS_TX_DISABLE ); audio_io_handle_t input = AudioSystem::getInput(AUDIO_SOURCE_FM_RADIO_RX, kSampleRate, kAudioFormat, kChannelMask, (audio_in_acoustics_t)flags, mSessionId); if (input == 0) { ALOGE("Could not get audio input for FM Radio source"); mInitCheck = UNKNOWN_ERROR; return; } // get frame count int frameCount = 0; status_t status = AudioRecord::getMinFrameCount(&frameCount, kSampleRate, kAudioFormat, popcount(kChannelMask)); if (status != NO_ERROR) { mInitCheck = status; return; } // create the IAudioRecord status = openRecord(frameCount, input); if (status != NO_ERROR) { mInitCheck = status; return; } AudioSystem::acquireAudioSessionId(mSessionId); mInitCheck = OK; return; }
// Ignores target and immortal int kill_group(state *s) { stones_t chain, p; stones_t opponent = s->opponent; for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j += 2) { p = (1ULL | (1ULL << V_SHIFT)) << (i + j * V_SHIFT); chain = flood(p, opponent); opponent ^= chain; stones_t libs = liberties(chain, s->playing_area & ~s->player); if (popcount(libs) == 1) { int prisoners; make_move(s, libs, &prisoners); return 1; } } } return 0; }
void SuccinctVector::indexForRank() { delete this->rank_index; this->rank_index = 0; WriteBuffer buffer(this->number_of_blocks + 1, this->integer_bits); const usint* data = this->array; buffer.writeItem(0); usint bitcount = 0; for(usint block = 0; block < this->number_of_blocks; block++) { for(usint word = 0; word < this->block_size; word++, ++data) { bitcount += popcount(*data); } buffer.writeItem(bitcount); } this->items = bitcount; this->rank_index = buffer.getReadBuffer(); }
static int solve_BLX_R4_SP(const unsigned char *p, uint32_t size, va_list ap, target_addr_t addr, void *user) { static int min_reg = 8 + 1; const unsigned char *pp[1]; int rv = is_BLX_R4_SP(p, size, ap, addr, pp); if (rv && user) { assert(rv & 1); if (rv < 0) { int reg = popcount(*pp[0]); if (min_reg <= reg) { return rv; } min_reg = reg; } ((const void **)user)[0] = pp[0]; ((const void **)user)[1] = (char *)(uintptr_t)addr + (rv & 1); } return rv; }
size_t memcpy_by_index_array_initialization(int8_t *idxary, size_t idxcount, uint32_t dst_mask, uint32_t src_mask) { size_t n = 0; int srcidx = 0; uint32_t bit, ormask = src_mask | dst_mask; while (ormask && n < idxcount) { bit = ormask & -ormask; /* get lowest bit */ ormask ^= bit; /* remove lowest bit */ if (src_mask & dst_mask & bit) { /* matching channel */ idxary[n++] = srcidx++; } else if (src_mask & bit) { /* source channel only */ ++srcidx; } else { /* destination channel only */ idxary[n++] = -1; } } return n + popcount(ormask & dst_mask); }
// static status_t AudioRecord::getMinFrameCount( size_t* frameCount, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask) { if (frameCount == NULL) { return BAD_VALUE; } // default to 0 in case of error *frameCount = 0; size_t size = 0; status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size); if (status != NO_ERROR) { ALOGE("AudioSystem could not query the input buffer size; status %d", status); return NO_INIT; } if (size == 0) { ALOGE("Unsupported configuration: sampleRate %u, format %d, channelMask %#x", sampleRate, format, channelMask); return BAD_VALUE; } // We double the size of input buffer for ping pong use of record buffer. size <<= 1; uint32_t channelCount = popcount(channelMask); #ifdef QCOM_HARDWARE if (audio_is_linear_pcm(format)) #endif size /= channelCount * audio_bytes_per_sample(format); #ifdef QCOM_HARDWARE else size /= sizeof(uint8_t); #endif *frameCount = size; return NO_ERROR; }
static u32_t get_seq(void) { u32_t seq_map, seq = 0; int err, i; for (i = 0; i < NRF_FICR->CODEPAGESIZE / sizeof(seq_map); i++) { err = flash_read(nvm, SEQ_PAGE + (i * sizeof(seq_map)), &seq_map, sizeof(seq_map)); if (err) { printk("flash_read err %d\n", err); return seq; } printk("seq_map 0x%08x\n", seq_map); if (seq_map) { seq = ((i * 32) + (32 - popcount(seq_map))) * SEQ_PER_BIT; if (!seq) { return 0; } break; } } seq += SEQ_PER_BIT; if (seq >= SEQ_MAX) { seq = 0; } if (seq) { seq_map >>= 1; flash_write_protection_set(nvm, false); err = flash_write(nvm, SEQ_PAGE + (i * sizeof(seq_map)), &seq_map, sizeof(seq_map)); flash_write_protection_set(nvm, true); if (err) { printk("flash_write err %d\n", err); } } else {
size_t memcpy_by_index_array_initialization_src_index(int8_t *idxary, size_t idxcount, uint32_t dst_mask, uint32_t src_mask) { size_t dst_count = popcount(dst_mask); if (idxcount == 0) { return dst_count; } if (dst_count > idxcount) { dst_count = idxcount; } size_t src_idx, dst_idx; for (src_idx = 0, dst_idx = 0; dst_idx < dst_count; ++dst_idx) { if (src_mask & 1) { idxary[dst_idx] = src_idx++; } else { idxary[dst_idx] = -1; } src_mask >>= 1; } return dst_idx; }
static uint64_t popcnt_harley_seal(const __m512i* data, const uint64_t size) { __m256i total = _mm256_setzero_si256(); __m512i ones = _mm512_setzero_si512(); __m512i twos = _mm512_setzero_si512(); __m512i fours = _mm512_setzero_si512(); __m512i eights = _mm512_setzero_si512(); __m512i sixteens = _mm512_setzero_si512(); __m512i twosA, twosB, foursA, foursB, eightsA, eightsB; const uint64_t limit = size - size % 16; uint64_t i = 0; for(; i < limit; i += 16) { CSA(&twosA, &ones, ones, data[i+0], data[i+1]); CSA(&twosB, &ones, ones, data[i+2], data[i+3]); CSA(&foursA, &twos, twos, twosA, twosB); CSA(&twosA, &ones, ones, data[i+4], data[i+5]); CSA(&twosB, &ones, ones, data[i+6], data[i+7]); CSA(&foursB, &twos, twos, twosA, twosB); CSA(&eightsA,&fours, fours, foursA, foursB); CSA(&twosA, &ones, ones, data[i+8], data[i+9]); CSA(&twosB, &ones, ones, data[i+10], data[i+11]); CSA(&foursA, &twos, twos, twosA, twosB); CSA(&twosA, &ones, ones, data[i+12], data[i+13]); CSA(&twosB, &ones, ones, data[i+14], data[i+15]); CSA(&foursB, &twos, twos, twosA, twosB); CSA(&eightsB, &fours, fours, foursA, foursB); CSA(&sixteens, &eights, eights, eightsA, eightsB); total = _mm256_add_epi64(total, popcount(sixteens)); } total = _mm256_slli_epi64(total, 4); // * 16 total = _mm256_add_epi64(total, _mm256_slli_epi64(popcount(eights), 3)); // += 8 * ... total = _mm256_add_epi64(total, _mm256_slli_epi64(popcount(fours), 2)); // += 4 * ... total = _mm256_add_epi64(total, _mm256_slli_epi64(popcount(twos), 1)); // += 2 * ... total = _mm256_add_epi64(total, popcount(ones)); for(; i < size; i++) { total = _mm256_add_epi64(total, popcount(data[i])); } return avx2_sum_epu64(total); }
static bool most_constrained_point(sudoku *s, point *p, u8 *a) { register u8 x, y, c, i, min = 0xFF; register u16 m, mask; for (y = 0; y < 9; y++) { if (s->row[y] == COMPLETE) continue; for (x = 0; x < 9; x++) { if (s->m[y][x]) continue; m = (s->row[y] | s->col[x] | s->sec[y/3][x/3]) ^ COMPLETE; if (m == 0) return false; if ((c = popcount(m)) < min) { p->x = x; p->y = y; mask = m; min = c; } } } if (min == 0xFF) return false; for (i = 1; i < 10; i++) if (mask & (1<<i)) *a++ = i; *a = 0; return true; }
static block_t *GetOutBuffer( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; if( !p_sys->b_date_set || p_dec->fmt_out.audio.i_rate != p_sys->dts.i_rate ) { msg_Dbg( p_dec, "DTS samplerate:%d bitrate:%d", p_sys->dts.i_rate, p_sys->dts.i_bitrate ); date_Init( &p_sys->end_date, p_sys->dts.i_rate, 1 ); date_Set( &p_sys->end_date, p_sys->i_pts ); p_sys->b_date_set = true; } p_dec->fmt_out.audio.i_rate = p_sys->dts.i_rate; if( p_dec->fmt_out.audio.i_bytes_per_frame < p_sys->dts.i_frame_size ) p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->dts.i_frame_size; p_dec->fmt_out.audio.i_frame_length = p_sys->dts.i_frame_length; p_dec->fmt_out.audio.i_original_channels = p_sys->dts.i_original_channels; p_dec->fmt_out.audio.i_physical_channels = p_sys->dts.i_original_channels & AOUT_CHAN_PHYSMASK; p_dec->fmt_out.audio.i_channels = popcount( p_dec->fmt_out.audio.i_physical_channels ); p_dec->fmt_out.i_bitrate = p_sys->dts.i_bitrate; block_t *p_block = block_Alloc( p_sys->i_input_size ); if( p_block == NULL ) return NULL; p_block->i_nb_samples = p_sys->dts.i_frame_length; p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date ); p_block->i_length = date_Increment( &p_sys->end_date, p_block->i_nb_samples ) - p_block->i_pts; return p_block; }
enum protocol_ecode check_welcome(const struct peer *peer, const struct protocol_pkt_welcome *w, const struct protocol_block_header **block_hdr, size_t *block_len) { size_t len = le32_to_cpu(w->len); if (len < sizeof(*w)) return PROTOCOL_ECODE_INVALID_LEN; if (w->type != cpu_to_le32(PROTOCOL_PKT_WELCOME)) return PROTOCOL_ECODE_UNKNOWN_COMMAND; if (w->version != cpu_to_le32(current_version())) return PROTOCOL_ECODE_HIGH_VERSION; /* This is too lenient, but future-proof. */ if (popcount(w->interests, 65536) < 2) return PROTOCOL_ECODE_NO_INTEREST; len -= sizeof(*w); *block_hdr = (const struct protocol_block_header *)(w + 1); *block_len = len; return PROTOCOL_ECODE_NONE; }
status_t Visualizer::setCaptureSize(uint32_t size) { if (size > VISUALIZER_CAPTURE_SIZE_MAX || size < VISUALIZER_CAPTURE_SIZE_MIN || popcount(size) != 1) { return BAD_VALUE; } Mutex::Autolock _l(mCaptureLock); if (mEnabled) { return INVALID_OPERATION; } union { uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; effect_param_t bufp; }; effect_param_t *p = &bufp; p->psize = sizeof(uint32_t); p->vsize = sizeof(uint32_t); int32_t const vpcs = VISUALIZER_PARAM_CAPTURE_SIZE; memcpy(&p->data, &vpcs, sizeof(vpcs)); memcpy(&p->data+sizeof(int32_t), &size, sizeof(size)); status_t status = setParameter(p); ALOGV("setCaptureSize size %d status %d p->status %d", size, status, p->status); if (status == NO_ERROR) { status = p->status; if (status == NO_ERROR) { mCaptureSize = size; } } return status; }
size_t BitSequenceRRR::rank1(size_t i) const { if(i+1==0) return 0; if((uint)(i+1)==0) return 0; // patch for 32-64 bits bad coding, to be removed in the future uint nearest_sampled_value = i/BLOCK_SIZE/sample_rate; uint sum = get_field(C_sampling,C_sampling_field_bits,nearest_sampled_value); uint pos_O = get_field(O_pos,O_pos_field_bits,nearest_sampled_value); uint pos = i/BLOCK_SIZE; uint k=nearest_sampled_value*sample_rate; if(k%2==1 && k<pos) { uint aux = get_field(C,C_field_bits,k); sum += aux; pos_O += E->get_log2binomial(BLOCK_SIZE,aux); k++; } unsigned char * a = (unsigned char *)C; size_t mask = 0x0F; a += k/2; while(k<(uint)max(0,(int)pos-1)) { assert(((*a)&mask)==get_field(C,C_field_bits,k)); assert((*a)/16==get_field(C,C_field_bits,k+1)); sum += ((*a)&mask)+(*a)/16; pos_O += E->get_log2binomial(BLOCK_SIZE,((*a)&mask))+E->get_log2binomial(BLOCK_SIZE,((*a)/16)); a++; k+=2; } if(k<pos) { size_t aux = get_field(C,C_field_bits,k); sum += aux; pos_O += E->get_log2binomial(BLOCK_SIZE,aux); k++; } size_t c = get_field(C,C_field_bits,pos); sum += popcount(((2<<(i%BLOCK_SIZE))-1) & E->short_bitmap(c,get_var_field(O,pos_O,pos_O+E->get_log2binomial(BLOCK_SIZE,c)-1))); return sum; }
// must be called with mLock held status_t AudioTrack::createTrack_l( int streamType, uint32_t sampleRate, uint32_t format, uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, audio_io_handle_t output, bool enforceFrameCount) { status_t status; const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); if (audioFlinger == 0) { LOGE("Could not get audioflinger"); return NO_INIT; } int afSampleRate; if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { return NO_INIT; } int afFrameCount; if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { return NO_INIT; } uint32_t afLatency; if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { return NO_INIT; } mNotificationFramesAct = mNotificationFramesReq; if (!audio_is_linear_pcm(format)) { if (sharedBuffer != 0) { frameCount = sharedBuffer->size(); } } else { // Ensure that buffer depth covers at least audio hardware latency uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); if (minBufCount < 2) minBufCount = 2; int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate; if (sharedBuffer == 0) { if (frameCount == 0) { frameCount = minFrameCount; } if (mNotificationFramesAct == 0) { mNotificationFramesAct = frameCount/2; } // Make sure that application is notified with sufficient margin // before underrun if (mNotificationFramesAct > (uint32_t)frameCount/2) { mNotificationFramesAct = frameCount/2; } if (frameCount < minFrameCount) { LOGW_IF(enforceFrameCount, "Minimum buffer size corrected from %d to %d", frameCount, minFrameCount); frameCount = minFrameCount; } } else { // Ensure that buffer alignment matches channelcount int channelCount = popcount(channelMask); if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) { LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount); return BAD_VALUE; } frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t); } } sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), streamType, sampleRate, format, channelMask, frameCount, ((uint16_t)flags) << 16, sharedBuffer, output, &mSessionId, &status); if (track == 0) { LOGE("AudioFlinger could not create track, status: %d", status); return status; } sp<IMemory> cblk = track->getCblk(); if (cblk == 0) { LOGE("Could not get control block"); return NO_INIT; } mAudioTrack.clear(); mAudioTrack = track; mCblkMemory.clear(); mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags); if (sharedBuffer == 0) { mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); } else { mCblk->buffers = sharedBuffer->pointer(); // Force buffer full condition as data is already present in shared memory mCblk->stepUser(mCblk->frameCount); } mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000); mCblk->sendLevel = uint16_t(mSendLevel * 0x1000); mAudioTrack->attachAuxEffect(mAuxEffectId); mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; mCblk->waitTimeMs = 0; mRemainingFrames = mNotificationFramesAct; mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate; return NO_ERROR; }