]> code.delx.au - pulseaudio/blobdiff - src/polypcore/core-scache.c
* split pa_cstrerror() into its own file polypcore/core-error.[ch]
[pulseaudio] / src / polypcore / core-scache.c
index 0d926abafa8c00b78d8c9d9257e0bcebfbc9c5d0..b44a7e198018fee7d5c89a1f5754742e719d67ac 100644 (file)
 #include <windows.h>
 #endif
 
-#include "core-scache.h"
-#include "sink-input.h"
 #include <polyp/mainloop.h>
-#include "sample-util.h"
-#include "play-memchunk.h"
-#include "xmalloc.h"
-#include "core-subscribe.h"
-#include "namereg.h"
-#include "sound-file.h"
-#include "util.h"
-#include "log.h"
 #include <polyp/channelmap.h>
+#include <polyp/timeval.h>
+#include <polyp/util.h>
 #include <polyp/volume.h>
+#include <polyp/xmalloc.h>
+
+#include <polypcore/sink-input.h>
+#include <polypcore/sample-util.h>
+#include <polypcore/play-memchunk.h>
+#include <polypcore/core-subscribe.h>
+#include <polypcore/namereg.h>
+#include <polypcore/sound-file.h>
+#include <polypcore/core-util.h>
+#include <polypcore/log.h>
+#include <polypcore/core-error.h>
+
+#include "core-scache.h"
 
 #define UNLOAD_POLL_TIME 2
 
@@ -114,7 +119,6 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_NEW, e->index);
     }
 
-    pa_cvolume_reset(&e->volume, PA_CHANNELS_MAX);
     e->last_used_time = 0;
     e->memchunk.memblock = NULL;
     e->memchunk.index = e->memchunk.length = 0;
@@ -122,7 +126,9 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
     e->lazy = 0;
     e->last_used_time = 0;
 
-    memset(&e->sample_spec, 0, sizeof(pa_sample_spec));
+    memset(&e->sample_spec, 0, sizeof(e->sample_spec));
+    pa_channel_map_init(&e->channel_map);
+    pa_cvolume_reset(&e->volume, PA_CHANNELS_MAX);
 
     return e;
 }
@@ -131,12 +137,16 @@ int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, c
     pa_scache_entry *e;
     assert(c && name);
 
+    if (chunk && chunk->length > PA_SCACHE_ENTRY_SIZE_MAX)
+        return -1;
+
     if (!(e = scache_add_item(c, name)))
         return -1;
 
     if (ss) {
         e->sample_spec = *ss;
-        pa_channel_map_init_auto(&e->channel_map, ss->channels);
+        pa_channel_map_init_auto(&e->channel_map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
+        e->volume.channels = e->sample_spec.channels;
     }
 
     if (map)
@@ -155,6 +165,7 @@ int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, c
 
 int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx) {
     pa_sample_spec ss;
+    pa_channel_map map;
     pa_memchunk chunk;
     int r;
 
@@ -165,10 +176,10 @@ int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint3
         filename = buf;
 #endif
 
-    if (pa_sound_file_load(filename, &ss, &chunk, c->memblock_stat) < 0)
+    if (pa_sound_file_load(filename, &ss, &map, &chunk, c->memblock_stat) < 0)
         return -1;
         
-    r = pa_scache_add_item(c, name, &ss, NULL, &chunk, idx);
+    r = pa_scache_add_item(c, name, &ss, &map, &chunk, idx);
     pa_memblock_unref(chunk.memblock);
 
     return r;
@@ -237,33 +248,42 @@ void pa_scache_free(pa_core *c) {
         c->mainloop->time_free(c->scache_auto_unload_event);
 }
 
-int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, const pa_cvolume *volume) {
+int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t volume) {
     pa_scache_entry *e;
     char *t;
     pa_cvolume r;
-    assert(c && name && sink);
+    
+    assert(c);
+    assert(name);
+    assert(sink);
 
     if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1)))
         return -1;
 
     if (e->lazy && !e->memchunk.memblock) {
-        if (pa_sound_file_load(e->filename, &e->sample_spec, &e->memchunk, c->memblock_stat) < 0)
+        if (pa_sound_file_load(e->filename, &e->sample_spec, &e->channel_map, &e->memchunk, c->memblock_stat) < 0)
             return -1;
 
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
+
+        if (e->volume.channels > e->sample_spec.channels)
+            e->volume.channels = e->sample_spec.channels;
     }
     
     if (!e->memchunk.memblock)
         return -1;
 
     t = pa_sprintf_malloc("sample:%s", name);
-    
-    if (pa_play_memchunk(sink, t, &e->sample_spec, &e->channel_map, &e->memchunk, pa_sw_cvolume_multiply(&r, volume, &e->volume)) < 0) {
-        free(t);
+
+    pa_cvolume_set(&r, e->volume.channels, volume);
+    pa_sw_cvolume_multiply(&r, &r, &e->volume);
+
+    if (pa_play_memchunk(sink, t, &e->sample_spec, &e->channel_map, &e->memchunk, &r) < 0) {
+        pa_xfree(t);
         return -1;
     }
 
-    free(t);
+    pa_xfree(t);
 
     if (e->lazy)
         time(&e->last_used_time);
@@ -340,7 +360,7 @@ static void add_file(pa_core *c, const char *pathname) {
     e = pa_path_get_filename(pathname);
     
     if (stat(pathname, &st) < 0) {
-        pa_log(__FILE__": stat('%s') failed: %s\n", pathname, strerror(errno));
+        pa_log(__FILE__": stat('%s'): %s", pathname, pa_cstrerror(errno));
         return;
     }
 
@@ -362,7 +382,7 @@ int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) {
         /* If that fails, try to open it as shell glob */
 
         if (glob(pathname, GLOB_ERR|GLOB_NOSORT, NULL, &p) < 0) {
-            pa_log(__FILE__": Failed to open directory: %s\n", strerror(errno));
+            pa_log(__FILE__": failed to open directory '%s': %s", pathname, pa_cstrerror(errno));
             return -1;
         }