JavaでJNAを用いてDLL上でOGGをデコードし、Java上で再生するという事をやっているのですが、マルチスレッドを用いて同時に再生しようとすると、何故かInvalid Memory Accessが出たり、音がおかしくなったりします。原因は全く分かりません。
ソースコードは以下の通りです。OGGのデコードのソースは以下のURLを使用しております。
http://marupeke296.com/OGG_main.html
よろしくお願いします。
DLL部分
C++
1#include <memory.h> 2#include <string> 3#include <iostream> 4#include "vorbis/vorbisfile.h" 5#include "OggDecoder.h" 6#include "OggVorbisMemory.h" 7#include "OggVorbisFile.h" 8#include "PCMPlayer.h" 9#include "DixSmartPtr.h" 10#include "DixComPtr.h" 11#include "OggMain.h" 12 13using namespace std; 14 15Dix::sp< Dix::OggVorbisMemory > spOggResource; 16Dix::sp< Dix::OggDecoder > spOggDecoder; 17int check; 18char* path; 19 20extern "C" int OggDll::open(char* filePath) 21{ 22 check = -1; 23 path = filePath; 24 25 spOggResource = Dix::sp< Dix::OggVorbisMemory > (new Dix::OggVorbisMemory); 26 if (spOggResource->createBuffer(filePath) == false) 27 { 28 check = -1; 29 return -1; 30 } 31 else 32 { 33 check = 0; 34 spOggDecoder = Dix::sp< Dix::OggDecoder>(new Dix::OggDecoder(spOggResource)); 35 spOggDecoder->getSampleRate(); 36 return 0; 37 } 38} 39 40extern "C" void OggDll::close() 41{ 42} 43 44 45// 指定サイズでPCM音声バッファを埋める関数 46extern "C" int OggDll::getPCMBuffer(char* buffer,int bufferSize) 47{ 48 bool a = true; 49 unsigned int b = 100; 50 if(check==-1) 51 { 52 return -1; 53 } 54 else 55 { 56 spOggDecoder->getSegment(buffer, bufferSize, &b, &a); 57 if (a == true) 58 { 59 cout << " a true " << endl; 60 return 0; 61 } 62 else 63 { 64 cout << " a false" << endl; 65 return -1; 66 } 67 } 68} 69 70// 指定サイズでPCM音声バッファを埋める関数 71extern "C" int OggDll::getSampleRate() 72{ 73 if (check == -1) 74 { 75 return -1; 76 } 77 else 78 { 79 return spOggDecoder->getSampleRate(); 80 } 81} 82 83// 指定サイズでPCM音声バッファを埋める関数 84extern "C" int OggDll::getChannel() 85{ 86 if (check == -1) 87 { 88 return -1; 89 } 90 else 91 { 92 return spOggDecoder->getChannel(); 93 } 94}
Java
Java
1public interface OggDllLibrary extends Library { 2 public String JNA_LIBRARY_NAME = "OggDll"; 3 public NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(OggDllLibrary.JNA_LIBRARY_NAME); 4 public OggDllLibrary INSTANCE = (OggDllLibrary)Native.loadLibrary(OggDllLibrary.JNA_LIBRARY_NAME, OggDllLibrary.class); 5 int getPCMBuffer(ByteBuffer buffer, int bufferSize); 6 int open(String filePath); 7 int close(); 8 int getSampleRate(); 9 int getChannel(); 10} 11 12public class OggClip extends DataClip { 13 //Oggを再生するためのDLLを呼び出す変数 14 OggDllLibrary oggDll; 15 //バッファ 16 ByteBuffer buffer; 17 /** 18 * コンストラクタ 19 * @param file ファイル 20 * @param volume ボリューム 21 * @param intPitch ピッチ(50~150%) 22 * @param leftRight 左右の位相 23 * @throws UnsupportedAudioFileException 24 * @throws IOException 25 * @throws LineUnavailableException 26 */ 27 public OggClip(File file, int volume, int intPitch, int leftRight) 28 throws UnsupportedAudioFileException, IOException, 29 LineUnavailableException { 30 super(file, volume, intPitch, leftRight); 31 oggDll=(OggDllLibrary)Native.loadLibrary(OggDllLibrary.JNA_LIBRARY_NAME, OggDllLibrary.class); 32 33 oggDll.open(file.getAbsolutePath()); 34 AudioFormat format = new AudioFormat(oggDll.getSampleRate(), 16,oggDll.getChannel(), true, false); 35 DataLine.Info info = new DataLine.Info (SourceDataLine.class,format, AudioSystem.NOT_SPECIFIED); 36 // ラインを取得 37 line = (SourceDataLine) AudioSystem.getLine (info); 38 bits=16; 39 buffer=ByteBuffer.allocate(oggDll.getSampleRate()); 40 sampleRate=oggDll.getSampleRate(); 41 line.open(format); 42 thread.start(); 43 } 44 45 /** 46 * 実際に再生する 47 */ 48 public void render() throws IOException { 49 int ret; 50 if (playing) { 51 ret = oggDll.getPCMBuffer(buffer,sampleRate); 52 System.out.println(file.getAbsolutePath()+" "+ret); 53 if(ret != -1) 54 { 55 //データを加工する 56 processingByteData=resampling(buffer.array()); 57 line.write (processingByteData, 0, processingByteData.length); 58 } 59 else 60 { 61 notYetEOF= false; 62 } 63 } else { 64 try { Thread.sleep (10);} 65 catch (InterruptedException ie) {} 66 } 67 } 68 69 /** 70 * スタート 71 */ 72 public void start() { 73 playing = true; 74 line.start(); 75 } 76 /** 77 * 再スタート 78 */ 79 public void contStart(){ 80 if(playing){ 81 oggDll.open(file.getAbsolutePath()); 82 super.contStart(); 83 }else{ 84 start(); 85 } 86 } 87 88 /** 89 * ストップ 90 */ 91 public void stop(){ 92 super.stop(); 93 oggDll.close(); 94 } 95 96 97 /** 98 * スレッド上で稼働させる関数 99 */ 100 public void run() 101 { 102 try { 103 while(true) 104 { 105 System.out.println("playing "+playing +" notYetEOF "+notYetEOF); 106 if(playing && notYetEOF) 107 { 108 render(); 109 } 110 else 111 { 112 stop(); 113 114 break; 115 } 116 } 117 } catch (IOException e) { 118 // TODO Auto-generated catch block 119 e.printStackTrace(); 120 } 121 } 122}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/26 13:33 編集
2016/05/26 13:01