Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read loop data embedded in WAV file #21

Open
jwm-art-net opened this issue Apr 15, 2014 · 1 comment
Open

Read loop data embedded in WAV file #21

jwm-art-net opened this issue Apr 15, 2014 · 1 comment
Assignees
Labels

Comments

@jwm-art-net
Copy link

Read loop data embedded in WAV file when loading a sample into a patch.

  • Loop data should only be read when WAV is loaded via UI events.
  • Loop data specified in a patch always overrides loop data specified in a WAV.
@jwm-art-net jwm-art-net self-assigned this Apr 15, 2014
@jwm-art-net
Copy link
Author

Potential patch, submitted by Jean-Pierre Haenlin.

diff -ruB Petri-Foo-0.1.87/gui/sample-selector.c Petri-Foo-jph/gui/sample-selector.c
--- Petri-Foo-0.1.87/gui/sample-selector.c  2012-08-07 17:10:47.000000000 +0200
+++ Petri-Foo-jph/gui/sample-selector.c 2014-04-22 21:33:35.568480751 +0200
@@ -117,9 +117,10 @@
         int samplerate = gtk_spin_button_get_value_as_int(
                                     GTK_SPIN_BUTTON(rb->samplerate));

-        if (patch_sample_load(patch, name,    samplerate,
-                                                rb->channels,
-                                                get_format(rb)) < 0)
+        if (patch_sample_load(patch, name, samplerate,
+                                           rb->channels,
+                                           get_format(rb),
+                                           true) < 0)
         {
             err = pf_error_get();
             goto fail;
@@ -132,7 +133,7 @@
         if (s->filename && strcmp(name, s->filename) == 0)
             return;

-        if (patch_sample_load(patch, name, 0, 0, 0))
+        if (patch_sample_load(patch, name, 0, 0, 0, true))
         {
             err = pf_error_get();
             goto fail;
@@ -252,7 +253,8 @@
         patch_sample_load(patch, last_sample->filename,
                                  last_sample->raw_samplerate,
                                  last_sample->raw_channels,
-                                 last_sample->sndfile_format);
+                                 last_sample->sndfile_format,
+                                 true);
     }

     return;
diff -ruB Petri-Foo-0.1.87/libpetrifoo/patch_util.c Petri-Foo-jph/libpetrifoo/patch_util.c
--- Petri-Foo-0.1.87/libpetrifoo/patch_util.c   2012-08-07 17:10:47.000000000 +0200
+++ Petri-Foo-jph/libpetrifoo/patch_util.c  2014-04-28 21:41:14.179134760 +0200
@@ -257,7 +257,7 @@

     patch_unlock(id);

-    patch_sample_load(id, "Default", 0, 0, 0);
+    patch_sample_load(id, "Default", 0, 0, 0, false);
     p->lower_note = 36;
     p->upper_note = 83;
     p->lower_vel  = 0;
@@ -433,7 +433,8 @@
 int patch_sample_load(int id, const char *name,
                                     int raw_samplerate,
                                     int raw_channels,
-                                    int sndfile_format)
+                                    int sndfile_format,
+                                    bool sampleinfo)
 {
     int val;
     double ratio = (patch_samplerate == 44100)
@@ -482,11 +483,22 @@
     }
     else
     {
-        patches[id]->fade_samples = (frames / 2 > 100) ? 100 * ratio : 0;
-        patches[id]->xfade_samples = (frames / 2 > 100) ? 100 * ratio : 0;
-        patches[id]->loop_start = patches[id]->xfade_samples;
-        patches[id]->loop_stop = patches[id]->sample_stop -
+       /* read loop info from the sample file */
+       if ( sampleinfo && patches[id]->sample->loop_valid)
+       {
+           patches[id]->fade_samples = 0;
+           patches[id]->xfade_samples = 0;
+           patches[id]->loop_start = patches[id]->sample->loop_start;
+           patches[id]->loop_stop = patches[id]->sample->loop_end;
+       }
+       else
+       {
+           patches[id]->fade_samples = (frames / 2 > 100) ? 100 * ratio : 0;
+           patches[id]->xfade_samples = (frames / 2 > 100) ? 100 * ratio : 0;
+           patches[id]->loop_start = patches[id]->xfade_samples;
+           patches[id]->loop_stop = patches[id]->sample_stop -
                                     patches[id]->xfade_samples;
+       }
     }

     if (patches[id]->sample_stop < patches[id]->fade_samples)
@@ -624,7 +636,8 @@
                 Sample* s = patches[id]->sample;
                 patch_sample_load(id, s->filename,  s->raw_samplerate,
                                                     s->raw_channels,
-                                                    s->sndfile_format);
+                                                    s->sndfile_format,
+                                                    false);
             }
         }

diff -ruB Petri-Foo-0.1.87/libpetrifoo/patch_util.h Petri-Foo-jph/libpetrifoo/patch_util.h
--- Petri-Foo-0.1.87/libpetrifoo/patch_util.h   2012-08-07 17:10:47.000000000 +0200
+++ Petri-Foo-jph/libpetrifoo/patch_util.h  2014-04-22 21:16:47.074279758 +0200
@@ -50,7 +50,8 @@
 int         patch_sample_load     (int id, const char* file,
             /* 0 for non-raw data */    int raw_samplerate,
             /* 0 for non-raw data */    int raw_channels,
-            /* 0 for non-raw data */    int sndfile_format);
+            /* 0 for non-raw data */    int sndfile_format,
+                                       bool sampleinfo);

 int         patch_sample_load_from(int dest_id, int src_id);

