blob: 93a4e8a137519c46f12970ab890c6f489b1a0a52 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <assert.h>
#include <os/util.h>
#include <stream/stream.h>
#include <i2s/i2s.h>
#include <i2s/i2s_stream.h>
OSTREAM_DEF(i2s_out_stream);
static int
i2s_out_stream_pump_from(struct out_stream *ostream, struct in_stream *istream, uint32_t count)
{
struct i2s_out_stream *i2s_str = CONTAINER_OF(ostream, struct i2s_out_stream, ostream);
struct i2s_sample_buffer *buffer = i2s_str->buffer;
struct i2s *i2s = i2s_str->i2s;
int written = 0;
uint32_t available = istream_available(istream);
uint32_t sample_count;
if (available < count) {
count = available;
}
sample_count = count / i2s->sample_size_in_bytes;
while (sample_count) {
if (buffer == NULL) {
buffer = i2s_buffer_get(i2s, 0);
if (buffer == NULL) {
break;
}
buffer->sample_count = 0;
}
uint32_t space = buffer->capacity - buffer->sample_count;
size_t copied = min(space, sample_count);
if (copied) {
uint8_t *buf = buffer->sample_data;
istream_read(istream, buf + buffer->sample_count * i2s->sample_size_in_bytes,
copied * i2s->sample_size_in_bytes);
buffer->sample_count += copied;
written += copied;
sample_count -= copied;
}
if (buffer->sample_count >= buffer->capacity) {
i2s_buffer_put(i2s, buffer);
buffer = NULL;
}
}
i2s_str->buffer = buffer;
return written * i2s_str->i2s->sample_size_in_bytes;
}
static int
i2s_out_stream_write(struct out_stream *ostream, const uint8_t *buf, uint32_t count)
{
struct mem_in_stream mstr;
mem_istream_init(&mstr, buf, count);
return i2s_out_stream_pump_from(ostream, (struct in_stream *)&mstr, count);
}
static int
i2s_out_stream_flush(struct out_stream *ostream)
{
struct i2s_out_stream *str = CONTAINER_OF(ostream, struct i2s_out_stream, ostream);
struct i2s *i2s = str->i2s;
struct i2s_sample_buffer *buffer = str->buffer;
str->buffer = NULL;
if (buffer) {
i2s_buffer_put(i2s, buffer);
}
return 0;
}