]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/sound-file.c
sample-util: move volume code to separate file
[pulseaudio] / src / pulsecore / sound-file.c
index 3183ede6093ac1af93925b47757b258bcf4d59fd..2d9b76ad6e4597deb836e78f3837c96f28b2efa0 100644 (file)
@@ -5,7 +5,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/core-scache.h>
+#include <pulsecore/sndfile-util.h>
 
 #include "sound-file.h"
 
 #include "sound-file.h"
-#include "core-scache.h"
 
 int pa_sound_file_load(
         pa_mempool *pool,
         const char *fname,
         pa_sample_spec *ss,
         pa_channel_map *map,
 
 int pa_sound_file_load(
         pa_mempool *pool,
         const char *fname,
         pa_sample_spec *ss,
         pa_channel_map *map,
-        pa_memchunk *chunk) {
+        pa_memchunk *chunk,
+        pa_proplist *p) {
 
     SNDFILE *sf = NULL;
 
     SNDFILE *sf = NULL;
-    SF_INFO sfinfo;
+    SF_INFO sfi;
     int ret = -1;
     size_t l;
     sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL;
     int ret = -1;
     size_t l;
     sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL;
@@ -59,7 +61,6 @@ int pa_sound_file_load(
     pa_assert(chunk);
 
     pa_memchunk_reset(chunk);
     pa_assert(chunk);
 
     pa_memchunk_reset(chunk);
-    memset(&sfinfo, 0, sizeof(sfinfo));
 
     if ((fd = open(fname, O_RDONLY
 #ifdef O_NOCTTY
 
     if ((fd = open(fname, O_RDONLY
 #ifdef O_NOCTTY
@@ -78,48 +79,29 @@ int pa_sound_file_load(
         pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded.");
 #endif
 
         pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded.");
 #endif
 
-    if (!(sf = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) {
+    pa_zero(sfi);
+    if (!(sf = sf_open_fd(fd, SFM_READ, &sfi, 1))) {
         pa_log("Failed to open file %s", fname);
         pa_log("Failed to open file %s", fname);
-        pa_close(fd);
         goto finish;
     }
 
         goto finish;
     }
 
-    switch (sfinfo.format & SF_FORMAT_SUBMASK) {
-        case SF_FORMAT_PCM_16:
-        case SF_FORMAT_PCM_U8:
-        case SF_FORMAT_PCM_S8:
-            ss->format = PA_SAMPLE_S16NE;
-            readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short;
-            break;
-
-        case SF_FORMAT_ULAW:
-            ss->format = PA_SAMPLE_ULAW;
-            break;
-
-        case SF_FORMAT_ALAW:
-            ss->format = PA_SAMPLE_ALAW;
-            break;
-
-        case SF_FORMAT_FLOAT:
-        case SF_FORMAT_DOUBLE:
-        default:
-            ss->format = PA_SAMPLE_FLOAT32NE;
-            readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float;
-            break;
-    }
-
-    ss->rate = sfinfo.samplerate;
-    ss->channels = sfinfo.channels;
+    fd = -1;
 
 
-    if (!pa_sample_spec_valid(ss)) {
-        pa_log("Unsupported sample format in file %s", fname);
+    if (pa_sndfile_read_sample_spec(sf, ss) < 0) {
+        pa_log("Failed to determine file sample format.");
         goto finish;
     }
 
         goto finish;
     }
 
-    if (map)
+    if ((map && pa_sndfile_read_channel_map(sf, map) < 0)) {
+        if (ss->channels > 2)
+            pa_log("Failed to determine file channel map, synthesizing one.");
         pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
         pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
+    }
 
 
-    if ((l = pa_frame_size(ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
+    if (p)
+        pa_sndfile_init_proplist(sf, p);
+
+    if ((l = pa_frame_size(ss) * (size_t) sfi.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
         pa_log("File too large");
         goto finish;
     }
         pa_log("File too large");
         goto finish;
     }
@@ -128,10 +110,12 @@ int pa_sound_file_load(
     chunk->index = 0;
     chunk->length = l;
 
     chunk->index = 0;
     chunk->length = l;
 
+    readf_function = pa_sndfile_readf_function(ss);
+
     ptr = pa_memblock_acquire(chunk->memblock);
 
     ptr = pa_memblock_acquire(chunk->memblock);
 
-    if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) ||
-        (!readf_function && sf_read_raw(sf, ptr, l) != (sf_count_t) l)) {
+    if ((readf_function && readf_function(sf, ptr, sfi.frames) != sfi.frames) ||
+        (!readf_function && sf_read_raw(sf, ptr, (sf_count_t) l) != (sf_count_t) l)) {
         pa_log("Premature file end");
         goto finish;
     }
         pa_log("Premature file end");
         goto finish;
     }
@@ -149,55 +133,35 @@ finish:
     if (ret != 0 && chunk->memblock)
         pa_memblock_unref(chunk->memblock);
 
     if (ret != 0 && chunk->memblock)
         pa_memblock_unref(chunk->memblock);
 
+    if (fd >= 0)
+        pa_close(fd);
+
     return ret;
 }
 
 int pa_sound_file_too_big_to_cache(const char *fname) {
 
     SNDFILE*sf = NULL;
     return ret;
 }
 
 int pa_sound_file_too_big_to_cache(const char *fname) {
 
     SNDFILE*sf = NULL;
-    SF_INFO sfinfo;
+    SF_INFO sfi;
     pa_sample_spec ss;
 
     pa_assert(fname);
 
     pa_sample_spec ss;
 
     pa_assert(fname);
 
-    if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) {
+    pa_zero(sfi);
+    if (!(sf = sf_open(fname, SFM_READ, &sfi))) {
         pa_log("Failed to open file %s", fname);
         return -1;
     }
 
         pa_log("Failed to open file %s", fname);
         return -1;
     }
 
-    sf_close(sf);
-
-    switch (sfinfo.format & SF_FORMAT_SUBMASK) {
-        case SF_FORMAT_PCM_16:
-        case SF_FORMAT_PCM_U8:
-        case SF_FORMAT_PCM_S8:
-            ss.format = PA_SAMPLE_S16NE;
-            break;
-
-        case SF_FORMAT_ULAW:
-            ss.format = PA_SAMPLE_ULAW;
-            break;
-
-        case SF_FORMAT_ALAW:
-            ss.format = PA_SAMPLE_ALAW;
-            break;
-
-        case SF_FORMAT_DOUBLE:
-        case SF_FORMAT_FLOAT:
-        default:
-            ss.format = PA_SAMPLE_FLOAT32NE;
-            break;
-    }
-
-    ss.rate = sfinfo.samplerate;
-    ss.channels = sfinfo.channels;
-
-    if (!pa_sample_spec_valid(&ss)) {
-        pa_log("Unsupported sample format in file %s", fname);
+    if (pa_sndfile_read_sample_spec(sf, &ss) < 0) {
+        pa_log("Failed to determine file sample format.");
+        sf_close(sf);
         return -1;
     }
 
         return -1;
     }
 
-    if ((pa_frame_size(&ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
+    sf_close(sf);
+
+    if ((pa_frame_size(&ss) * (size_t) sfi.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
         pa_log("File too large: %s", fname);
         return 1;
     }
         pa_log("File too large: %s", fname);
         return 1;
     }