Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

'klikloos' loopen binnen DirectSound buffers. Hoe

musicom76
2 antwoorden
  • Hallo mensen. Ik heb een probleempje met het loopen binnen DirectSound buffers. Handig te weten is misschien het feit dat het over een sample gaat van een orgelpijp, opgenomen in
    een ruimte met 2 seconden nagalm.

    De situatie is als volgt:

    Ik heb een sample. Deze bestaat uit 3 delen, en het idee is dat hij 'bespeeld' kan worden
    met een MIDI-keyboard. Zodra de toets op het kb ingedrukt wordt, moet de sample uiteraard
    gaan spelen. Logisch. Maar, de sample moet blijven spelen als de toets ingedrukt BLIJFT !!
    Welnu, in mijn geval kan ik niet gewoon IDirectsoundbuffer.Play(0,0,1) aanroepen oftewel de sample 'loopend' afspelend, want het begin en einde van de sample mogen niet herhaald worden. Het is dus de bedoeling dat alleen het middenste deel van de sample, tussen twee
    vast bepaalde punten - in mijn voorbeeld L1 en L2 - geloopt moet worden terwijl de toets
    ingedrukt blijft.

    De volgorde moet dus zijn :
    TOETS INDRUK : Sample speelt af
    AANGEKOMEN BIJ einde Loop-gedeelte : CurrentPlayPosition wordt terug gezet naar begin loop-gedeelte
    TOETS LOSLAAT : CurrentPlayPositoin wordt geset naar einde loop-gedeelte en de buffer speelt de sample verder af totdat deze afgelopen is. (nagalm stukje)


    Ik heb zelf al bedacht om per sample 3 buffers te gebruiken, en het loopgedeelte in de middelste buffer te stoppen. Als ik ze dan achter elkaar afspeel blijkt er geen fatsoenlijke
    loop te makne zijn, je hoort de klikjes van de overgangen. het verwisselen van de Current Playing Buffer kost teveel tijd, enkele milliseconden zelfs.

    Nu wil ik het dus binnen 1 sample houden en met setCurrentPlayPosition doen. Maar ook nu hoor ik klikjes. Ik denk dat het aan mijn manier ligt van 'detecteren' wanneer currentPlayPosition gelijk is aan L2 (einde loopgedeelte), ik gebruik Sleep(ms: integer) en
    die werkt maar tot op de millisec oftewel met 1000 hertz. en ik vrees dat ik een hogere triggerfrequentie nodig heb, de sample speelt immers af met 44100 hertz.

    Ik hoop dat jullie mij kunnen helpen om dit probleem op te lossen !

    [Mijn (Delphi3) code:]
    ——————————————————————————
    // i:\testsamp.wav loopgedeelte (splwaarden): 35319 - 51621

    samplesPerSecond := lpwfxFormat.nSamplesPerSec;

    // channels en bits/spl opvragen om te kunnen converteren van
    // sampleNRs(in de editboxen) naar byteNRs.
    multiplyier := lpwfxFormat.nChannels * lpwfxFormat.wBitsPerSample div 8;

    aantalkeren := strtoint(edit_loopaantal.Text);

    //beginpunt loop
    L1 := StrToInt(edit_from.Text);// * multiplyier; // conv sampNR naar byteNR
    //eindpunt loop
    L2 := StrToInt(edit_to.Text);// * multiplyier;

    //wat onhandig maar goed…
    // sleeptime1 = tijd in ms van begin tot begin loop-gedeelte
    // sleeptime2 = tijd in ms van begin loop-gedeelte tot eind loop-gedeelte
    exsleeptime1 := (1000 * L1) / samplesPerSecond; // in millisec
    exsleeptime2 := (1000 * (L2-L1)) / samplesPerSecond; // in millisec
    strsleeptime1 := FloatToStr(exsleeptime1);
    strsleeptime2 := FloatToStr(exsleeptime2);
    intsleeptime1 := StrToInt(Copy(strsleeptime1, 1, Pos(',', strsleeptime1)-1));
    intsleeptime2 := StrToInt(Copy(strsleeptime2, 1, Pos(',', strsleeptime2)-1));


    // zet de buffer aan het spelen
    buffer.SetCurrentPosition(0);
    buffer.play(0,0,0);

    // speel 1e deel sample
    sleep(intsleeptime1); // in millisec

    if aantalkeren = 1 then
    begin
    // 2e (LOOP-) deel sample
    Log1('Playing 2nd (LOOP-) part');
    sleep(intsleeptime2); // in millisec
    Log2('Done');
    end else
    for i := 1 to aantalkeren-1 do
    begin
    // 2e (LOOP-) deel sample
    sleep(intsleeptime2); // in millisec
    buffer.SetCurrentPosition(L1*Multiplyier);
    buffer.getCurrentPosition(dwCurrentPlayCursor, lpdwCurrentWriteCursor);

    end;

    // 3e deel sample speelt vanzelf af omdat setCurrentPosition niet meer is aangeroepen.

    end;
    ——————————————————————————
  • [quote:a5174a2b98="musicom76"]
    De volgorde moet dus zijn :
    TOETS INDRUK : Sample speelt af
    AANGEKOMEN BIJ einde Loop-gedeelte : CurrentPlayPosition wordt terug gezet naar begin loop-gedeelte
    TOETS LOSLAAT : CurrentPlayPositoin wordt geset naar einde loop-gedeelte en de buffer speelt de sample verder af totdat deze afgelopen is. (nagalm stukje)


    Ik heb zelf al bedacht om per sample 3 buffers te gebruiken, en het loopgedeelte in de middelste buffer te stoppen. Als ik ze dan achter elkaar afspeel blijkt er geen fatsoenlijke
    loop te makne zijn, je hoort de klikjes van de overgangen. het verwisselen van de Current Playing Buffer kost teveel tijd, enkele milliseconden zelfs.

    Nu wil ik het dus binnen 1 sample houden en met setCurrentPlayPosition doen. Maar ook nu hoor ik klikjes. Ik denk dat het aan mijn manier ligt van 'detecteren' wanneer currentPlayPosition gelijk is aan L2 (einde loopgedeelte), ik gebruik Sleep(ms: integer) en
    die werkt maar tot op de millisec oftewel met 1000 hertz. en ik vrees dat ik een hogere triggerfrequentie nodig heb, de sample speelt immers af met 44100 hertz.

    Ik hoop dat jullie mij kunnen helpen om dit probleem op te lossen !

    [Mijn (Delphi3) code:]
    ——————————————————————————
    // i:\testsamp.wav loopgedeelte (splwaarden): 35319 - 51621

    samplesPerSecond := lpwfxFormat.nSamplesPerSec;

    // channels en bits/spl opvragen om te kunnen converteren van
    // sampleNRs(in de editboxen) naar byteNRs.
    multiplyier := lpwfxFormat.nChannels * lpwfxFormat.wBitsPerSample div 8;
    [/quote:a5174a2b98]
    [quote:a5174a2b98="musicom76"]
    aantalkeren := strtoint(edit_loopaantal.Text);

    //beginpunt loop
    L1 := StrToInt(edit_from.Text);// * multiplyier; // conv sampNR naar byteNR
    //eindpunt loop
    L2 := StrToInt(edit_to.Text);// * multiplyier;

    //wat onhandig maar goed…
    // sleeptime1 = tijd in ms van begin tot begin loop-gedeelte
    // sleeptime2 = tijd in ms van begin loop-gedeelte tot eind loop-gedeelte
    exsleeptime1 := (1000 * L1) / samplesPerSecond; // in millisec
    exsleeptime2 := (1000 * (L2-L1)) / samplesPerSecond; // in millisec
    strsleeptime1 := FloatToStr(exsleeptime1);
    strsleeptime2 := FloatToStr(exsleeptime2);
    intsleeptime1 := StrToInt(Copy(strsleeptime1, 1, Pos(',', strsleeptime1)-1));
    intsleeptime2 := StrToInt(Copy(strsleeptime2, 1, Pos(',', strsleeptime2)-1));
    [/quote:a5174a2b98]
    [img:a5174a2b98]http://forum.fok.nl/i/s/nooo.gif[/img:a5174a2b98]
    [quote:a5174a2b98="musicom76"]

    // zet de buffer aan het spelen
    buffer.SetCurrentPosition(0);
    buffer.play(0,0,0);

    // speel 1e deel sample
    sleep(intsleeptime1); // in millisec

    if aantalkeren = 1 then
    begin
    // 2e (LOOP-) deel sample
    Log1('Playing 2nd (LOOP-) part');
    sleep(intsleeptime2); // in millisec
    Log2('Done');
    end else
    [/quote:a5174a2b98]
    [quote:a5174a2b98="musicom76"]
    for i := 1 to aantalkeren-1 do
    begin
    // 2e (LOOP-) deel sample
    sleep(intsleeptime2); // in millisec
    buffer.SetCurrentPosition(L1*Multiplyier);
    buffer.getCurrentPosition(dwCurrentPlayCursor, lpdwCurrentWriteCursor);
    end;
    [/quote:a5174a2b98]
    [img:a5174a2b98]http://forum.fok.nl/i/s/nooo.gif[/img:a5174a2b98]
    [quote:a5174a2b98="musicom76"]
    // 3e deel sample speelt vanzelf af omdat setCurrentPosition niet meer is aangeroepen.

    end;
    ——————————————————————————[/quote:a5174a2b98]
    Heb je een miniprojectje met de code (en de .wav)?

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.