void GradientScreenRectRenderer::render(void *args) { if(!program) { program = get_program(standard_color_program_loader); } GradientScreenRectParams* params = (GradientScreenRectParams*)args; GLfloat verts[] = { params->corners[0].x, params->corners[0].y, 0.0f, // bl params->corners[1].x, params->corners[1].y, 0.0f, // br params->corners[2].x, params->corners[2].y, 0.0f, // tr params->corners[2].x, params->corners[2].y, 0.0f, // tr params->corners[3].x, params->corners[3].y, 0.0f, // tl params->corners[0].x, params->corners[0].y, 0.0f // bl }; GLfloat colors[] = { params->colors[0].r, params->colors[0].g, params->colors[0].b, params->colors[0].a, params->colors[1].r, params->colors[1].g, params->colors[1].b, params->colors[1].a, params->colors[2].r, params->colors[2].g, params->colors[2].b, params->colors[2].a, params->colors[2].r, params->colors[2].g, params->colors[2].b, params->colors[2].a, params->colors[3].r, params->colors[3].g, params->colors[3].b, params->colors[3].a, params->colors[0].r, params->colors[0].g, params->colors[0].b, params->colors[0].a, }; GLfloat texs[] = { params->texture->u0, params->texture->v0, params->texture->u1, params->texture->v0, params->texture->u1, params->texture->v1, params->texture->u1, params->texture->v1, params->texture->u0, params->texture->v1, params->texture->u0, params->texture->v0 }; gl_check(program->use()); GLuint vert_buffer = next_buffer(); gl_check(glEnableVertexAttribArray(GLPARAM_VERTEX)); gl_check(glBindBuffer(GL_ARRAY_BUFFER, vert_buffer)); gl_check(glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_DYNAMIC_DRAW)); gl_check(glVertexAttribPointer(GLPARAM_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0)); GLuint tex_buffer = next_buffer(); gl_check(glEnableVertexAttribArray(GLPARAM_TEXCOORD0)); gl_check(glBindBuffer(GL_ARRAY_BUFFER, tex_buffer)); gl_check(glBufferData(GL_ARRAY_BUFFER, sizeof(texs), texs, GL_DYNAMIC_DRAW)); gl_check(glVertexAttribPointer(GLPARAM_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 0, 0)); GLuint color_buffer = next_buffer(); gl_check(glEnableVertexAttribArray(GLPARAM_OTHER0)); gl_check(glBindBuffer(GL_ARRAY_BUFFER, color_buffer)); gl_check(glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * 6, colors, GL_DYNAMIC_DRAW)); gl_check(glVertexAttribPointer(GLPARAM_OTHER0, 4, GL_FLOAT, GL_FALSE, 0, 0)); params->texture->texture->bind(); gl_check(glUniform1i(program->requireUniform(UNIFORM_TEX0), 0)); gl_check(glUniformMatrix4fv(program->requireUniform(UNIFORM_MVP), 1, GL_FALSE, GIGGLE->renderer->orthographic_projection.data)); gl_check(glDrawArrays(GL_TRIANGLES, 0, 6)); }
int write_from_buffer(int fd, struct list *list, int log) { int index = log ? 1 : 0; struct buffer *buffer = list->head; size_t pos = buffer->pos[index]; size_t size = buffer->size; ssize_t count = write(fd, buffer->data + pos, size - pos); if (count < 0) { if (EINTR == errno || EAGAIN == errno || EWOULDBLOCK == errno) { return 1; /* try again */ } emtpy_buffer(list, index); return 0; } /* buffer cleanup */ buffer->pos[index] = pos + count; list->head = next_buffer(buffer, index); if (NULL == list->head) list->tail = NULL; return 1; }
static void buffer_pool_buffer_cleanup(void *data) { buffer_pool_cleanup_t* c = data; buffer_pool_t* buffer_pool = c->buffer_pool; void* buffer = c->buffer; next_buffer(buffer) = buffer_pool->head; buffer_pool->head = buffer; }
void emtpy_buffer(struct list *list, int index) { struct buffer *buffer = list->head; /* consume all buffers */ while(buffer = next_buffer(buffer, index)) { buffer->pos[index] = buffer->size; } list->head = NULL; list->tail = NULL; }
static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){ UNUSED(sample_rate); UNUSED(context); #ifdef STORE_SBC_TO_WAV_FILE wav_writer_write_int16(num_samples*num_channels, data); frame_count++; #endif #ifdef HAVE_PORTAUDIO // store pcm samples in ring buffer btstack_ring_buffer_write(&ring_buffer, (uint8_t *)data, num_samples*num_channels*2); if (!audio_stream_started){ audio_stream_paused = 1; /* -- start stream -- */ PaError err = Pa_StartStream(stream); if (err != paNoError){ printf("Error starting the stream: \"%s\"\n", Pa_GetErrorText(err)); return; } audio_stream_started = 1; } #endif #ifdef HAVE_AUDIO_DMA // store in ring buffer uint8_t * write_data = start_of_buffer(write_buffer); uint16_t len = num_samples*num_channels*2; memcpy(write_data, data, len); audio_samples_len[write_buffer] = len; // add/drop audio frame to fix drift if (sbc_samples_fix > 0){ memcpy(write_data + len, write_data + len - 4, 4); audio_samples_len[write_buffer] += 4; } if (sbc_samples_fix < 0){ audio_samples_len[write_buffer] -= 4; } write_buffer = next_buffer(write_buffer); #endif }
buffer_pool_t* buffer_pool_create(vod_pool_t* pool, vod_log_t* log, size_t buffer_size, size_t count) { buffer_pool_t* buffer_pool; u_char* cur_buffer; void* head; if ((buffer_size & 0x0F) != 0) { vod_log_error(VOD_LOG_ERR, log, 0, "buffer_pool_create: invalid size %uz must be a multiple of 16", buffer_size); return NULL; } buffer_pool = vod_alloc(pool, sizeof(*buffer_pool)); if (buffer_pool == NULL) { vod_log_debug0(VOD_LOG_DEBUG_LEVEL, log, 0, "buffer_pool_create: vod_alloc failed (1)"); return NULL; } cur_buffer = vod_alloc(pool, buffer_size * count); if (cur_buffer == NULL) { vod_log_debug0(VOD_LOG_DEBUG_LEVEL, log, 0, "buffer_pool_create: vod_alloc failed (2)"); return NULL; } head = NULL; for (; count > 0; count--, cur_buffer += buffer_size) { next_buffer(cur_buffer) = head; head = cur_buffer; } buffer_pool->size = buffer_size; buffer_pool->head = head; return buffer_pool; }
void* buffer_pool_alloc(request_context_t* request_context, buffer_pool_t* buffer_pool, size_t* buffer_size) { buffer_pool_cleanup_t* buf_cln; vod_pool_cleanup_t* cln; void* result; if (buffer_pool == NULL) { return vod_alloc(request_context->pool, *buffer_size); } if (buffer_pool->head == NULL) { *buffer_size = buffer_pool->size; return vod_alloc(request_context->pool, *buffer_size); } cln = vod_pool_cleanup_add(request_context->pool, sizeof(buffer_pool_cleanup_t)); if (cln == NULL) { vod_log_debug0(VOD_LOG_DEBUG_LEVEL, request_context->log, 0, "buffer_pool_alloc: vod_pool_cleanup_add failed"); return NULL; } result = buffer_pool->head; buffer_pool->head = next_buffer(result); cln->handler = buffer_pool_buffer_cleanup; buf_cln = cln->data; buf_cln->buffer = result; buf_cln->buffer_pool = buffer_pool; *buffer_size = buffer_pool->size; return result; }
void hal_audio_dma_done(void){ if (audio_stream_paused){ hal_audio_dma_play((const uint8_t *) silent_buffer, DMA_AUDIO_FRAMES*4); return; } // next buffer int next_playback_buffer = next_buffer(playback_buffer); uint8_t * playback_data; if (next_playback_buffer == write_buffer){ // TODO: stop codec while playing silence when getting 'stream paused' // start playing silence audio_stream_paused = 1; hal_audio_dma_play((const uint8_t *) silent_buffer, DMA_AUDIO_FRAMES*4); printf("%6u - paused - bytes in buffer %u\n", (int) btstack_run_loop_get_time_ms(), btstack_ring_buffer_bytes_available(&ring_buffer)); return; } playback_buffer = next_playback_buffer; playback_data = start_of_buffer(playback_buffer); hal_audio_dma_play(playback_data, audio_samples_len[playback_buffer]); // btstack_run_loop_embedded_trigger(); }
/* Write given segment from buffer at address onto tape. */ int write_segment(unsigned segment_id, byte * address, int flushing) { TRACE_FUN(5, "write_segment"); int result = 0; int bytes_written = 0; TRACEi(5, "segment_id =", segment_id); if (ftape_state != writing) { if (ftape_state == reading) { TRACE(5, "calling ftape_abort_operation"); result = ftape_abort_operation(); if (result < 0) { TRACE(1, "ftape_abort_operation failed"); } } ftape_zap_read_buffers(); ftape_zap_write_buffers(); ftape_state = writing; } /* if all buffers full we'll have to wait... */ wait_segment(writing); if (buffer[tail].status == error) { /* setup for a retry */ buffer[tail].status = waiting; bytes_written = -EAGAIN; /* force retry */ if (buffer[tail].hard_error_map != 0) { TRACEx1(1, "warning: %d hard error(s) in written segment", count_ones(buffer[tail].hard_error_map)); TRACEx1(4, "hard_error_map = 0x%08lx", buffer[tail].hard_error_map); /* Implement hard write error recovery here */ } } else if (buffer[tail].status == done) { history.defects += count_ones(buffer[tail].hard_error_map); } else { TRACE(1, "wait for empty segment failed"); result = -EIO; } /* If just passed last segment on tape: wait for BOT or EOT mark. */ if (result >= 0 && runner_status == logical_eot) { int status; result = ftape_ready_wait(timeout.seek, &status); if (result < 0 || (status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) == 0) { TRACE(1, "eot/bot not reached"); } else { runner_status = end_of_tape; } } /* should runner stop ? */ if (result >= 0 && (runner_status == aborting || runner_status == buffer_underrun || runner_status == end_of_tape)) { if (runner_status != end_of_tape) { result = ftape_dumb_stop(); } if (result >= 0) { if (runner_status == aborting) { if (buffer[head].status == writing) { buffer[head].status = done; /* ????? */ } } runner_status = idle; /* aborted ? */ } } /* Don't start tape if runner idle and segment empty. */ if (result >= 0 && !(runner_status == idle && get_bad_sector_entry(segment_id) == EMPTY_SEGMENT)) { if (buffer[tail].status == done) { /* now at least one buffer is empty, fill it with our data. * skip bad sectors and generate ecc. * copy_and_gen_ecc return nr of bytes written, * range 0..29 Kb inclusive ! */ result = copy_and_gen_ecc(buffer[tail].address, address, get_bad_sector_entry(segment_id)); if (result >= 0) { bytes_written = result; buffer[tail].segment_id = segment_id; buffer[tail].status = waiting; next_buffer(&tail); } } /* Start tape only if all buffers full or flush mode. * This will give higher probability of streaming. */ if (result >= 0 && runner_status != running && ((head == tail && buffer[tail].status == waiting) || flushing)) { result = start_writing(WRITE_MULTI); } } TRACE_EXIT; return (result < 0) ? result : bytes_written; }