Changeset d988ef2 in mainline
- Timestamp:
- 2013-04-05T12:02:45Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1438e5
- Parents:
- 4b33db8e
- Location:
- uspace/srv/audio/hound
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/audio/hound/audio_data.c
r4b33db8e rd988ef2 34 34 */ 35 35 36 #include <macros.h> 36 37 #include <malloc.h> 37 38 #include "audio_data.h" 38 39 39 static void ref_inc(audio_data_t *adata) 40 audio_data_t *audio_data_create(const void *data, size_t size, 41 pcm_format_t format) 42 { 43 audio_data_t *adata = malloc(sizeof(audio_data_t)); 44 if (adata) { 45 adata->data = data; 46 adata->size = size; 47 adata->format = format; 48 atomic_set(&adata->refcount, 1); 49 } 50 return adata; 51 } 52 53 void audio_data_addref(audio_data_t *adata) 40 54 { 41 55 assert(adata); … … 44 58 } 45 59 46 static void ref_dec(audio_data_t *adata)60 void audio_data_unref(audio_data_t *adata) 47 61 { 48 62 assert(adata); … … 55 69 } 56 70 57 audio_data_t *audio_data_create(const void *data, size_t size,58 pcm_format_t format)59 {60 audio_data_t *adata = malloc(sizeof(audio_data_t));61 if (adata) {62 adata->data = data;63 adata->size = size;64 adata->format = format;65 atomic_set(&adata->refcount, 1);66 }67 return adata;68 }69 70 void audio_data_unref(audio_data_t *adata)71 {72 ref_dec(adata);73 }74 75 71 audio_data_link_t *audio_data_link_create(audio_data_t *adata) 76 72 { … … 78 74 audio_data_link_t *link = malloc(sizeof(audio_data_link_t)); 79 75 if (link) { 80 ref_inc(adata);76 audio_data_addref(adata); 81 77 link->adata = adata; 82 78 link->position = 0; … … 103 99 assert(link); 104 100 assert(!link_in_use(&link->link)); 105 ref_dec(link->adata);101 audio_data_unref(link->adata); 106 102 free(link); 107 103 } … … 111 107 assert(alink); 112 108 assert(alink->adata); 113 return pcm_format_size_to_frames(a link->adata->size - alink->position,109 return pcm_format_size_to_frames(audio_data_link_remain_size(alink), 114 110 &alink->adata->format); 111 } 112 113 /* Audio Pipe */ 114 115 116 void audio_pipe_init(audio_pipe_t *pipe) 117 { 118 assert(pipe); 119 list_initialize(&pipe->list); 120 fibril_mutex_initialize(&pipe->guard); 121 pipe->frames = 0; 122 pipe->bytes = 0; 123 } 124 125 126 127 void audio_pipe_fini(audio_pipe_t *pipe) 128 { 129 assert(pipe); 130 while (!list_empty(&pipe->list)) { 131 audio_data_t *adata = audio_pipe_pop(pipe); 132 audio_data_unref(adata); 133 } 134 } 135 136 int audio_pipe_push(audio_pipe_t *pipe, audio_data_t *data) 137 { 138 assert(pipe); 139 assert(data); 140 audio_data_link_t *alink = audio_data_link_create(data); 141 if (!alink) 142 return ENOMEM; 143 144 fibril_mutex_lock(&pipe->guard); 145 list_append(&alink->link, &pipe->list); 146 pipe->bytes += audio_data_link_remain_size(alink); 147 pipe->frames += audio_data_link_available_frames(alink); 148 fibril_mutex_unlock(&pipe->guard); 149 return EOK; 150 } 151 152 audio_data_t *audio_pipe_pop(audio_pipe_t *pipe) 153 { 154 assert(pipe); 155 fibril_mutex_lock(&pipe->guard); 156 audio_data_t *adata = NULL; 157 link_t *l = list_first(&pipe->list); 158 if (l) { 159 audio_data_link_t *alink = audio_data_link_list_instance(l); 160 list_remove(&alink->link); 161 adata = alink->adata; 162 audio_data_addref(adata); 163 audio_data_link_destroy(alink); 164 } 165 fibril_mutex_unlock(&pipe->guard); 166 return adata; 167 } 168 169 ssize_t audio_pipe_mix_data(audio_pipe_t *pipe, void *data, 170 size_t size, const pcm_format_t *f) 171 { 172 assert(pipe); 173 const size_t dst_frame_size = pcm_format_frame_size(f); 174 size_t needed_frames = size / dst_frame_size; 175 size_t copied_size = 0; 176 fibril_mutex_lock(&pipe->guard); 177 while (needed_frames > 0 && !list_empty(&pipe->list)) { 178 /* Get first audio chunk */ 179 link_t *l = list_first(&pipe->list); 180 audio_data_link_t *alink = audio_data_link_list_instance(l); 181 182 /* Get audio chunk metadata */ 183 const size_t src_frame_size = 184 pcm_format_frame_size(&alink->adata->format); 185 const size_t available_frames = 186 audio_data_link_available_frames(alink); 187 const size_t copy_frames = min(available_frames, needed_frames); 188 const size_t copy_size = copy_frames * dst_frame_size; 189 190 /* Copy audio data */ 191 pcm_format_convert_and_mix(data, copy_size, 192 audio_data_link_start(alink), 193 audio_data_link_remain_size(alink), 194 &alink->adata->format, f); 195 196 /* Update values */ 197 copied_size += copy_size; 198 needed_frames -= copy_frames; 199 data += copy_size; 200 alink->position += (copy_frames * src_frame_size); 201 if (audio_data_link_remain_size(alink) == 0) { 202 list_remove(&alink->link); 203 audio_data_link_destroy(alink); 204 } else { 205 assert(needed_frames == 0); 206 } 207 } 208 fibril_mutex_unlock(&pipe->guard); 209 return copied_size; 115 210 } 116 211 -
uspace/srv/audio/hound/audio_data.h
r4b33db8e rd988ef2 37 37 #define AUDIO_DATA_H_ 38 38 39 #include <pcm/format.h>40 39 #include <adt/list.h> 41 40 #include <atomic.h> 41 #include <errno.h> 42 #include <fibril_synch.h> 43 #include <pcm/format.h> 42 44 43 45 typedef struct { … … 54 56 } audio_data_link_t; 55 57 58 typedef struct { 59 list_t list; 60 size_t bytes; 61 size_t frames; 62 fibril_mutex_t guard; 63 } audio_pipe_t; 64 56 65 static inline audio_data_link_t * audio_data_link_list_instance(link_t *l) 57 66 { … … 61 70 audio_data_t * audio_data_create(const void *data, size_t size, 62 71 pcm_format_t format); 72 void audio_data_addref(audio_data_t *adata); 63 73 void audio_data_unref(audio_data_t *adata); 64 74 … … 83 93 return alink->adata->size - alink->position; 84 94 } 95 96 void audio_pipe_init(audio_pipe_t *pipe); 97 void audio_pipe_fini(audio_pipe_t *pipe); 98 99 int audio_pipe_push(audio_pipe_t *pipe, audio_data_t *data); 100 audio_data_t *audio_pipe_pop(audio_pipe_t *pipe); 101 102 ssize_t audio_pipe_mix_data(audio_pipe_t *pipe, void *buffer, size_t size, 103 const pcm_format_t *f); 104 105 static inline size_t audio_pipe_bytes(audio_pipe_t *pipe) 106 { 107 assert(pipe); 108 return pipe->bytes; 109 } 110 111 static inline size_t audio_pipe_frames(audio_pipe_t *pipe) 112 { 113 assert(pipe); 114 return pipe->frames; 115 } 116 117 static inline int audio_pipe_push_data(audio_pipe_t *pipe, 118 const void *data, size_t size, pcm_format_t f) 119 { 120 audio_data_t *adata = audio_data_create(data, size, f); 121 if (adata) { 122 const int ret = audio_pipe_push(pipe, adata); 123 audio_data_unref(adata); 124 return ret; 125 } 126 return ENOMEM; 127 } 128 129 85 130 #endif 86 131
Note:
See TracChangeset
for help on using the changeset viewer.