2010-08-08 2 views
1

J'essaie de lire un flux en temps réel (je continue d'y appairer des données provenant d'une source externe) mais peu importe ce que FMOD ne veut pas continuer à jouer après premier morceau qui a été chargé, il semble que c'est en train de copier le flux de mémoire/décodage avant de jouer, puis pendant qu'il joue, il n'utilise plus mon flux.C# FMOD Lecture de flux en temps réel

J'utilise ce qui suit pour jouer mon flux:

 var exinfo = new FMOD.CREATESOUNDEXINFO(); 
     exinfo.cbsize = Marshal.SizeOf(exinfo); 
     exinfo.length = (uint)_buffer.Length; 

     _result = System.createStream(_buffer, MODE.CREATESTREAM | MODE.OPENMEMORY_POINT , ref exinfo, ref _sound); 
     FMODErrorCheck(_result); 

     _result = System.playSound(FMOD.CHANNELINDEX.FREE, _sound, false, ref _channel); 
     FMODErrorCheck(_result); 

Mais peu importe, il ne joue que la quantité de données qui est dans le cours d'eau au point d'appeler playSound.

Quelqu'un peut-il savoir comment modifier le tampon en temps réel? Après que le flux a commencé à jouer ...?

Répondre

1

Si vous souhaitez diffuser des données brutes, pas des données PCM, vous pouvez y parvenir en remplaçant le système de fichiers FMOD. Il y a deux façons d'y parvenir, la première consiste à définir les rappels de fichiers dans la structure CreateSoundExInfo s'il s'agit d'un fichier spécifique. La seconde est que vous pouvez définir le système de fichiers globalement pour toutes les opérations de fichiers FMOD (au cas où vous voulez le faire avec plusieurs fichiers). Je vais expliquer ce dernier, il serait trivial de passer à la première cependant. Reportez-vous à l'exemple "filecallbacks" FMOD pour un exemple complet.

pointeurs de fonction:

private FMOD.FILE_OPENCALLBACK myopen = new FMOD.FILE_OPENCALLBACK(OPENCALLBACK); 
private FMOD.FILE_CLOSECALLBACK myclose = new FMOD.FILE_CLOSECALLBACK(CLOSECALLBACK); 
private FMOD.FILE_READCALLBACK myread = new FMOD.FILE_READCALLBACK(READCALLBACK); 
private FMOD.FILE_SEEKCALLBACK myseek = new FMOD.FILE_SEEKCALLBACK(SEEKCALLBACK); 

: Callbacks

private static FMOD.RESULT OPENCALLBACK([MarshalAs(UnmanagedType.LPWStr)]string name, int unicode, ref uint filesize, ref IntPtr handle, ref IntPtr userdata) 
{ 
    // You can ID the file from the name, then do any loading required here 
    return FMOD.RESULT.OK; 
} 

private static FMOD.RESULT CLOSECALLBACK(IntPtr handle, IntPtr userdata) 
{ 
    // Do any closing required here 
    return FMOD.RESULT.OK; 
} 

private static FMOD.RESULT READCALLBACK(IntPtr handle, IntPtr buffer, uint sizebytes, ref uint bytesread, IntPtr userdata) 
{ 
    byte[] readbuffer = new byte[sizebytes]; 

    // Populate readbuffer here with raw data 

    Marshal.Copy(readbuffer, 0, buffer, (int)sizebytes); 
    return FMOD.RESULT.OK; 
} 

private static FMOD.RESULT SEEKCALLBACK(IntPtr handle, int pos, IntPtr userdata) 
{ 
    // Seek your stream to desired position 
    return FMOD.RESULT.OK; 
} 

Mise en œuvre:

// Usual init code here... 

result = system.setFileSystem(myopen, myclose, myread, myseek, 2048); 
ERRCHECK(result); 

// Usual create sound code here... 
2

Je vous recommande de consulter l'exemple "usercreatedsound" livré avec FMOD, il devrait faire ce que vous avez besoin. L'idée de base est de définir les propriétés du son que vous souhaitez lire dans la structure CreateSoundExInfo et de lui fournir des rappels que vous pouvez utiliser pour charger/diffuser des données depuis où vous voulez.

pointeur Fonction:

private FMOD.SOUND_PCMREADCALLBACK pcmreadcallback = new FMOD.SOUND_PCMREADCALLBACK(PCMREADCALLBACK); 

callback utilisée pour alimenter le son FMOD:

private static FMOD.RESULT PCMREADCALLBACK(IntPtr soundraw, IntPtr data, uint datalen) 
{ 
    unsafe 
    { 
     short *stereo16bitbuffer = (short *)data.ToPointer(); 

     // Populate the 'stereo16bitbuffer' with sound data 
    } 

    return FMOD_OK; 
} 
code

pour créer le son qui utilisera la fonction de rappel:

// ...Usual FMOD initialization code here... 

FMOD.CREATESOUNDEXINFO exinfo = new FMOD.CREATESOUNDEXINFO(); 

// You define your required frequency and channels 
exinfo.cbsize   = Marshal.SizeOf(exinfo); 
exinfo.length   = frequency * channels * 2 * 5; // *2 for sizeof(short) *5 for 5 seconds 
exinfo.numchannels  = (int)channels; 
exinfo.defaultfrequency = (int)frequency; 
exinfo.format   = FMOD.SOUND_FORMAT.PCM16; 
exinfo.pcmreadcallback = pcmreadcallback; 

result = system.createStream((string)null, (FMOD.MODE.DEFAULT | FMOD.MODE.OPENUSER | FMOD.MODE.LOOP_NORMAL), ref exinfo, ref sound); 

Cela devrait être suffisant pour vous aider à avancer, j'espère que cela vous aidera.

+0

Merci pour la réponse, cela fonctionnera avec ogg? beacuse je n'ai pas le format brut des fichiers ... –

+0

Non cette solution est juste pour PCM, je fournirai une autre réponse pour le cas des données compressées. –