Du bist nicht angemeldet.

Werbeanzeige

1

09.04.2022, 16:05

CoreAudio

Hi, ich möchte mit CoreAudio in den Buffer schreiben. Zum Test lade ich eine .wav um korrekte Daten zum schreiben zu haben.
Allerdings gelingt mir das nicht richtig. Er spielt mir ein störendes Geräusch zwischen dem .wav

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
#include <AudioToolbox/AudioToolbox.h>

FILE *fp;

typedef struct TwavHeader{
            
    char RIFF[4];
    uint32_t RIFFChunkSize;
    char WAVE[4];
            
    char fmt[4];
    uint32_t Subchunk1Size;
    uint16_t AudioFormat;
    uint16_t NumOfChan;
    uint32_t SamplesPerSec;
    uint32_t bytesPerSec;
    uint16_t blockAlign;
    uint16_t bitsPerSample;
            
    char Subchunk2ID[4];
    uint32_t Subchunk2Size;
}TwavHeader;



typedef struct SoundState {
    bool done;
}SoundState;


void auCallback(void *inUserData, AudioQueueRef queue, AudioQueueBufferRef buffer) {
  
    
    buffer->mAudioDataByteSize = 1024*4;
    
    int numToRead = buffer->mAudioDataByteSize / sizeof(float) * 2;

    void *p = malloc(numToRead);

    fread(p, numToRead,1,fp);
     

    void *myBuf = buffer->mAudioData;


    for (int i=0; i < numToRead / 2; i++) {
       uint16_t w = *(uint16_t *)&(p[i*sizeof(uint16_t)]);
       
            float f = ((float)w / (float)0x8000) - 1.0;
        *(float *)&(myBuf[i*sizeof(float)]) = f;
    }
    

    free(p);
    AudioQueueEnqueueBuffer(queue, buffer, 0, 0);
}

void checkError(OSStatus error){
    if (error != noErr) {
        printf("Error: %d", error);
        exit(error);
    }
}

int main(int argc, const char * argv[]) {
    
    printf("START\n");
    
    TwavHeader theHeader;

    
    fp = fopen("/Users/kirillkranz/Documents/mytralala-code/CoreAudioTest/unreal.wav", "r");
    fread(&theHeader, sizeof(TwavHeader),1,fp);
    
    printf("%i\n",theHeader.bitsPerSample);
    
    
    
    
    

    AudioStreamBasicDescription auDesc =  {};
    
    auDesc.mSampleRate = theHeader.SamplesPerSec;
    auDesc.mFormatID = kAudioFormatLinearPCM;
    auDesc.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked;
    auDesc.mBytesPerPacket = 8;
    auDesc.mFramesPerPacket = 1;
    auDesc.mBytesPerFrame = 8;
    auDesc.mChannelsPerFrame = 2;
    auDesc.mBitsPerChannel = 32;
    
    
    
    AudioQueueRef auQueue = 0;
    AudioQueueBufferRef auBuffers[2] ={};
    
    // our persistent state for sound playback
    SoundState soundState=  {};
    soundState.done=false;
    
    
    OSStatus err;

    // most of the 0 and nullptr params here are for compressed sound formats etc.
    err = AudioQueueNewOutput(&auDesc, &auCallback, &soundState, 0, 0, 0, &auQueue);
    checkError(err);
    
    // generate buffers holding at most 1/16th of a second of data
    uint32_t bufferSize = 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, 0);
    AudioQueueEnqueueBuffer(auQueue, auBuffers[1], 0, 0);

    // go!
    AudioQueueStart(auQueue, 0);
            
    
    
    
    char rxChar[10]; scanf( "%s", &rxChar);
    printf("FINISH");
    
    fclose(fp);
    // be nice even it doesn't really matter at this point
    if (auQueue)
        AudioQueueDispose(auQueue, true);
}

ist unter Xcode ohne Änderungen kompilieren.



was mache ich falsch?

Schrompf

Alter Hase

Beiträge: 1 460

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

2

09.04.2022, 17:01

