Forum > Cocoa

[Solved] CoreAudio

<< < (2/2)

Key-Real:
I have Music Engine for win and linux. No i'm using mac and wanna port this project to macOS. I have a mixer. It writes to a sound buffer. I'm looking for the best way to implement the device driver. The second test was by far the better way I could find on the net.

Key-Real:
Now I think I play only on one channel. This could explain the annoying noice. The sound is now in the correct key. This could mean the sample rate is correct now.



--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$linkframework AudioToolbox}{$MODE OBJFPC}uses MacOSAll,CocoaAll,crt; type     TSoundState = packed record        done:boolean;    end;    TwavHeader = packed record                        RIFF:array [0..3] of char;        // RIFF Header Magic header            ChunkSize:dword;      // RIFF Chunk Size            WAVE:array [0..3] of char;        // WAVE Header                        fmt:array [0..3] of char;         // FMT header            Subchunk1Size:dword;  // Size of the fmt chunk            AudioFormat:word;    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM            NumOfChan:word;      // Number of channels 1=Mono 2=Sterio            SamplesPerSec:dword;  // Sampling Frequency in Hz            bytesPerSec:dword;    // bytes per second            blockAlign:word;     // 2=16-bit mono, 4=16-bit stereo            bitsPerSample:word;  // Number of bits per sample                        Subchunk2ID:array [0..3] of char; // "data"  string            Subchunk2Size:dword;  // Sampled data length  end;  var  wavFile:file;  wavheader:TwavHeader;    procedure auCallback(inUserData:pointer;  queue:AudioQueueRef;  buffer:AudioQueueBufferRef); MWPascal;var    SoundState : TSoundState;    p:pointer;    numToRead:dword;    i:dword;    w:word;    f:single;    int:integer;begin        SoundState:=TSoundState(inUserData^);     buffer^.mAudioDataByteSize := 1024*4;     numToRead:=buffer^.mAudioDataByteSize div sizeof(single) * 2;      getmem(p,numToRead);            blockread(wavFile,p^,numToRead);             for i:=0 to numToRead div 2 do begin            w:=pword(p+i*2)^;            f:=(w / $8000) - 1;            psingle(buffer^.mAudioData + i*sizeof(single))^:=f;           end;        freemem(p);      AudioQueueEnqueueBuffer(queue, buffer, 0, nil);end; procedure checkError(error:OSStatus);begin    if (error <> noErr) then begin        writeln('Error: ', error);        halt;    end;end;  var    auDesc:AudioStreamBasicDescription;    auQueue:AudioQueueRef;    auBuffers:array[0..1] of AudioQueueBufferRef;    soundState:TSoundState;    err:OSStatus;    bufferSize:uint32;begin      assign(wavFile,'unreal.wav');  reset(wavFile,1);   blockread(wavFile,wavHeader,sizeof(Twavheader));   with wavHeader do begin              writeln(RIFF[0],RIFF[1],RIFF[2],RIFF[3]);        // RIFF Header Magic header    writeln('RIFF Chunk Size ',ChunkSize);    writeln(WAVE[0],WAVE[1],WAVE[2],WAVE[3]);      // WAVE Header                writeln(fmt[0],fmt[1],fmt[2],fmt[3]);         // FMT header     writeln('Size of the fmt chunk ',Subchunk1Size);    writeln('Audio format ',AudioFormat);    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM    writeln('Number of channels ', NumOfChan);      // Number of channels 1=Mono 2=Sterio    writeln('Sampling Frequency in Hz ',SamplesPerSec);  // Sampling Frequency in Hz    writeln('bytes per second ',bytesPerSec);    // bytes per second    writeln('blockAlign ',blockAlign);     // 2=16-bit mono, 4=16-bit stereo    writeln('Number of bits per sample ',bitsPerSample);  // Number of bits per sample                writeln(Subchunk2ID[0],Subchunk2ID[1],Subchunk2ID[2],Subchunk2ID[3]); // "data"  string    writeln('Sampled data length ',Subchunk2Size);  // Sampled data length  end;      // stereo 16-bit interleaved linear PCM audio data at 48kHz in SNORM format     auDesc.mSampleRate := wavHeader.SamplesPerSec;    auDesc.mFormatID := kAudioFormatLinearPCM;    auDesc.mFormatFlags := kLinearPCMFormatFlagIsFloat or kLinearPCMFormatFlagIsPacked;     auDesc.mBytesPerPacket := 8;    auDesc.mFramesPerPacket := 1;    auDesc.mBytesPerFrame := 8;    auDesc.mChannelsPerFrame := 2;    auDesc.mBitsPerChannel := 32;   {      auDesc.mSampleRate := 48000;    auDesc.mFormatID := kAudioFormatLinearPCM;    auDesc.mFormatFlags := kLinearPCMFormatFlagIsBigEndian or kLinearPCMFormatFlagIsSignedInteger or kLinearPCMFormatFlagIsPacked;    auDesc.mBytesPerPacket := 4;    auDesc.mFramesPerPacket := 1;    auDesc.mBytesPerFrame := 4;    auDesc.mChannelsPerFrame := 2;    auDesc.mBitsPerChannel := 16; }           // our persistent state for sound playback    soundState.done:=false;         // most of the 0 and nullptr params here are for compressed sound formats etc.    err := AudioQueueNewOutput(auDesc, @auCallback, @soundState, nil, nil, 0, auQueue);    checkError(err);      // generate buffers holding at most 1/16th of a second of data    bufferSize := round(auDesc.mBytesPerFrame * (auDesc.mSampleRate / 16));    err := AudioQueueAllocateBuffer(auQueue, bufferSize, auBuffers[0]);    checkError(err);     err := AudioQueueAllocateBuffer(auQueue, bufferSize, auBuffers[1]);    checkError(err);     // prime the buffers    auCallback(@soundState, auQueue, auBuffers[0]);    auCallback(@soundState, auQueue, auBuffers[1]);     // enqueue for playing    AudioQueueEnqueueBuffer(auQueue, auBuffers[0], 0, nil);    AudioQueueEnqueueBuffer(auQueue, auBuffers[1], 0, nil);     // go!    AudioQueueStart(auQueue, nil);       // Our AudioQueue creation options put the CA handling on its own thread    // so this is a quick hack to allow us to hear some sound.      readln;         // be nice even it doesn't really matter at this point     AudioQueueDispose(auQueue, true);end. 

how to edit this code to play on both channels?

AL:
Try this:

          auDesc.mBytesPerPacket  := auDesc.mChannelsPerFrame * sizeof (int32);    (your bit per channel)
          auDescmBytesPerFrame    := auDesc.mChannelsPerFrame * sizeof (int32);   

Key-Real:
If yo wanna floating point format:



--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var       i:dword;    w:int16;    f:single;        p:pointer;         buffer:AudioBuffer;         numToRead:dword;        singleSize:dword; begin        buffer:=outOutputData.mBuffers[0];    buffer.mDataByteSize:=1024;        numToRead:=buffer.mDataByteSize div sizeof(single) * 2;      getmem(p,numToRead);            blockread(wavFile,p^,numToRead);           for i:=0 to numToRead div 2 do begin                      w:=pint16(p+i*2)^;            f:=(w / $8000);            psingle(buffer.mData + i*sizeof(single))^:=f;          end;        freemem(p);    

If you wanna signed integer format:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- procedure auCallback(inUserData:pointer;  queue:AudioQueueRef;  buffer:AudioQueueBufferRef); MWPascal;var    SoundState : TSoundState;    p:pointer;    numToRead:dword;    i:dword;    w:int16;    f:single;    int:integer;begin        SoundState:=TSoundState(inUserData^);      buffer^.mAudioDataByteSize := 1024*4;        numToRead := buffer^.mAudioDataByteSize;     getmem(p,numToRead);       blockread(wavFile,buffer^.mAudioData^,numToRead);           freemem(p);     AudioQueueEnqueueBuffer(queue, buffer, 0, nil); end; 



--- Code: ---
    auDesc.mSampleRate := wavHeader.SamplesPerSec;
    auDesc.mFormatID := kAudioFormatLinearPCM;
    auDesc.mFormatFlags := kLinearPCMFormatFlagIsSignedInteger or kLinearPCMFormatFlagIsPacked;
    auDesc.mBytesPerPacket := 4;
    auDesc.mFramesPerPacket := 1;
    auDesc.mBytesPerFrame := 4;
    auDesc.mChannelsPerFrame := 2;
    auDesc.mBitsPerChannel := 16;

--- End code ---

Navigation

[0] Message Index

[*] Previous page

Go to full version