2016-11-14 10 views
0

私はC++でネイティブコードをdllにエクスポートし、それをC#スクリプトで1つにインポートしました。 C++コードは、wavファイルから音楽を再生します。統一された場面では、私は矢印キーを押しながら回転させることができる人間の頭を持っています。私がしたいのは、両方の方法を同期させることです。私は頭を回転させると同時に音楽を再現したい、将来的に頭の回転に応じて音楽が変わるからです。同時に2つのメソッドC++とc#を実行Unity

私はUnityゲームを実行すると、音楽が再生され、再生が完了すると、人間の頭を回転させることができます。これまでにない。ここで

が私のコードです:

Audio.h:

#pragma once 
#include <iostream> 
#define EXPORT __declspec(dllexport) 

extern "C" {  
    EXPORT void initialize(std::string soundFilePaths[]); 
    EXPORT void setSourcePosition(std::string soundFilePath, float x, float y, float z); 
    EXPORT void play(); 
    EXPORT void stop(); 
    EXPORT void setListenerRotation(float x, float y, float z); 
} 

class Audio { 

public: 

static Audio& instance() { // Singleton 
    static Audio INSTANCE; 
    return INSTANCE; 
} 

void initialize(std::string soundFilePaths[]); 
void setSourcePosition(std::string soundFilePath, float x, float y, float z); 
void play(); 
void stop(); 
void setListenerRotation(float x, float y, float z); 
~Audio(); 

private:  
    Audio(); 
}; 

Audio.cpp:ここ

#include "Buffer.h" 
#include "MonoSample.h" 
#include "AudioDevice.h" 
#include "Audio.h" 
#include <windows.h> 
#include <mmsystem.h> 

#include <thread> 

#include <stdio.h> 
#include <conio.h> 

#define NUMCHANNELS 2 
#define OUTBUFSIZE 1024  
#define CREATEWAVFILE true 


extern "C" {  

    void initialize(const char *soundFilePaths[], bool continuous) {  
     Audio::instance().initialize(soundFilePaths,continuous);   
    } 

    void setSourcePosition(const char *soundFilePath, float x, float y, float z) { 
     Audio::instance().setSourcePosition(soundFilePath, x, y, z); 
    } 

    void play() { 
     Audio::instance().play(); 
    } 

    void stop() { 
     Audio::instance().stop(); 
    } 

    void setListenerRotation(float x, float y, float z) { 
     Audio::instance().setListenerRotation(x, y, z); 
    } 
} 

float degree; 
int numCanals; 

Buffer channel[NUMCHANNELS];       // Input buffer 
unsigned char buffer[OUTBUFSIZE];      // Ouput buffer 
wavHdr header, *pheader; 
FILE* outFile;           // Create output (wave format) file 
AudioDevice ad; 


Audio::Audio() 
{ 
} 

Audio::~Audio() 
{ 
} 

void Audio::initialize(const char *soundFilePaths[], bool continuous) 
{ 
    char nom[20]; 

    for (int i = 0; i < NUMCHANNELS; i++) 
    { 
     sprintf(nom, "%02d.wav", i + 1); 
     string fitxer(nom); 
     string path = WAVBASEPATH + fitxer; 
     if (!channel[i].openFile(path, i))  //obre i llegeix bytes (fread) 
     { 
      /*cout << "ERROR [" << i + 1 << "]";*/ 
      ExitProcess(1); 
     } 
    } 

    int inSampleRate = channel[0].getHeader().samplesPerSec;   
    int inSampleLen = channel[0].getHeader().bitsPerSample; 
    int inNumberOfCn = channel[0].getHeader().numOfChan;    

    ad.iniAudioDevice(inSampleRate, inSampleLen, 2);     
    ad.setVolume50p();            

} 

void Audio::setSourcePosition(const char *soundFilePath, float x, float y, float z) 
{ 

} 

void Audio::play() 
{  
     while (1) 
     { 
      long readBytes; 
      readBytes = channel[0].ReadInputBufferBlock(buffer, OUTBUFSIZE, channel, NUMCHANNELS, 1, false);    

      if (readBytes > 0) 
      { 
       ad.writeAudio((LPSTR)buffer, sizeof(buffer));   
      } 
      else 
       break; 
     } 
} 

void Audio::stop() 
{ 
    while (ad.waveFreeBlockCount < BLOCK_COUNT)      
     Sleep(10); 

    ad.closeAudioDevice(); 
} 

