質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3724閲覧

JavaでJNAを用いてOGGを同時に再生できない

KureteRubyLua

総合スコア206

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/05/24 12:34

編集2016/05/24 12:35

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}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これはおそらく、
DLL側がマルチスレッドに対応していないためではないでしょうか。

Dix::sp< Dix::OggVorbisMemory > spOggResourceを含めて4つのグローバル変数を2つのスレッドで共有してしまっているんだと思います。

JNAは詳しくないので具体的な対応方法はお教えすることができませんが、
変数を構造体にまとめるかクラス化するかして、スレッドごとにインスタンスを作るようにすれば回避できるかもしれません。

投稿2016/05/25 11:54

argius

総合スコア9390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KureteRubyLua

2016/05/26 13:33 編集

>変数を構造体にまとめるかクラス化するかして、スレッドごとにインスタンスを作るようにすれば回避できるかもしれません。 これを行うには具体的にどのようにすればいいのでしょうか?
argius

2016/05/26 13:01

回答に書いた通り、具体的にどうすれば良いのか適切にお教えすることができません。 私の推測では、この質問がJNAに特化しているため、C++に詳しい回答者さんに見てもらえていない可能性があると思っています。 「DLLのマルチスレッド対応」という切り口で別途質問されてみては如何ですか? 私はJava+JNAに限らず、他言語からマルチスレッドでこのDLLを呼び出した場合に同様の問題が発生するかも知れないと思っていますので、 質問のポイントとしては、 ・この質問に関連する質問であることを明記してください。(この質問のURLを貼ってください) ・タイトルとタグは、Javaについて触れないでおいてください。 ・本文で、JavaからJNA経由でマルチスレッドで呼び出している旨を書いてください。 この辺を押さえてやってみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問