title: How to find missing audio segments
body: <p>I am writing my own audio format as part of a game console project. Part of the project requires me to write an emulator so I know exactly how to implement it's functions in hardware. I am currently writing the DSP portion, but I am having trouble writing a decoding algorithm. Before I go further, I'll explain my format.</p>
  <p><strong>DST (Dingo Sound Track) Audio format</strong></p>
  <p>The audio format only records to pieces of data per sample: the amplitude and the number of frames since the last sample. I'll explain. When converting an audio file (WAV for example), it compares the current sample with the previous one. If it detects that the current sample switches amplitude direction in relation to the previous sample, it records the previous sample and the number of frames since the last record. It keeps going until the end of the file. Here is a diagram to explain further:</p>
  <p><a href="https://i.stack.imgur.com/e5LWe.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/e5LWe.png" alt="enter image description here" /></a></p>
  <p><strong>What I need to do</strong></p>
  <p>I need my &quot;DSP&quot; to figure out the data between each sample, as accurately as possible using only the given information. I don't think it's my encoding algorithm, because when I play the file in Audacity, I can sort of make out the original song. But when I try to play it with my decoding algorithm, I get scattered clicks. I am able to play WAV files directly with a few mods to the algorithm with almost no quality drop, so I know it's definitely the algorithm and not the rest of the DSP.</p>
  <p><strong>The Code</strong></p>
  <p>So now I got all of the basic info out of the way, here is my code (only the important parts).</p>
  <p>Encoding algorithm:</p>
  <pre><code>                FileInputStream s = null;
                  BufferedWriter bw;
                      try {
                          int bytes;
                          int previous = 0;
                          int unsigned;
                          int frames = 0;
                          int size;
                          int cursor = 0;
                          boolean dir = true;
                          int bytes2;
                          int previous2 = 0;
                          int unsigned2;
                          int frames2 = 0;
                          boolean dir2 = true;
                          s = new FileInputStream(selectedFile);
                          size = (int)s.getChannel().size();
                          File f = new File(Directory.getPath() + &quot;\\&quot; + (selectedFile.getName().replace(&quot;.wav&quot;, &quot;.dts&quot;)));
                          System.out.println(f.getPath());
                          if(!f.exists()){
                              f.createNewFile();
                          }
                          bw = new BufferedWriter(new FileWriter(f));
                          try (BufferedInputStream b = new BufferedInputStream(s)) {
                              byte[] data = new byte[128];
                              b.skip(44);
                              System.out.println(&quot;Loading...&quot;);
                              while ((bytes = b.read(data)) &gt; 0) {
                                // do something
                                for(int i=1; i&lt;bytes; i += 4) {
                                    unsigned = data[i] &amp; 0xFF;
                                    if (dir) {
                                        if (unsigned &lt; previous) {
                                            bw.write(previous);
                                            bw.write(frames);
                                            dir = !dir;
                                            frames = 0;
                                        }else{
                                            frames ++;
                                        }
                                    } else {
                                        if (unsigned &gt; previous) {
                                            bw.write(previous);
                                            bw.write(frames);
                                            dir = !dir;
                                            frames = 0;
                                        }else{
                                            frames ++;
                                        }
                                    }
                                    previous = unsigned;
                                    cursor ++;
                                    unsigned2 = data[i + 2] &amp; 0xFF;
                                    if (dir2) {
                                        if (unsigned2 &lt; previous2) {
                                            bw.write(previous2);
                                            bw.write(frames2);
                                            dir2 = !dir2;
                                            frames2 = 0;
                                        }else{
                                            frames2 ++;
                                        }
                                    } else {
                                        if (unsigned2 &gt; previous2) {
                                            bw.write(previous2);
                                            bw.write(frames2);
                                            dir2 = !dir2;
                                            frames2 = 0;
                                        }else{
                                            frames2 ++;
                                        }
                                    }
                                    previous2 = unsigned2;
                                    cursor ++;
                                    progress.setValue((int)(((float)(cursor / size)) * 100));
                                }
                              }
                              b.read(data);
                          }
                          bw.flush();
                          bw.close();
                          System.out.println(&quot;Done&quot;);
                          convert.setEnabled(true);
                          status.setText(&quot;finished&quot;);
                      } catch (Exception ex) {
                          status.setText(&quot;An error has occured&quot;);
                          ex.printStackTrace();
                          convert.setEnabled(true);
                  }
                  finally {
                      try {
                          s.close();
                      } catch (Exception ex) {
                          status.setText(&quot;An error has occured&quot;);
                          ex.printStackTrace();
                          convert.setEnabled(true);
                      }
                  }
  </code></pre>
  <p>The progress and status objects can be ignored for they are part of the GUI of my converter tool. This algorithm converts WAV files to my format (DST).</p>
  <p>Decoding algorithm:</p>
  <pre><code>int start = bufferSize * (bufferNumber - 1);
  short current;
  short frames;
  short count = 1;
  short count2 = 1;
  float jump;
  for (int i = 0; i &lt; bufferSize; i ++) {
      current = RAM.read(start + i);
      i++;
      frames = RAM.read(start + i);
      if (frames == 0) {
          buffer[count - 1] = current;
          count ++;
      } else {
          jump = current / frames;
          for (int i2 = 1; i2 &lt; frames; i2++) {
              buffer[(2 * i2) - 1] = (short) (jump * i2);
              count ++;
          }
      }
      i++;
      current = RAM.read(start + i);
      i++;
      frames = RAM.read(start + i);
      if (frames == 0) {
          buffer[count2] = current;
          count2 ++;
      } else {
          jump = current / frames;
          for (int i2 = 1; i2 &lt; frames; i2++) {
              buffer[2 * i2] = (short) (jump * i2);
              count2 ++;
          }
      }
  }
  bufferNumber ++;
  if(bufferNumber &gt; maxBuffer){
      bufferNumber = 1;
  }
  </code></pre>
  <p>The RAM object is just a byte array. bufferNumber and maxBuffer refer to the amount of processing buffers the DSP core uses. buffer is the object that the resulting audio is written to. This algorithm set is designed to convert stereo tracks, which works the same way in my format but each sample will contain two sets of data, one for each track.</p>
  <p><strong>The Question</strong></p>
  <p>How do I figure out the missing audio between each sample, as accurately as possible, and how accurate will the approach be? I would love to simply use the WAV format, but my console is limited on memory (RAM). This format halves the RAM space required to process audio. I am also planning on implementing this algorithm in an ARM microcontroller, which will be the console's real DSP. The algorithm should also be fast, but accuracy is more important. If I need to clarify or explain anything further, let me know since this is my first BIG question and I am sure I forgot something. Code samples would be nice, but aren't needed that much.</p>
  <p><strong>EDIT:</strong></p>
  <p>I managed to get the DSP to output a song, but it's sped up and filled with static. The sped up part is due to a glitch in it not splitting the track into stereo (I think). And the static is due to the initial increment being too steep. Here is a picture of what I'm getting:
  <a href="https://i.stack.imgur.com/vRkry.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vRkry.png" alt="enter image description here" /></a></p>
  <p>Here is the new code used in the DSP:</p>
  <pre><code>            if (frames == 0) {
                  buffer[i - 1] = current;
                  //System.out.println(current);
              } else {
                  for (int i2 = 1; i2 &lt; frames + 1; i2++) {
                      jump = (float)(previous + ((float)(current - previous) / (frames - i2 + 1)));
                      //System.out.println((short)jump);
                      buffer[(2 * i2) - 1] = (short)(jump);
                  }
              }
              previous = current;
  </code></pre>
  <p>I need a way to smooth out those initial increments, and I'd prefer not to use complex arithmetic because I am limited on performance when I port this to hardware (preferably something that can operate on a 100MHZ ARM controller while being able to keep a 44.1KHZ sample rate). Edit: the result wave should actually be backwards. Sorry.</p>
  <p><strong>Second Edit:</strong>
  I got the DSP to output in stereo, but unfortunately that didn't fix anything else like I hoped it would. I also fixed some bugs with the encoder so now it takes 8 bit unsigned audio. This has become more of a math issue so I think I'll post a similar question in Mathematics Stack Exchange. Well that was a waste of time. It got put on fhold near instantly.</p>