Audiostream afspelen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MrMaxus
  • Registratie: Januari 2011
  • Laatst online: 19-07 11:33
Beste,

ik werk momenteel aan een klein projectje waar ik video afspeel. Dit lukt perfect, alleen de bijbehorende audio afspelen lukt niet goed. Ik kan niet de volledige audio ophalen en afspelen, dit moet stuk voor stuk gebeuren.
Bij het afspelen zit er echter een 'tik' in het geluid.

De audio wordt opgehaald en gedecodeerd via de methode GetAudio. Deze levert een array van bytes met wav-data en een voorgaande WAV-header van 44 bytes.De audio wordt tegelijkertijd(iets vroeger) asynchroon opgehaald dus er is geen vertraging door het decoderen ervan.
Deze array wordt dan doorgegeven aan WinMM.dll om het af te spelen.
C#:
1
2
3
4
5
6
7
byte[] audio = audioStream.GetAudio(second, length);

[DllImport("winmm.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        static extern bool PlaySound(
            byte[] pszSound,
            IntPtr hMod,
            SoundFlags sf);


Ik heb al zitten spelen met verschillende lengtes van audio maar het afspelen is nooit perfect. Op voorhand alle audio ophalen is niet direct een optie omdat dit 200+ MB is.

Zijn er betere oplossingen of doe ik iets verkeerd?

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Meestal hoor je je hardware device te bufferen, terwijl je device 1 buffer afspeelt zet je de 2e klaar. Je audiodevice kan dan gelijk overgaan naar de volgende buffer zonder "tik". Volgens mij had WinMM een event-systeem waarbij je buffers kon feeden die je dan terug kreeg in een callback (waarna je ze kan reclaimen of hergebruiken etc). Hoe je dat naar .NET kan porten weet ik niet, maar de code die ik van jou zie ziet er iets te simpel uit, of je hebt lang niet alles gepost :)

-niks-


Acties:
  • 0 Henk 'm!

  • MrMaxus
  • Registratie: Januari 2011
  • Laatst online: 19-07 11:33
De rest van de code is in feite irrelevant, want het betreft enkel het decoden en omzetten naar WAV & toevoegen van een header per stukje, anders speelt het niet af.

Het enige die nog interessant zou zijn, is erg straightforward:
C#:
1
2
3
public static void Play(byte[] bytes){
       SoundPlayer.PlaySound(bytes, IntPtr.Zero, SoundFlags.SND_ASYNC | SoundFlags.SND_MEMORY);
}


Indien in werk met 2 buffers, moet er ook telkens een header meegeleverd worden?

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

MrMaxus schreef op donderdag 24 maart 2011 @ 22:57:
De rest van de code is in feite irrelevant, want het betreft enkel het decoden en omzetten naar WAV & toevoegen van een header per stukje, anders speelt het niet af.

Het enige die nog interessant zou zijn, is erg straightforward:
C#:
1
2
3
public static void Play(byte[] bytes){
       SoundPlayer.PlaySound(bytes, IntPtr.Zero, SoundFlags.SND_ASYNC | SoundFlags.SND_MEMORY);
}


Indien in werk met 2 buffers, moet er ook telkens een header meegeleverd worden?
Wanneer stuur je een nieuwe buffer dan?
PlaySound is bedoeld om hele files in 1x af te spelen, jij kan je waveform wel opbreken in verschillende stukken, maar hoe maak je duidelijk dat 1 buffer op de andere aansluit? Met PlaySound kan dat in elk geval niet afaik.

De correcte manier om dit te doen met winMM is volgens mij met waveOutWrite (om buffers toe te voegen), maar dat is een stuk ingewikkelder (om nog maar niet te gaan praten over dat je native structs moet gaan marshallen etc) Wellicht wil je een prebuilt .NET library gaan zoeken op het internet :)

[ Voor 40% gewijzigd door MLM op 24-03-2011 23:11 ]

-niks-


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
MLM schreef op donderdag 24 maart 2011 @ 22:48:
Meestal hoor je je hardware device te bufferen, terwijl je device 1 buffer afspeelt zet je de 2e klaar. Je audiodevice kan dan gelijk overgaan naar de volgende buffer zonder "tik". Volgens mij had WinMM een event-systeem waarbij je buffers kon feeden die je dan terug kreeg in een callback (waarna je ze kan reclaimen of hergebruiken etc). Hoe je dat naar .NET kan porten weet ik niet, maar de code die ik van jou zie ziet er iets te simpel uit, of je hebt lang niet alles gepost :)
Dat is hoe je 't doet met waveOutWrite of OpenAL, de TS is op zoek naar een manier om de audio tegelijk met z'n video te laten lopen. Om dat te doen moet 'ie het voor elkaar zien te krijgen om de audio op de zelfde snelheid af te spelen als de video. Kortom, wellicht moet er het een en ander aan PCM data opgerekt of vertraagt worden.

Acties:
  • 0 Henk 'm!

  • barfieldmv
  • Registratie: Maart 2004
  • Laatst online: 23-08 21:37
.Net werkt met de standaard thread scheduler resolutie van ongeveer 40 ms. 40 ms is net een mooie tik in je audio stream. (zeker op een druk systeem, kan je drie thread blocks missen zit je dus 120ms zonder geluid)

Pas de thread switch resolutie van je applictie aan (zit ook ergens in de Multi Media dll) of zorg dat de audio op een andere manier afspeelt.


pfff Mensen die op een niet real time OS er maar vanuit gaan dat ze Real Time resultaten krijgen bij Video/Audio. Er staat echt niet op de windows doos Nu RealTime OS hoor 8) (windows bash)

[ Voor 21% gewijzigd door barfieldmv op 25-03-2011 09:24 ]

Pagina: 1