はユニティのC#スクリプトです:

using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using UnityEngine; 

public class AudioPlugin : MonoBehaviour 
{ 
    public AudioContainer[] audioContainers; 
    public Transform headGeometry; 
    public float rotationSpeed = 50; 
    public float maxYRotation = 90; 
    public float minYRotation = -90; 

    float _currentYRotation; 


    void Start() 
    { 
     _currentYRotation = headGeometry.transform.rotation.eulerAngles.y; 
     string[] filePaths = GetAllFilePathsFromClips(); 
     AudioPluginConnection.Initialize(filePaths); 
     AudioPluginConnection.Play(); 
    } 

    void Update() 
    { 
     TurnHeadWithInput(); 
     UpdateListenerRotation(); 
     UpdateSoundPositions(); 
    } 

    void OnDestroy() 
    { 
     AudioPluginConnection.Stop(); 
    } 

    void TurnHeadWithInput() 
    { 
     float horizontal = Input.GetAxis("Horizontal"); 
     horizontal *= Time.deltaTime * rotationSpeed; 
     _currentYRotation = Mathf.Clamp(_currentYRotation + horizontal, minYRotation, maxYRotation); 
     Vector3 eulerAngles = headGeometry.rotation.eulerAngles; 
     eulerAngles.y = _currentYRotation; 
     headGeometry.rotation = Quaternion.Euler(eulerAngles); 
    } 

    void UpdateListenerRotation() 
    { 
     Vector3 eulerAngles = headGeometry.rotation.eulerAngles; 
     AudioPluginConnection.SetListenerRotation(eulerAngles.x, eulerAngles.y, eulerAngles.y); 
    } 

    void UpdateSoundPositions() 
    { 
     foreach (AudioContainer container in audioContainers) 
     { 
      Vector3 position = container.source.position; 
      AudioPluginConnection.SetSourcePosition(container.filePath, position.x, position.y, position.z); 
     } 
    } 

    string[] GetAllFilePathsFromClips() 
    { 
     List<string> audioFilePaths = new List<string>(); 
     foreach (AudioContainer container in audioContainers) 
     { 
      audioFilePaths.Add(container.filePath); 
     } 
     return audioFilePaths.ToArray(); 
    }  
} 

[System.Serializable] 
public class AudioContainer 
{ 
    public AudioClip clip; 
    public Transform source; 
    //Dont forget, that you have to copy the Audio Folder in the 
    //Unity Editor to the *_Data Folder in your builded Project!!! Quan construim projecte 
    public string filePath { get { return Application.dataPath + "/Audio/" + clip.name + ".wav"; } } 
} 

public class AudioPluginConnection 
{ 
    [DllImport("AudioPlugin", EntryPoint = "test")] 
    public static extern int Test(); 
    [DllImport("AudioPlugin", EntryPoint = "initialize")] 
    public static extern void Initialize(string[] soundFilePaths); 
    [DllImport("AudioPlugin", EntryPoint = "setSourcePosition")] 
    public static extern void SetSourcePosition(string soundFilePath, float x, float y, float z); 
    [DllImport("AudioPlugin", EntryPoint = "play")] 
    public static extern void Play(); 
    [DllImport("AudioPlugin", EntryPoint = "stop")] 
    public static extern void Stop(); 
    [DllImport("AudioPlugin", EntryPoint = "setListenerRotation")] 
    public static extern void SetListenerRotation(float x, float y, float z); 
} 

私はmaに並列スレッドを作成する必要があると思う1つには、両方の行動を行うことができるように統一されていますが、わかりません。

機能AudioPluginConnection.play()はサウンドを再生するもので、TurnHeadWithInput()関数はヘッドを回転させるものです。

私の目標は、ヘッドを回転させるボタンを押しながら、音楽も鳴るようにすることです。将来、頭部の回転に応じて、wavファイルのサンプルにアルゴリズムを適用し、それを再現します。

は、あなたが正しい、事前

答えて

0

にありがとう、あなたは別のスレッドを作成し、そのスレッドからあなたのC++の機能を実行する必要があります。私はスレッドについて学ぶためにいくつかの情報源をお勧めしたいと思います: Unity AnswersのBunny83は、hereにUnityのスレッディングに関するいくつかの重要なことについて約束しました。

スレッド化はUnityではなくC#で実装されているので、スレッドに関するMSDNチュートリアルを読むことをお勧めします。here

関連する問題