Puh, gute Frage. Keine Ahnung, was diese AudioQueue-Funktionen tun, aber der Rest des Codes:
- Deine Umrechnung in Float nimmt an, dass die Samples uint16 sind, also bei 0x8000 die Nullstelle ist. Ich kenne das als int16, also Nullstelle bei 0 und -1 bei -32768 und +1 bei +32767.
- Deine audioDescription.mBytesPerPacket ist 8? Auf StackOverflow schreibst Du, Du würdest Mono senden. Ein float ist nur 4 Byte groß. Die audioDescription beschreibt aber Stereo?

und unabhängig vom Thema:
- Du machst Zeiger-Arithmetik auf void*... wusste gar nicht, dass das erlaubt ist :-)
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

3

15.04.2022, 14:44

Jetzt!

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
#include <AudioToolbox/AudioToolbox.h>

FILE *fp;

typedef struct TwavHeader{
            
    char RIFF[4];
    uint32_t RIFFChunkSize;
    char WAVE[4];
            
    char fmt[4];
    uint32_t Subchunk1Size;
    uint16_t AudioFormat;
    uint16_t NumOfChan;
    uint32_t SamplesPerSec;
    uint32_t bytesPerSec;
    uint16_t blockAlign;
    uint16_t bitsPerSample;
            
    char Subchunk2ID[4];
    uint32_t Subchunk2Size;
}TwavHeader;



typedef struct SoundState {
    bool done;
}SoundState;


void auCallback(void *inUserData, AudioQueueRef queue, AudioQueueBufferRef buffer) {
  
    
    buffer->mAudioDataByteSize = 1024*4;
    
    int numToRead = buffer->mAudioDataByteSize / sizeof(float)*2;

    void *p = malloc(numToRead);

    fread(p, numToRead,1,fp);
     

    void *myBuf = buffer->mAudioData;


    for (int i=0; i < numToRead / 2; i++) {
       int16_t w = *(int16_t *)&(p[i*sizeof(int16_t)]);
       
        
            float f = ((float)w / (float)0x8000);
        *(float *)&(myBuf[i*sizeof(float)]) = f;
    }
    

    free(p);
    AudioQueueEnqueueBuffer(queue, buffer, 0, 0);
}

void checkError(OSStatus error){
    if (error != noErr) {
        printf("Error: %d", error);
        exit(error);
    }
}

int main(int argc, const char * argv[]) {
    
    printf("START\n");

    
    
    
    
    
    TwavHeader theHeader;

    
    fp = fopen("/Users/kirillkranz/Documents/mytralala-code/CoreAudioTest/unreal.wav", "r");
    fread(&theHeader, sizeof(TwavHeader),1,fp);
    
    printf("%i\n",theHeader.bitsPerSample);
    
    
    
    
    

    AudioStreamBasicDescription auDesc =  {};
    
    auDesc.mSampleRate = theHeader.SamplesPerSec;
    auDesc.mFormatID = kAudioFormatLinearPCM;
    auDesc.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked;
    auDesc.mBytesPerPacket = 8;
    auDesc.mFramesPerPacket = 1;
    auDesc.mBytesPerFrame = 8;
    auDesc.mChannelsPerFrame = 2;
    auDesc.mBitsPerChannel = 32;
    
    
    
    AudioQueueRef auQueue = 0;
    AudioQueueBufferRef auBuffers[2] ={};
    
    // our persistent state for sound playback
    SoundState soundState=  {};
    soundState.done=false;
    
    
    OSStatus err;

    // most of the 0 and nullptr params here are for compressed sound formats etc.
    err = AudioQueueNewOutput(&auDesc, &auCallback, &soundState, 0, 0, 0, &auQueue);
    checkError(err);
    
    // generate buffers holding at most 1/16th of a second of data
    uint32_t bufferSize = 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, 0);
    AudioQueueEnqueueBuffer(auQueue, auBuffers[1], 0, 0);

    // go!
    AudioQueueStart(auQueue, 0);
            
    
    
    
    char rxChar[10]; scanf( "%s", &rxChar);
    printf("FINISH");
    
    fclose(fp);
    // be nice even it doesn't really matter at this point
    if (auQueue)
        AudioQueueDispose(auQueue, true);
}

David Scherfgen

Administrator

Beiträge: 10 370

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

16.04.2022, 22:48

Was meinst du mit „Jetzt!“?
Problem gelöst?

5

26.07.2022, 13:01

Ja, ich habe es rausgefunden und gepostet

Werbeanzeige