1 // SPDX-License-Identifier: GPL-2.0
3 // frame-cache.c - maintainer of cache for data frame.
5 // Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
7 // Licensed under the terms of the GNU General Public License, version 2.
9 #include "frame-cache.h"
11 static void align_frames_in_i(struct frame_cache *cache,
12 unsigned int consumed_count)
14 char *buf = cache->buf;
18 cache->remained_count -= consumed_count;
20 offset = cache->bytes_per_sample * cache->samples_per_frame *
22 size = cache->bytes_per_sample * cache->samples_per_frame *
23 cache->remained_count;
24 memmove(buf, buf + offset, size);
26 cache->buf_ptr = buf + size;
29 static void align_frames_in_n(struct frame_cache *cache,
30 unsigned int consumed_count)
32 char **bufs = cache->buf;
33 char **buf_ptrs = cache->buf_ptr;
38 cache->remained_count -= consumed_count;
40 for (i = 0; i < cache->samples_per_frame; ++i) {
41 offset = cache->bytes_per_sample * consumed_count;
42 size = cache->bytes_per_sample * cache->remained_count;
43 memmove(bufs[i], bufs[i] + offset, size);
44 buf_ptrs[i] = bufs[i] + size;
48 int frame_cache_init(struct frame_cache *cache, snd_pcm_access_t access,
49 unsigned int bytes_per_sample,
50 unsigned int samples_per_frame,
51 unsigned int frames_per_cache)
53 if (access == SND_PCM_ACCESS_RW_INTERLEAVED)
54 cache->align_frames = align_frames_in_i;
55 else if (access == SND_PCM_ACCESS_RW_NONINTERLEAVED)
56 cache->align_frames = align_frames_in_n;
59 cache->access = access;
61 if (access == SND_PCM_ACCESS_RW_INTERLEAVED) {
64 buf = calloc(frames_per_cache,
65 bytes_per_sample * samples_per_frame);
75 bufs = calloc(samples_per_frame, sizeof(*bufs));
78 buf_ptrs = calloc(samples_per_frame, sizeof(*buf_ptrs));
81 for (i = 0; i < samples_per_frame; ++i) {
82 bufs[i] = calloc(frames_per_cache, bytes_per_sample);
85 buf_ptrs[i] = bufs[i];
88 cache->buf_ptr = buf_ptrs;
91 cache->remained_count = 0;
92 cache->bytes_per_sample = bytes_per_sample;
93 cache->samples_per_frame = samples_per_frame;
94 cache->frames_per_cache = frames_per_cache;
99 void frame_cache_destroy(struct frame_cache *cache)
101 if (cache->access == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
103 for (i = 0; i < cache->samples_per_frame; ++i) {
104 char **bufs = cache->buf;
107 free(cache->buf_ptr);
110 memset(cache, 0, sizeof(*cache));