diff -ruB Petri-Foo-0.1.87/libpetrifoo/sample.c Petri-Foo-jph/libpetrifoo/sample.c
--- Petri-Foo-0.1.87/libpetrifoo/sample.c   2012-08-07 17:10:47.000000000 +0200
+++ Petri-Foo-jph/libpetrifoo/sample.c  2014-04-28 21:39:36.046122368 +0200
@@ -325,6 +325,32 @@
 }


+/*
+ * get loop informations from sample data
+ */
+static bool sample_get_loop_info( SNDFILE *sndfile, unsigned int *start, unsigned int *end)
+{
+
+   SF_INSTRUMENT inst;
+   bool result = false;
+
+
+   sf_command( sndfile, SFC_GET_INSTRUMENT, &inst, sizeof (inst));
+   /* check existence of a loop */
+   if ( inst.loop_count == 1 )
+   {
+       if ( (inst.loops[0].mode >= 800) && (inst.loops[0].mode <= 809) &&
+            (inst.loops[0].start <  inst.loops[0].end) )
+       {
+           *start = inst.loops[0].start;
+           *end = inst.loops[0].end;
+           result = true;
+       }
+   }
+   return result;
+}
+
+
 int sample_load_file(Sample* sample, const char* name,
                                         int rate,
                                         int raw_samplerate,
@@ -335,6 +361,13 @@
     float* tmp;
     SF_INFO sfinfo;
     SNDFILE* sfp;
+    unsigned int lstart;
+    unsigned int lend;
+    bool sf_loop_ret;
+    int size_o;
+    int size_r;
+    double ratio;
+

     if (!(sfp = open_sample(&sfinfo, name,  raw_samplerate,
                                             raw_channels,
@@ -346,6 +379,9 @@
     if (!(tmp = read_audio(sfp, &sfinfo)))
         return -1;

+    /* get loop points */
+    sf_loop_ret = sample_get_loop_info( sfp, &lstart, &lend);
+
     sf_close(sfp);

     if (raw_samplerate || raw_channels || sndfile_format)
@@ -366,6 +402,8 @@
             JACK is not running, useful under debug conditions. */
         if (rate > 0 && sfinfo.samplerate != rate)
         {
+           size_o = sfinfo.frames;
+
             float* tmp2 = resample(tmp, rate, &sfinfo);

             if (!tmp2)
@@ -374,14 +412,23 @@
                 return -1;
             }

-            free(tmp);
+           free(tmp);
             tmp = tmp2;
+
+            /* modify loop points according to the new length */
+            if ( sf_loop_ret )
+            {
+               size_r = sfinfo.frames;
+               ratio = size_r/(size_o * 1.0);
+               lstart = lstart * ratio;
+               lend = lend * ratio;
+            }
         }
     }

     if (sfinfo.channels == 1)
     {
-        float* tmp2 = mono_to_stereo(tmp, &sfinfo);
+       float* tmp2 = mono_to_stereo(tmp, &sfinfo);

         if (!tmp2)
         {
@@ -403,6 +450,21 @@

     sample->default_sample = false;

+    if ( sf_loop_ret )
+    {
+       if ( lstart > (unsigned int) sample->frames )
+           lstart = sample->frames;
+       if ( lend > (unsigned int) sample->frames )
+           lend = sample->frames;
+           sample->loop_start = lstart;
+           sample->loop_end = lend;
+           sample->loop_valid = true;
+    }
+    else
+    {
+           sample->loop_valid = false;
+    }
+
     return 0;
 }

diff -ruB Petri-Foo-0.1.87/libpetrifoo/sample.h Petri-Foo-jph/libpetrifoo/sample.h
--- Petri-Foo-0.1.87/libpetrifoo/sample.h   2012-08-07 17:10:47.000000000 +0200
+++ Petri-Foo-jph/libpetrifoo/sample.h  2014-04-28 21:39:36.088122374 +0200
@@ -55,6 +55,10 @@
     int raw_channels;   /* with a header, then these fields will be  */
     int sndfile_format; /* zero. if raw, they will be non-zero       */

+    int loop_start;        /* info present in the sample */
+    int loop_end;
+    bool loop_valid;
+
     char*   filename;

     bool    default_sample;
diff -ruB Petri-Foo-0.1.87/libpetrifui/dish_file.c Petri-Foo-jph/libpetrifui/dish_file.c
--- Petri-Foo-0.1.87/libpetrifui/dish_file.c    2012-08-07 17:10:47.000000000 +0200
+++ Petri-Foo-jph/libpetrifui/dish_file.c   2014-04-22 21:18:20.827298132 +0200
@@ -928,7 +928,8 @@
             if (patch_sample_load(patch_id, filename,
                                             raw_samplerate,
                                             raw_channels,
-                                            sndfile_format) < 0)
+                                            sndfile_format,
+                                            false) < 0)
             {
                 msg_log(MSG_ERROR, "failed to load sample: %s error (%s)\n",
                     filename, pf_error_str(pf_error_get()));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants