Created
April 8, 2021 10:15
-
-
Save saivert/c8168ed82a2f5e26eab88c893ab5133a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Excerpt from my client code. bits that calls pw_stream_connect | |
| static int ddbpw_set_spec(ddb_waveformat_t *fmt) | |
| { | |
| memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t)); | |
| if (!plugin.fmt.channels) { | |
| // generic format | |
| plugin.fmt.bps = 16; | |
| plugin.fmt.is_float = 0; | |
| plugin.fmt.channels = 2; | |
| plugin.fmt.samplerate = 44100; | |
| plugin.fmt.channelmask = 3; | |
| } | |
| if (plugin.fmt.samplerate > 192000) { | |
| plugin.fmt.samplerate = 192000; | |
| } | |
| trace ("format %dbit %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask); | |
| const struct spa_pod *params[2]; | |
| enum spa_audio_format pwfmt; | |
| switch (fmt->bps) { | |
| case 8: | |
| pwfmt = SPA_AUDIO_FORMAT_S8; | |
| break; | |
| case 16: | |
| pwfmt = SPA_AUDIO_FORMAT_S16_LE; | |
| break; | |
| case 24: | |
| pwfmt = SPA_AUDIO_FORMAT_S24_LE; | |
| break; | |
| case 32: | |
| if (fmt->is_float) { | |
| pwfmt = SPA_AUDIO_FORMAT_F32_LE; | |
| } | |
| else { | |
| pwfmt = SPA_AUDIO_FORMAT_S32_LE; | |
| } | |
| break; | |
| default: | |
| pwfmt = SPA_AUDIO_FORMAT_UNKNOWN; | |
| }; | |
| uint8_t buffer[1024]; | |
| struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); | |
| struct spa_audio_info_raw rawinfo = SPA_AUDIO_INFO_RAW_INIT( | |
| .format = pwfmt, | |
| .channels = fmt->channels, | |
| .rate = fmt->samplerate ); | |
| set_channel_map(fmt->channels, &rawinfo); | |
| params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &rawinfo); | |
| struct spa_pod_frame f[2]; | |
| float vols[SPA_AUDIO_MAX_CHANNELS], plvol; | |
| int i; | |
| spa_pod_builder_push_object(&b, &f[0], | |
| SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); | |
| spa_pod_builder_add(&b, | |
| SPA_PROP_volume, SPA_POD_Float(1.0f), | |
| SPA_PROP_mute, SPA_POD_Bool(0.0f), | |
| 0); | |
| spa_pod_builder_prop(&b, SPA_PROP_channelVolumes, 0); | |
| if (1/* plugin.has_volume */) { | |
| plvol = deadbeef->volume_get_amp(); | |
| } else { | |
| plvol = 1.0f; | |
| } | |
| for (i = 0; i < fmt->channels; i++) { | |
| vols[i] = plvol; | |
| } | |
| spa_pod_builder_array(&b, sizeof(float), SPA_TYPE_Float, | |
| fmt->channels, vols); | |
| spa_pod_builder_prop(&b, SPA_PROP_channelMap, 0); | |
| spa_pod_builder_array(&b, sizeof(uint32_t), SPA_TYPE_Id, | |
| rawinfo.channels, rawinfo.position); | |
| params[1] = spa_pod_builder_pop(&b, &f[0]); | |
| spa_debug_pod(2, NULL, params[0]); | |
| spa_debug_pod(2, NULL, params[1]); | |
| if (0 != pw_stream_connect(data.stream, | |
| PW_DIRECTION_OUTPUT, | |
| PW_ID_ANY, | |
| PW_STREAM_FLAG_AUTOCONNECT | | |
| PW_STREAM_FLAG_MAP_BUFFERS | | |
| PW_STREAM_FLAG_RT_PROCESS, | |
| params, 2)) { | |
| log_err("PipeWire: Error connecting stream!\n"); | |
| if (pw_properties_get(pw_stream_get_properties(data.stream), PW_KEY_REMOTE_NAME)) { | |
| log_err("PipeWire: Please check if remote daemon name is valid and daemon is up.\n") | |
| } | |
| return -1; | |
| }; | |
| state = DDB_PLAYBACK_STATE_PLAYING; | |
| return OP_ERROR_SUCCESS; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment