Recent

Author Topic: [Solved] CoreAudio  (Read 951 times)

Key-Real

  • New Member
  • *
  • Posts: 41
[Solved] CoreAudio
« on: March 27, 2022, 05:48:02 pm »
It plays with annoying noise.

why?



Code: Pascal  [Select][+][-]
  1. {$linkframework CoreAudio}
  2. {$MODE OBJFPC}
  3. uses MacOSAll,CocoaAll,crt;
  4.  
  5.  
  6. type
  7.   TwavHeader = packed record
  8.            
  9.             RIFF:array [0..3] of char;        // RIFF Header Magic header
  10.             ChunkSize:dword;      // RIFF Chunk Size
  11.             WAVE:array [0..3] of char;        // WAVE Header
  12.            
  13.             fmt:array [0..3] of char;         // FMT header
  14.             Subchunk1Size:dword;  // Size of the fmt chunk
  15.             AudioFormat:word;    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
  16.             NumOfChan:word;      // Number of channels 1=Mono 2=Sterio
  17.             SamplesPerSec:dword;  // Sampling Frequency in Hz
  18.             bytesPerSec:dword;    // bytes per second
  19.             blockAlign:word;     // 2=16-bit mono, 4=16-bit stereo
  20.             bitsPerSample:word;  // Number of bits per sample
  21.            
  22.             Subchunk2ID:array [0..3] of char; // "data"  string
  23.             Subchunk2Size:dword;  // Sampled data length
  24.   end;
  25.  
  26.  
  27. var
  28.   wavFile:file;
  29.   wavheader:TwavHeader;
  30.  
  31.  
  32. function audioIOProc(inDevice:AudioObjectID;
  33.                    const inNow:AudioTimeStamp;
  34.                    const inInputData:AudioBufferList;
  35.                    const inInputTime:AudioTimeStamp;
  36.                    var outOutputData:AudioBufferList;
  37.                    const inOutputTime:AudioTimeStamp;
  38.                    inClientData:pointer
  39.                    ):OSStatus;MWPascal;
  40.  
  41.  var
  42.    
  43.     i:dword;
  44.     w:word;
  45.     f:single;
  46.         p:pointer;
  47.  
  48.         buffer:AudioBuffer;
  49.  
  50.         numToRead:dword;
  51.         singleSize:dword;
  52.  
  53.  
  54.  begin  
  55.  
  56.     buffer:=outOutputData.mBuffers[0];
  57.    
  58.    
  59.     numToRead:=buffer.mDataByteSize div sizeof(single);
  60.  
  61.      getmem(p,numToRead);
  62.  
  63.  
  64.           blockread(wavFile,p^,numToRead);
  65.  
  66.           for i:=0 to numToRead div 2 do begin
  67.             w:=pword(p+i*2)^;
  68.             f:=(w / $8000) - 1.0;
  69.             psingle(buffer.mData + i*sizeof(single))^:=f;
  70.           end;
  71.  
  72.  
  73.  
  74.     freemem(p);
  75.  
  76.  
  77.  
  78. result:=noErr;
  79. end;
  80.  
  81.  
  82.  
  83. procedure printCoreAudioErrorAndExit(error:OSStatus);
  84. begin
  85.     if (error <> noErr) then begin
  86.         writeln('Error: ', error);
  87.         halt;
  88.     end;
  89. end;
  90.  
  91.  
  92. var
  93.  
  94. info:AudioObjectPropertyAddress;
  95. err:OSStatus;
  96. propertySize:UInt32;
  97. defaultOutputDevice:AudioObjectID;
  98. procID:AudioDeviceIOProcID;
  99.  
  100. begin  
  101.     randomize;
  102.  
  103.  
  104.  assign(wavFile,'output.wav');
  105.   reset(wavFile,1);
  106.  
  107.   blockread(wavFile,wavHeader,sizeof(Twavheader));
  108.  
  109.   with wavHeader do begin          
  110.     writeln(RIFF[0],RIFF[1],RIFF[2],RIFF[3]);        // RIFF Header Magic header
  111.     writeln('RIFF Chunk Size ',ChunkSize);
  112.     writeln(WAVE[0],WAVE[1],WAVE[2],WAVE[3]);      // WAVE Header
  113.            
  114.     writeln(fmt[0],fmt[1],fmt[2],fmt[3]);         // FMT header
  115.  
  116.     writeln('Size of the fmt chunk ',Subchunk1Size);
  117.     writeln('Audio format ',AudioFormat);    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
  118.     writeln('Number of channels ', NumOfChan);      // Number of channels 1=Mono 2=Sterio
  119.     writeln('Sampling Frequency in Hz ',SamplesPerSec);  // Sampling Frequency in Hz
  120.     writeln('bytes per second ',bytesPerSec);    // bytes per second
  121.     writeln('blockAlign ',blockAlign);     // 2=16-bit mono, 4=16-bit stereo
  122.     writeln('Number of bits per sample ',bitsPerSample);  // Number of bits per sample
  123.            
  124.     writeln(Subchunk2ID[0],Subchunk2ID[1],Subchunk2ID[2],Subchunk2ID[3]); // "data"  string
  125.     writeln('Sampled data length ',Subchunk2Size);  // Sampled data length
  126.   end;
  127.  
  128.    
  129.         info.mSelector := kAudioHardwarePropertyDefaultOutputDevice;
  130.         info.mElement := kAudioObjectPropertyElementMaster;
  131.         info.mScope := kAudioObjectPropertyScopeGlobal;
  132.    
  133.            
  134.  
  135.     err := AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, info, 0, nil, propertySize);
  136.     printCoreAudioErrorAndExit(err);
  137.    
  138.  
  139.     err:= AudioObjectGetPropertyData(kAudioObjectSystemObject, info, 0, nil, propertySize, @defaultOutputDevice);
  140.     printCoreAudioErrorAndExit(err);
  141.    
  142.  
  143.     err := AudioDeviceCreateIOProcID(defaultOutputDevice, @audioIOProc, nil, procID);
  144.     printCoreAudioErrorAndExit(err);
  145.    
  146.     err := AudioDeviceStart(defaultOutputDevice, procID);
  147.     printCoreAudioErrorAndExit(err);
  148.    
  149.     writeln('Press ENTER to stop.');
  150.     readln;
  151.  
  152.     err := AudioDeviceStop(defaultOutputDevice, nil);
  153.     printCoreAudioErrorAndExit(err);
  154.    
  155.     err := AudioDeviceDestroyIOProcID(defaultOutputDevice, procID);
  156.     printCoreAudioErrorAndExit(err);
  157.  
  158.     close(wavFile);
  159. end.
  160.  

my .wav is:
Code: Pascal  [Select][+][-]
  1. RIFF
  2. RIFF Chunk Size 16449624
  3. WAVE
  4. fmt
  5. Size of the fmt chunk 16
  6. Audio format 1
  7. Number of channels 2
  8. Sampling Frequency in Hz 44100
  9. bytes per second 176400
  10. blockAlign 4
  11. Number of bits per sample 16
  12. data
  13. Sampled data length 16449580
  14.  
« Last Edit: April 15, 2022, 02:38:08 pm by Key-Real »

Thaddy

  • Hero Member
  • *****
  • Posts: 11764
Re: CoreAudio
« Reply #1 on: March 27, 2022, 06:23:25 pm »
Yes. Because you do not have the corrects sampling rate.....
Black themes should be banned.

Key-Real

  • New Member
  • *
  • Posts: 41
Re: CoreAudio
« Reply #2 on: March 27, 2022, 06:54:23 pm »
This time I setuped an other test:

Code: Pascal  [Select][+][-]
  1. {$linkframework AudioToolbox}
  2. {$MODE OBJFPC}
  3. uses MacOSAll,CocoaAll,crt;
  4.  
  5. type
  6.  
  7.     TSoundState = packed record
  8.         done:boolean;
  9.     end;
  10.  
  11.  
  12.   TwavHeader = packed record
  13.            
  14.             RIFF:array [0..3] of char;        // RIFF Header Magic header
  15.             ChunkSize:dword;      // RIFF Chunk Size
  16.             WAVE:array [0..3] of char;        // WAVE Header
  17.            
  18.             fmt:array [0..3] of char;         // FMT header
  19.             Subchunk1Size:dword;  // Size of the fmt chunk
  20.             AudioFormat:word;    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
  21.             NumOfChan:word;      // Number of channels 1=Mono 2=Sterio
  22.             SamplesPerSec:dword;  // Sampling Frequency in Hz
  23.             bytesPerSec:dword;    // bytes per second
  24.             blockAlign:word;     // 2=16-bit mono, 4=16-bit stereo
  25.             bitsPerSample:word;  // Number of bits per sample
  26.            
  27.             Subchunk2ID:array [0..3] of char; // "data"  string
  28.             Subchunk2Size:dword;  // Sampled data length
  29.   end;
  30.  
  31.  
  32. var
  33.   wavFile:file;
  34.   wavheader:TwavHeader;
  35.  
  36.  
  37.  
  38.  
  39. procedure auCallback(inUserData:pointer;  queue:AudioQueueRef;  buffer:AudioQueueBufferRef); MWPascal;
  40. var
  41.     SoundState : TSoundState;
  42.     p:pointer;
  43.     numToRead:dword;
  44.     i:dword;
  45.     w:word;
  46.     f:single;
  47.  
  48. begin
  49.    
  50.     SoundState:=TSoundState(inUserData^);
  51.  
  52.     writeln('write');
  53.  
  54.     buffer^.mAudioDataByteSize := 4098;
  55.  
  56.  
  57.  
  58.  
  59.     numToRead:=buffer^.mAudioDataByteSize div sizeof(single) * 2;
  60.  
  61.      getmem(p,numToRead);
  62.  
  63.  
  64.           blockread(wavFile,p^,numToRead);
  65.  
  66.           for i:=0 to numToRead div 2 do begin
  67.             w:=pword(p+i*2)^;
  68.             f:=(w / $8000) - 1;
  69.             psingle(buffer^.mAudioData + i*sizeof(single))^:=f;
  70.           end;
  71.  
  72.  
  73.  
  74.     freemem(p);
  75.  
  76.  
  77.     AudioQueueEnqueueBuffer(queue, buffer, 0, nil);
  78. end;
  79.  
  80. var
  81.     auDesc:AudioStreamBasicDescription;
  82.     auQueue:AudioQueueRef;
  83.     auBuffers:array[0..1] of AudioQueueBufferRef;
  84.     soundState:TSoundState;
  85.     err:OSStatus;
  86.     bufferSize:uint32;
  87. begin
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  assign(wavFile,'unreal.wav');
  94.   reset(wavFile,1);
  95.  
  96.   blockread(wavFile,wavHeader,sizeof(Twavheader));
  97.  
  98.   with wavHeader do begin          
  99.     writeln(RIFF[0],RIFF[1],RIFF[2],RIFF[3]);        // RIFF Header Magic header
  100.     writeln('RIFF Chunk Size ',ChunkSize);
  101.     writeln(WAVE[0],WAVE[1],WAVE[2],WAVE[3]);      // WAVE Header
  102.            
  103.     writeln(fmt[0],fmt[1],fmt[2],fmt[3]);         // FMT header
  104.  
  105.     writeln('Size of the fmt chunk ',Subchunk1Size);
  106.     writeln('Audio format ',AudioFormat);    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
  107.     writeln('Number of channels ', NumOfChan);      // Number of channels 1=Mono 2=Sterio
  108.     writeln('Sampling Frequency in Hz ',SamplesPerSec);  // Sampling Frequency in Hz
  109.     writeln('bytes per second ',bytesPerSec);    // bytes per second
  110.     writeln('blockAlign ',blockAlign);     // 2=16-bit mono, 4=16-bit stereo
  111.     writeln('Number of bits per sample ',bitsPerSample);  // Number of bits per sample
  112.            
  113.     writeln(Subchunk2ID[0],Subchunk2ID[1],Subchunk2ID[2],Subchunk2ID[3]); // "data"  string
  114.     writeln('Sampled data length ',Subchunk2Size);  // Sampled data length
  115.   end;
  116.  
  117.  
  118.     // stereo 16-bit interleaved linear PCM audio data at 48kHz in SNORM format
  119.    
  120.     auDesc.mSampleRate := 48000;
  121.     auDesc.mFormatID := kAudioFormatLinearPCM;
  122.     auDesc.mFormatFlags := kLinearPCMFormatFlagIsBigEndian or kLinearPCMFormatFlagIsSignedInteger or kLinearPCMFormatFlagIsPacked;
  123.     auDesc.mBytesPerPacket := 4;
  124.     auDesc.mFramesPerPacket := 1;
  125.     auDesc.mBytesPerFrame := 4;
  126.     auDesc.mChannelsPerFrame := 2;
  127.     auDesc.mBitsPerChannel := 16;
  128.    
  129.    
  130.     // our persistent state for sound playback
  131.     soundState.done:=false; // 261.6 ~= Middle C frequency
  132.    
  133.     // most of the 0 and nullptr params here are for compressed sound formats etc.
  134.     err := AudioQueueNewOutput(auDesc, @auCallback, @soundState, nil, nil, 0, auQueue);
  135.    
  136.     if err=0 then begin
  137.         // generate buffers holding at most 1/16th of a second of data
  138.         bufferSize := round(auDesc.mBytesPerFrame * (auDesc.mSampleRate / 16));
  139.         err := AudioQueueAllocateBuffer(auQueue, bufferSize, auBuffers[0]);
  140.  
  141.         if err=0 then begin
  142.             err := AudioQueueAllocateBuffer(auQueue, bufferSize, auBuffers[1]);
  143.  
  144.             if err=0 then begin
  145.                 // prime the buffers
  146.                 auCallback(@soundState, auQueue, auBuffers[0]);
  147.                 auCallback(@soundState, auQueue, auBuffers[1]);
  148.  
  149.                 // enqueue for playing
  150.                 AudioQueueEnqueueBuffer(auQueue, auBuffers[0], 0, nil);
  151.                 AudioQueueEnqueueBuffer(auQueue, auBuffers[1], 0, nil);
  152.  
  153.                 // go!
  154.                 AudioQueueStart(auQueue, nil);
  155.             end;
  156.         end;
  157.     end;
  158.  
  159.     // Our AudioQueue creation options put the CA handling on its own thread
  160.     // so this is a quick hack to allow us to hear some sound.
  161.  
  162.  
  163.     readln;
  164.    
  165.  
  166.     // be nice even it doesn't really matter at this point
  167.  
  168.     AudioQueueDispose(auQueue, true);
  169. end.
  170.  

now I can setup the sampling rate and stuff.

it is better now, but I hear the sound only on the right speaker, and the sound is not 100% correct

My new File is 48000 sampling rate


pls hip
« Last Edit: March 27, 2022, 07:12:11 pm by Key-Real »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1983
  • Former Delphi 1-7, 10.2 user
Re: CoreAudio
« Reply #3 on: March 28, 2022, 12:59:40 am »
To play *.wav files, see my Wiki article macOS Audio Playter using the Apple AVFoundation framework which is more high level than CoreAudio.
Lazarus 2.3, FPC 3.3.1 macOS 12.3.1 x86_64 Xcode 13.4
Lazarus 2.3, FPC 3.3.1 macOS 12.3.1 aarch64 Xcode 13.4

Key-Real

  • New Member
  • *
  • Posts: 41
Re: CoreAudio
« Reply #4 on: March 28, 2022, 06:33:59 am »
I don't wanna just Play a .WAV. It is a Test for writing in to the Buffer. I Chose a .WAV to have valid Data.
« Last Edit: March 28, 2022, 06:42:54 am by Key-Real »

Key-Real

  • New Member
  • *
  • Posts: 41
Re: CoreAudio
« Reply #5 on: March 29, 2022, 11:47:26 am »
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

  • New Member
  • *
  • Posts: 41
Re: CoreAudio
« Reply #6 on: April 03, 2022, 02:47:58 pm »
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  [Select][+][-]
  1. {$linkframework AudioToolbox}
  2. {$MODE OBJFPC}
  3. uses MacOSAll,CocoaAll,crt;
  4.  
  5. type
  6.  
  7.     TSoundState = packed record
  8.         done:boolean;
  9.     end;
  10.  
  11.  
  12.   TwavHeader = packed record
  13.            
  14.             RIFF:array [0..3] of char;        // RIFF Header Magic header
  15.             ChunkSize:dword;      // RIFF Chunk Size
  16.             WAVE:array [0..3] of char;        // WAVE Header
  17.            
  18.             fmt:array [0..3] of char;         // FMT header
  19.             Subchunk1Size:dword;  // Size of the fmt chunk
  20.             AudioFormat:word;    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
  21.             NumOfChan:word;      // Number of channels 1=Mono 2=Sterio
  22.             SamplesPerSec:dword;  // Sampling Frequency in Hz
  23.             bytesPerSec:dword;    // bytes per second
  24.             blockAlign:word;     // 2=16-bit mono, 4=16-bit stereo
  25.             bitsPerSample:word;  // Number of bits per sample
  26.            
  27.             Subchunk2ID:array [0..3] of char; // "data"  string
  28.             Subchunk2Size:dword;  // Sampled data length
  29.   end;
  30.  
  31.  
  32. var
  33.   wavFile:file;
  34.   wavheader:TwavHeader;
  35.  
  36.  
  37.  
  38.  
  39. procedure auCallback(inUserData:pointer;  queue:AudioQueueRef;  buffer:AudioQueueBufferRef); MWPascal;
  40. var
  41.     SoundState : TSoundState;
  42.     p:pointer;
  43.     numToRead:dword;
  44.     i:dword;
  45.     w:word;
  46.     f:single;
  47.     int:integer;
  48. begin
  49.    
  50.     SoundState:=TSoundState(inUserData^);
  51.  
  52.     buffer^.mAudioDataByteSize := 1024*4;
  53.  
  54.     numToRead:=buffer^.mAudioDataByteSize div sizeof(single) * 2;
  55.  
  56.      getmem(p,numToRead);
  57.  
  58.  
  59.           blockread(wavFile,p^,numToRead);
  60.  
  61.  
  62.  
  63.           for i:=0 to numToRead div 2 do begin
  64.             w:=pword(p+i*2)^;
  65.             f:=(w / $8000) - 1;
  66.             psingle(buffer^.mAudioData + i*sizeof(single))^:=f;
  67.  
  68.           end;
  69.  
  70.  
  71.  
  72.     freemem(p);
  73.  
  74.  
  75.     AudioQueueEnqueueBuffer(queue, buffer, 0, nil);
  76. end;
  77.  
  78. procedure checkError(error:OSStatus);
  79. begin
  80.     if (error <> noErr) then begin
  81.         writeln('Error: ', error);
  82.         halt;
  83.     end;
  84. end;
  85.  
  86.  
  87. var
  88.     auDesc:AudioStreamBasicDescription;
  89.     auQueue:AudioQueueRef;
  90.     auBuffers:array[0..1] of AudioQueueBufferRef;
  91.     soundState:TSoundState;
  92.     err:OSStatus;
  93.     bufferSize:uint32;
  94. begin
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  assign(wavFile,'unreal.wav');
  101.   reset(wavFile,1);
  102.  
  103.   blockread(wavFile,wavHeader,sizeof(Twavheader));
  104.  
  105.   with wavHeader do begin          
  106.     writeln(RIFF[0],RIFF[1],RIFF[2],RIFF[3]);        // RIFF Header Magic header
  107.     writeln('RIFF Chunk Size ',ChunkSize);
  108.     writeln(WAVE[0],WAVE[1],WAVE[2],WAVE[3]);      // WAVE Header
  109.            
  110.     writeln(fmt[0],fmt[1],fmt[2],fmt[3]);         // FMT header
  111.  
  112.     writeln('Size of the fmt chunk ',Subchunk1Size);
  113.     writeln('Audio format ',AudioFormat);    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
  114.     writeln('Number of channels ', NumOfChan);      // Number of channels 1=Mono 2=Sterio
  115.     writeln('Sampling Frequency in Hz ',SamplesPerSec);  // Sampling Frequency in Hz
  116.     writeln('bytes per second ',bytesPerSec);    // bytes per second
  117.     writeln('blockAlign ',blockAlign);     // 2=16-bit mono, 4=16-bit stereo
  118.     writeln('Number of bits per sample ',bitsPerSample);  // Number of bits per sample
  119.            
  120.     writeln(Subchunk2ID[0],Subchunk2ID[1],Subchunk2ID[2],Subchunk2ID[3]); // "data"  string
  121.     writeln('Sampled data length ',Subchunk2Size);  // Sampled data length
  122.   end;
  123.  
  124.  
  125.     // stereo 16-bit interleaved linear PCM audio data at 48kHz in SNORM format
  126.  
  127.     auDesc.mSampleRate := wavHeader.SamplesPerSec;
  128.     auDesc.mFormatID := kAudioFormatLinearPCM;
  129.     auDesc.mFormatFlags := kLinearPCMFormatFlagIsFloat or kLinearPCMFormatFlagIsPacked;
  130.  
  131.     auDesc.mBytesPerPacket := 8;
  132.     auDesc.mFramesPerPacket := 1;
  133.     auDesc.mBytesPerFrame := 8;
  134.     auDesc.mChannelsPerFrame := 2;
  135.     auDesc.mBitsPerChannel := 32;
  136.  
  137.   {  
  138.     auDesc.mSampleRate := 48000;
  139.     auDesc.mFormatID := kAudioFormatLinearPCM;
  140.     auDesc.mFormatFlags := kLinearPCMFormatFlagIsBigEndian or kLinearPCMFormatFlagIsSignedInteger or kLinearPCMFormatFlagIsPacked;
  141.     auDesc.mBytesPerPacket := 4;
  142.     auDesc.mFramesPerPacket := 1;
  143.     auDesc.mBytesPerFrame := 4;
  144.     auDesc.mChannelsPerFrame := 2;
  145.     auDesc.mBitsPerChannel := 16;
  146.  }  
  147.    
  148.     // our persistent state for sound playback
  149.     soundState.done:=false;
  150.    
  151.     // most of the 0 and nullptr params here are for compressed sound formats etc.
  152.     err := AudioQueueNewOutput(auDesc, @auCallback, @soundState, nil, nil, 0, auQueue);
  153.     checkError(err);
  154.  
  155.  
  156.     // generate buffers holding at most 1/16th of a second of data
  157.     bufferSize := round(auDesc.mBytesPerFrame * (auDesc.mSampleRate / 16));
  158.     err := AudioQueueAllocateBuffer(auQueue, bufferSize, auBuffers[0]);
  159.     checkError(err);
  160.  
  161.     err := AudioQueueAllocateBuffer(auQueue, bufferSize, auBuffers[1]);
  162.     checkError(err);
  163.  
  164.     // prime the buffers
  165.     auCallback(@soundState, auQueue, auBuffers[0]);
  166.     auCallback(@soundState, auQueue, auBuffers[1]);
  167.  
  168.     // enqueue for playing
  169.     AudioQueueEnqueueBuffer(auQueue, auBuffers[0], 0, nil);
  170.     AudioQueueEnqueueBuffer(auQueue, auBuffers[1], 0, nil);
  171.  
  172.     // go!
  173.     AudioQueueStart(auQueue, nil);
  174.  
  175.  
  176.  
  177.     // Our AudioQueue creation options put the CA handling on its own thread
  178.     // so this is a quick hack to allow us to hear some sound.
  179.  
  180.  
  181.     readln;
  182.    
  183.  
  184.     // be nice even it doesn't really matter at this point
  185.  
  186.     AudioQueueDispose(auQueue, true);
  187. end.
  188.  


how to edit this code to play on both channels?

AL

  • Full Member
  • ***
  • Posts: 230
Re: CoreAudio
« Reply #7 on: April 10, 2022, 05:21:15 am »
Try this:

          auDesc.mBytesPerPacket  := auDesc.mChannelsPerFrame * sizeof (int32);    (your bit per channel)
          auDescmBytesPerFrame    := auDesc.mChannelsPerFrame * sizeof (int32);   
Laz 2.1.0, fpc 3.3.1, Win10
Laz 2.1.0, fpc 3.3.1, Mac OS Mojave running on VMWare
Laz 2.1.0  fpc 3.3.1 Ubuntu 20.04

Key-Real

  • New Member
  • *
  • Posts: 41
Re: CoreAudio
« Reply #8 on: April 15, 2022, 02:37:51 pm »
If yo wanna floating point format:


Code: Pascal  [Select][+][-]
  1. var
  2.    
  3.     i:dword;
  4.     w:int16;
  5.     f:single;
  6.         p:pointer;
  7.  
  8.         buffer:AudioBuffer;
  9.  
  10.         numToRead:dword;
  11.         singleSize:dword;
  12.  begin  
  13.  
  14.     buffer:=outOutputData.mBuffers[0];
  15.     buffer.mDataByteSize:=1024;
  16.    
  17.     numToRead:=buffer.mDataByteSize div sizeof(single) * 2;
  18.  
  19.      getmem(p,numToRead);
  20.  
  21.  
  22.           blockread(wavFile,p^,numToRead);
  23.  
  24.           for i:=0 to numToRead div 2 do begin
  25.          
  26.             w:=pint16(p+i*2)^;
  27.             f:=(w / $8000);
  28.             psingle(buffer.mData + i*sizeof(single))^:=f;
  29.           end;
  30.  
  31.  
  32.  
  33.     freemem(p);
  34.  
  35.  
  36.  


If you wanna signed integer format:

Code: Pascal  [Select][+][-]
  1.  
  2. procedure auCallback(inUserData:pointer;  queue:AudioQueueRef;  buffer:AudioQueueBufferRef); MWPascal;
  3. var
  4.     SoundState : TSoundState;
  5.     p:pointer;
  6.     numToRead:dword;
  7.     i:dword;
  8.     w:int16;
  9.     f:single;
  10.     int:integer;
  11. begin
  12.    
  13.     SoundState:=TSoundState(inUserData^);
  14.  
  15.  
  16.     buffer^.mAudioDataByteSize := 1024*4;
  17.    
  18.     numToRead := buffer^.mAudioDataByteSize;
  19.  
  20.     getmem(p,numToRead);
  21.  
  22.  
  23.     blockread(wavFile,buffer^.mAudioData^,numToRead);
  24.      
  25.  
  26.  
  27.     freemem(p);
  28.  
  29.     AudioQueueEnqueueBuffer(queue, buffer, 0, nil);
  30.  
  31. end;
  32.  



Code: [Select]

    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;

 

TinyPortal © 2005-2018