Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

184
LINES

< > BotCompany Repo | #1032917 // OpusFromStream_v2

JavaX fragment (include) [tags: use-pretranspiled]

Uses 521K of libraries. Compilation Failed (6322L/37K).

1  
// derived from org.gagravarr.opus.OpusFile
2  
/*
3  
 * Licensed under the Apache License, Version 2.0 (the "License");
4  
 * you may not use this file except in compliance with the License.
5  
 * You may obtain a copy of the License at
6  
 *
7  
 *     http://www.apache.org/licenses/LICENSE-2.0
8  
 *
9  
 * Unless required by applicable law or agreed to in writing, software
10  
 * distributed under the License is distributed on an "AS IS" BASIS,
11  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  
 * See the License for the specific language governing permissions and
13  
 * limitations under the License.
14  
 */
15  
 
16  
lib 1400511 // VorbisJava (to unpack ogg file)
17  
lib 1400502 // Concentus 1.0 (to decode OPUS audio in ogg file)
18  
19  
import org.gagravarr.ogg.*;
20  
import org.gagravarr.ogg.audio.*;
21  
import org.gagravarr.opus.*;
22  
import static org.gagravarr.ogg.OggStreamIdentifier.OggStreamType;
23  
import org.concentus.*;
24  
25  
sclass OpusFromStream_v2 implements OggAudioStream, OggAudioHeaders, Closeable {
26  
  InputStream in;
27  
  OggStreamPacketReader_v2 r;
28  
  int sid = -1;
29  
  int channels;
30  
  OpusDecoder decoder;
31  
32  
  OpusInfo info;
33  
  OpusTags tags;
34  
35  
  // channels = 1 or 2 (mono/stereo)
36  
  *(InputStream *in, int *channels) throws IOException, OpusException {
37  
    decoder = new OpusDecoder(48000, channels);
38  
    r = new OggStreamPacketReader_v2(in);
39  
  }
40  
  
41  
  bool initialized() { ret tags != null; }
42  
  
43  
  bool initStep() throws IOException {
44  
    OggStreamPacket p = null;
45  
    
46  
    // find first packet (info)
47  
    
48  
    if (sid < 0) {
49  
      while ((p = getNextPacket()) != null) {
50  
        if (p.isBeginningOfStream() && p.getData().length > 10) {
51  
          if (OpusPacketFactory.isOpusStream(p)) {
52  
            sid = p.getSid();
53  
            info = (OpusInfo) OpusPacketFactory.create(p);
54  
            ifdef OpusFromStream_debug
55  
              printVars OpusFromStream(+sid, +info);
56  
            endifdef
57  
            break;
58  
          }
59  
        }
60  
      }
61  
    }
62  
    
63  
    // find second packet (tags)
64  
    
65  
    if (tags == null) {  
66  
      if ((p = getNextPacketWithSid(sid)) != null) {
67  
        tags = (OpusTags) OpusPacketFactory.create(p);
68  
        ifdef OpusFromStream_debug
69  
          printVars OpusFromStream(+tags);
70  
        endifdef
71  
      }
72  
    }
73  
    
74  
    ret initialized();
75  
  }
76  
77  
  public OpusAudioData getNextAudioPacket() throws IOException {
78  
    if (!initStep()) null;
79  
    
80  
    OggStreamPacket p = null;
81  
    OpusPacket op = null;
82  
    while ((p = getNextPacketWithSid(sid)) != null) {
83  
      op = OpusPacketFactory.create(p);
84  
      if (op cast OpusAudioData) ret op;
85  
      else
86  
        warn("Skipping non audio packet " + op + " mid audio stream");
87  
    }
88  
    null;
89  
  }
90  
91  
  /**
92  
   * Returns the Ogg Stream ID
93  
   */
94  
  public int getSid() {
95  
    ret sid;
96  
  }
97  
98  
  /**
99  
   * This is an Opus file
100  
   */
101  
  public OggStreamType getType() {
102  
    ret OggStreamIdentifier.OPUS_AUDIO;
103  
  }
104  
105  
  public OpusInfo getInfo() {
106  
    return info;
107  
  }
108  
  
109  
  public OpusTags getTags() {
110  
    return tags;
111  
  }
112  
  
113  
  public void skipToGranule(long granulePosition) throws IOException {
114  
    unimplemented();
115  
  }
116  
  
117  
  /**
118  
   * Opus doesn't have setup headers, so this is always null
119  
   */
120  
  public OggAudioSetupHeader getSetup() {
121  
    null;
122  
  }
123  
124  
  close {
125  
    dispose r;
126  
    dispose in;
127  
  }
128  
129  
  // return some audio samples. null if none available
130  
  short[] nextSamples() throws OpusException, IOException {
131  
    OpusAudioData data;
132  
    while ((data = getNextAudioPacket()) != null) {
133  
      byte[] bytes = data.getData();
134  
      if (empty(bytes)) continue;
135  
136  
      // decode packet
137  
      short[] pcm = new[5760*channels]; // max opus frame size
138  
      int nSamples = decoder.decode(bytes, 0, l(bytes), pcm, 0, l(pcm), false);
139  
      ret subShortArray(pcm, 0, nSamples);
140  
    }
141  
    null;
142  
  }
143  
  
144  
  public OggStreamPacket getNextPacket() throws IOException {
145  
    in.mark(65536);
146  
    OggStreamPacket p;
147  
    try {
148  
      p = r.getNextPacket();
149  
    } catch (EOFException e) {
150  
      ifdef OpusFromStream_debug
151  
        print("OpusFromStream: EOFException, resetting");
152  
      endifdef
153  
      in.reset();
154  
      null;
155  
    }
156  
    
157  
    if (p == null) {
158  
      ifdef OpusFromStream_debug
159  
        print("OpusFromStream: packet null, resetting");
160  
      endifdef
161  
      in.reset();
162  
    }
163  
    ifdef OpusFromStream_debug
164  
      printVars OpusFromStream(packet := p, +in);
165  
    endifdef
166  
    ret p;
167  
  }
168  
  
169  
  /**
170  
     * Returns the next packet with the given SID (Stream ID), or
171  
     *  null if no more packets remain.
172  
     * Any packets from other streams will be silently discarded.
173  
     */
174  
  public OggStreamPacket getNextPacketWithSid(int sid) throws IOException {
175  
    OggStreamPacket p = null;
176  
    while ((p = getNextPacket()) != null) {
177  
      if (p.getSid() == sid) ret p;
178  
    }
179  
    null;
180  
  }
181  
  
182  
  // e.g. for mark/reset
183  
  static int bufferSizeNeeded() { ret 65536; }
184  
}

Author comment

Began life as a copy of #1032905

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1032917
Snippet name: OpusFromStream_v2
Eternal ID of this version: #1032917/2
Text MD5: ed1e341c49cc56de18588e4faad0ec56
Transpilation MD5: bcbc6e20ecb2406fd873b9029aef59f9
Author: stefan
Category: javax / audio
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-10-10 21:55:52
Source code size: 4951 bytes / 184 lines
Pitched / IR pitched: No / No
Views / Downloads: 87 / 178
Version history: 1 change(s)
Referenced in: [show references]